From patchwork Mon Dec 23 14:49:13 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 853075 Delivered-To: patch@linaro.org Received: by 2002:a5d:4888:0:b0:385:e875:8a9e with SMTP id g8csp3433807wrq; Mon, 23 Dec 2024 06:51:04 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCUuKAN1W0jS8eDa+h/zcpO3Nm5EjFUpQedS0lA3NC9VSVOUOKR6VgZfv4j84nYaBAGVgC48Rw==@linaro.org X-Google-Smtp-Source: AGHT+IEsDXrZHbiXll4UU1NTeFQsw4kamFXd2LYI7YR4JY57qxIjElp6Tdsg1NdFaSfIRLvqAGuT X-Received: by 2002:a05:622a:551:b0:463:64b2:2e0d with SMTP id d75a77b69052e-46a4a96b4e0mr197792171cf.40.1734965464687; Mon, 23 Dec 2024 06:51:04 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1734965464; cv=pass; d=google.com; s=arc-20240605; b=Jo8J/jPKe3vwNOuJFabyDtTrp/ofuGUl2A8qXa6aDLgKux/WYCx91d1nq5XfXF5Tbz /OsD8IzLQs16a4SUTTnLE8wxDvKngI4gLnTMBovlkC4lfxYpTooOK4E65ALmHxqf4DqG MCqgXWkc1g+a8QaeuajtMVLcSWsERZqVVDxaoryP/nCFU7XY5XMfWiPuOU6rd99McuHb hfQSyfYOSRGMFRq4PjbYOazvJBTi8FbvbxJOkVQEPwa6psEq9LGnEM3zP1Fd15rwcOsh 4F+ZdKDE7qCp9X27/wSOeV77Js5tB4ltSuP2Ey7k4/wt8Ajxi8ZKYffrZWXsKfXku1yr w+0w== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature:dkim-filter:arc-filter:dmarc-filter :delivered-to:dkim-filter; bh=pWSbi2W4U2S6ZCDZF2NTI3AKbIGISskxUHfoT0xt8b8=; fh=xV8Gp349bHw1ljD2lFQRwhGaJ4bIEzpeFyS/N97S3Sw=; b=bO43ZAAErjuTjn+JGgY/ddLtm7OQF2OOlLcJ7sKJJMawUT+08TJcYdsNCWCeSIzxsI PV3XtG48OFMzt5sTuxRwWP8745AagD0Jwgn0llTOyQTVlkHgealGVu9sfZ05LySpRJi/ cbkJyGekg/3JYC9DjvSj57fDekafl+BrbKRMFzfBSidQ8rya7K/UOZdYkFXrTCmijB54 woWSFaUGAp1T9Ntev1mz3jrGGisbLMXmhEUgdp52oe59u5/sLukV1bOML23ho8IVZy9l Zv8HybMkdzM2q5s6a05v2ZG+zP0Fn+JFnaYQNFVe+qfa7++IskbKerz6bk0U3184rSzp AtvQ==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=aK1rU8LA; arc=pass (i=1); spf=pass (google.com: domain of libc-alpha-bounces~patch=linaro.org@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="libc-alpha-bounces~patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from server2.sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id d75a77b69052e-46a3eb98047si115715061cf.301.2024.12.23.06.51.04 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 23 Dec 2024 06:51:04 -0800 (PST) Received-SPF: pass (google.com: domain of libc-alpha-bounces~patch=linaro.org@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=aK1rU8LA; arc=pass (i=1); spf=pass (google.com: domain of libc-alpha-bounces~patch=linaro.org@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="libc-alpha-bounces~patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 0B9893858D34 for ; Mon, 23 Dec 2024 14:51:04 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0B9893858D34 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=aK1rU8LA X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pf1-x429.google.com (mail-pf1-x429.google.com [IPv6:2607:f8b0:4864:20::429]) by sourceware.org (Postfix) with ESMTPS id E84B2385840E for ; Mon, 23 Dec 2024 14:50:08 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org E84B2385840E Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=linaro.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org E84B2385840E Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::429 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1734965409; cv=none; b=T4GMG1tmXqG8rBbFsi/kr888VYXLqTTg8x6XT3///2vy3WgVAvxp6+wMf53SKKXlKk4e1hZMHldBMbpYG6t3dgI7Ahf7ZH9uKomCV1if2d0wg16b6FnPTzuiFJros1YdDr1Cbu/v0do59bCHhQmooJOwPTM8HdD2yDl7Z+dqSoE= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1734965409; c=relaxed/simple; bh=cVndp3HxdZBqMARaVukBYCfbDjox+fkLdqLM3Zl3VvM=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=p+Upp9cxROkHGZ0BECtRKPtZEIKcC4ZB7nqT5AiGMQzxDYs7Wu8kBPdi3o002aLIfMBwfzoDTu++xNbaWXnTWuJRfWMpIq7uSm5TVlV4dAVy7iNC9VSnPRv1ejH5vMvkN1AGNqAESUm3T/iyARYXqVkfJpR++cIMiXnCD7HwFE4= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E84B2385840E Received: by mail-pf1-x429.google.com with SMTP id d2e1a72fcca58-725dac69699so3783357b3a.0 for ; Mon, 23 Dec 2024 06:50:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1734965408; x=1735570208; darn=sourceware.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=pWSbi2W4U2S6ZCDZF2NTI3AKbIGISskxUHfoT0xt8b8=; b=aK1rU8LApsrCQGalfVyU95Nmrrfy2vO8ADdyQAgwPcDQnV5m13gwqL0dyb8q2gJZJr YLpGmtJcMramzVdErjtpZVE21f6lpD7Dh+FR8L5+rC0nIDEJPpB/cU7DYEOfub3mtDCy SV8qKGyho6SovnVP44vwch1+pcS9tSCg2t6wlK7e2VY3BBC6tLIgsUfZ10/UNfms7rFv jbx8qy6SUy2a5VVhNQBdKelHE7aTdxVqu0ZdWhIswn2eNxNV2YK3hXC+lda/OqgVBWwI voASM5cOhg3r0cG0LPIYrzlQBccC/YIUo+c9lDKoCSk9gkchdLP89mRMd0+pwXJP5B3x /ujQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1734965408; x=1735570208; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=pWSbi2W4U2S6ZCDZF2NTI3AKbIGISskxUHfoT0xt8b8=; b=Ln4uzzk6oCHYzw+/bE6/MRpQkckd0xbRIwFWUdQp9tqWo7A+j+L7BrZb+te/E0PKmb o/xnOJNqa0KpsUs/OBIMK7/lVqVEQZLRzcMy0tWx+1r9Mjy8udITEeQUOUg7mCzzSP7V FBf3BuLW8Xmj0SdqmeJeaNEUHWxYy+dhLcMKImC0dtL+rH/OXFGLo61AruyhrSBXB8bd 7AGxtK6j28mWadtwLzOmD6KNTxidssyeVnvPJaUGtPFHhDql2KHzfSMvFoOeuXV2t7nL 32n/4rR7W/VsTn01161G7CpfmCWyTNB54lxgrk7se0ACiXeAUmxOX7nB1M56vxD76pz2 RqdQ== X-Gm-Message-State: AOJu0YzgQTju1+aZeo186Bqb0Hdluibb/JvPf3c9OmoFPp/q53U9WTu1 ZtGrGRfSEXcx4XeDYjXBLdQI424HldzrcTmxSbahmZBT/HtYXDKvu9S6VWLRXchxWDABO/yn0Nm a X-Gm-Gg: ASbGnct2DELeuG8vBk9SJB0w2T+XdKtL81iHCcc6UYNLGRJF8tO/t4Nt9dLIw81Nm5/ hEV3Bvc8YI0pWVFLGlF58i8qVDBrVijaWI36A8yFmpS/aJtyufbngKea16l30ENzgeJoHT5WkiS hY49w26zIOXrQhdVa77UUcAdgXqOtUMZUMa94B5t5Nxn6y4QQmhqFNE5hA/moWqfYAjHtIiVDPc mbn+hl6CWc4CGLYQxj25d74qn/Ol4zYp7PpfMb0OUl3YGQzPLNJpRtKCZPaPTaWip6FK85OHiaa c4CUM9qBk7bAzW3sRm0uS0kSFw== X-Received: by 2002:a05:6a00:8f07:b0:725:b201:2362 with SMTP id d2e1a72fcca58-72abddb0bd4mr16298137b3a.11.1734965407741; Mon, 23 Dec 2024 06:50:07 -0800 (PST) Received: from ubuntu-vm.. (189-69-57-246.dsl.telesp.net.br. [189.69.57.246]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-72aad816187sm7930372b3a.16.2024.12.23.06.50.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 23 Dec 2024 06:50:07 -0800 (PST) From: Adhemerval Zanella To: libc-alpha@sourceware.org Cc: Florian Weimer , Adhemerval Zanella Subject: [PATCH v6 3/3] elf: Add glibc.rtld.execstack Date: Mon, 23 Dec 2024 11:49:13 -0300 Message-ID: <20241223144954.3823971-4-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241223144954.3823971-1-adhemerval.zanella@linaro.org> References: <20241223144954.3823971-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patch=linaro.org@sourceware.org The new tunable can be used to control whether executable stacks are allowed from either the main program or dependencies. The default is to allow executable stacks. The executable stacks default permission is checked agains the one provided by the PT_GNU_STACK from program headers (if present). The tunable also disables the stack permission change if any dependency requires an executable stack at loading time. Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu. --- NEWS | 5 ++++ elf/Makefile | 44 ++++++++++++++++++++++++++++++++++ elf/dl-load.c | 4 +++- elf/dl-support.c | 5 ++++ elf/dl-tunables.list | 6 +++++ elf/rtld.c | 4 ++++ elf/tst-rtld-list-tunables.exp | 1 + manual/tunables.texi | 19 +++++++++++++++ 8 files changed, 87 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index f91c4c2421..c0a5dd8ad3 100644 --- a/NEWS +++ b/NEWS @@ -46,6 +46,11 @@ Major new features: liable to change. Features from C2Y are also enabled by _GNU_SOURCE, or by compiling with "gcc -std=gnu2y". +* A new tunable, glibc.rtld.execstack, can be used to control whether + executable stacks are allowed from main program, either implicitly due + a mising GNU_STACK ELF header or explicit explicitly because of the + executable bit in GNU_STACK. The default is to allow executable stacks. + Deprecated and removed features, and other changes affecting compatibility: * The big-endian ARC port (arceb-linux-gnu) has been removed. diff --git a/elf/Makefile b/elf/Makefile index cea48e9537..4874d9b59e 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -570,6 +570,13 @@ tests-execstack-yes = \ tests-execstack-static-yes = \ tst-execstack-prog-static # tests-execstack-static-yes +ifeq (yes,$(run-built-tests)) +tests-execstack-special-yes = \ + $(objpfx)tst-execstack-needed-noexecstack.out \ + $(objpfx)tst-execstack-prog-noexecstack.out \ + $(objpfx)tst-execstack-prog-static-noexecstack.out \ + # tests-execstack-special-yes +endif # $(run-built-tests) endif endif ifeq ($(have-depaudit),yes) @@ -666,6 +673,7 @@ $(objpfx)tst-rtld-dash-dash.out: tst-rtld-dash-dash.sh $(objpfx)ld.so tests += $(tests-execstack-$(have-z-execstack)) tests-static+= $(tests-execstack-static-$(have-z-execstack)) +tests-special += $(tests-execstack-special-$(have-z-execstack)) ifeq ($(run-built-tests),yes) tests-special += \ $(objpfx)tst-ldconfig-X.out \ @@ -1989,6 +1997,42 @@ CFLAGS-tst-execstack-mod.c += -Wno-trampolines LDFLAGS-tst-execstack-prog-static = -Wl,-z,execstack CFLAGS-tst-execstack-prog-static.c += -Wno-trampolines + +ifeq (yes,$(build-hardcoded-path-in-tests)) +tst-execstack-prog-noexecstack-msg = "Fatal glibc error: executable stack is not allowed$$" +else +tst-execstack-prog-noexecstack-msg = "error while loading shared libraries:.*cannot enable executable stack as shared object requires:" +endif + +$(objpfx)tst-execstack-prog-noexecstack.out: $(objpfx)tst-execstack-prog + $(test-program-cmd-before-env) \ + $(run-program-env) \ + GLIBC_TUNABLES=glibc.rtld.execstack=0 \ + $(test-program-cmd-after-env) $< \ + > $@ 2>&1; echo "status: $$?" >> $@; \ + grep -q $(tst-execstack-prog-noexecstack-msg) $@ \ + && grep -q '^status: 127$$' $@; \ + $(evaluate-test) + +$(objpfx)tst-execstack-needed-noexecstack.out: $(objpfx)tst-execstack-needed + $(test-program-cmd-before-env) \ + $(run-program-env) \ + GLIBC_TUNABLES=glibc.rtld.execstack=0 \ + $(test-program-cmd-after-env) $< \ + > $@ 2>&1; echo "status: $$?" >> $@; \ + grep -q 'error while loading shared libraries:.*cannot enable executable stack as shared object requires:' $@ \ + && grep -q '^status: 127$$' $@; \ + $(evaluate-test) + +$(objpfx)tst-execstack-prog-static-noexecstack.out: $(objpfx)tst-execstack-prog-static + $(test-program-cmd-before-env) \ + $(run-program-env) \ + GLIBC_TUNABLES=glibc.rtld.execstack=0 \ + $< \ + > $@ 2>&1; echo "status: $$?" >> $@; \ + grep -q 'Fatal glibc error: executable stack is not allowed$$' $@ \ + && grep -q '^status: 127$$' $@; \ + $(evaluate-test) endif LDFLAGS-tst-array2 = -Wl,--no-as-needed diff --git a/elf/dl-load.c b/elf/dl-load.c index a238ff4286..76430e26da 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -32,6 +32,7 @@ #include #include #include +#include /* Type for the buffer we put the ELF header and hopefully the program header. This buffer does not really have to be too large. In most @@ -1317,7 +1318,8 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, /* The stack is presently not executable, but this module requires that it be executable. Only tries to change the stack protection during process startup. */ - if ((mode & __RTLD_DLOPEN) == 0) + if ((mode & __RTLD_DLOPEN) == 0 + && TUNABLE_GET (glibc, rtld, execstack, int32_t, NULL) == 1) errval = _dl_make_stack_executable (stack_endp); else errval = EINVAL; diff --git a/elf/dl-support.c b/elf/dl-support.c index fe1f8c8f6a..73fcd33892 100644 --- a/elf/dl-support.c +++ b/elf/dl-support.c @@ -45,6 +45,7 @@ #include #include #include +#include extern char *__progname; char **_dl_argv = &__progname; /* This is checked for some error messages. */ @@ -331,6 +332,10 @@ _dl_non_dynamic_init (void) break; } + if ((__glibc_unlikely (GL(dl_stack_flags)) & PF_X) + && TUNABLE_GET (glibc, rtld, execstack, int32_t, NULL) == 0) + _dl_fatal_printf ("Fatal glibc error: executable stack is not allowed\n"); + call_function_static_weak (_dl_find_object_init); /* Setup relro on the binary itself. */ diff --git a/elf/dl-tunables.list b/elf/dl-tunables.list index 40ac5b3776..8e656296bb 100644 --- a/elf/dl-tunables.list +++ b/elf/dl-tunables.list @@ -135,6 +135,12 @@ glibc { maxval: 1 default: 0 } + execstack { + type: INT_32 + minval: 0 + maxval: 1 + default: 1 + } } mem { diff --git a/elf/rtld.c b/elf/rtld.c index 5eb130be30..8dd0381985 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -1645,6 +1645,10 @@ dl_main (const ElfW(Phdr) *phdr, bool has_interp = rtld_setup_main_map (main_map); + if ((__glibc_unlikely (GL(dl_stack_flags)) & PF_X) + && TUNABLE_GET (glibc, rtld, execstack, int32_t, NULL) == 0) + _dl_fatal_printf ("Fatal glibc error: executable stack is not allowed\n"); + /* If the current libname is different from the SONAME, add the latter as well. */ if (_dl_rtld_map.l_info[DT_SONAME] != NULL diff --git a/elf/tst-rtld-list-tunables.exp b/elf/tst-rtld-list-tunables.exp index db0e1c86e9..9f5990f340 100644 --- a/elf/tst-rtld-list-tunables.exp +++ b/elf/tst-rtld-list-tunables.exp @@ -13,5 +13,6 @@ glibc.malloc.top_pad: 0x20000 (min: 0x0, max: 0x[f]+) glibc.malloc.trim_threshold: 0x0 (min: 0x0, max: 0x[f]+) glibc.rtld.dynamic_sort: 2 (min: 1, max: 2) glibc.rtld.enable_secure: 0 (min: 0, max: 1) +glibc.rtld.execstack: 1 (min: 0, max: 1) glibc.rtld.nns: 0x4 (min: 0x1, max: 0x10) glibc.rtld.optional_static_tls: 0x200 (min: 0x0, max: 0x[f]+) diff --git a/manual/tunables.texi b/manual/tunables.texi index 0b1b2898c0..c3e894f4fe 100644 --- a/manual/tunables.texi +++ b/manual/tunables.texi @@ -355,6 +355,25 @@ tests for @code{AT_SECURE} programs and not meant to be a security feature. The default value of this tunable is @samp{0}. @end deftp +@deftp Tunable glibc.rtld.execstack +@theglibc{} will use either the default architecture ABI flags (that might +contain the executable bit) or the value of @code{PT_GNU_STACK} (if present) +to define whether to mark the stack non-executable, and if the program or +any shared library dependency require an executable stack the loader will +change the main stack permission if kernel starts with a non executable stack. + +The @code{glibc.rtld.execstack} tunable allows the user to control how +to proceed regarding the stack execution bit. Setting its value to @code{0} +disables executable stacks, where @code{1} enables it. The default value +is @code{1}. + +When executable stacks are not allowed, and if the main program requires an +executable stack, the loader will fail with an error message. +@strong{NB:} Trying to load a dynamic shared library with @code{dlopen} or +@code{dlmopen} that requires an executable stack will always fail if the +default flags does not contain the executable bit. +@end deftp + @node Elision Tunables @section Elision Tunables @cindex elision tunables