From patchwork Mon Jan 2 19:37:38 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Siddhesh Poyarekar X-Patchwork-Id: 89574 Delivered-To: patch@linaro.org Received: by 10.140.20.101 with SMTP id 92csp7719031qgi; Mon, 2 Jan 2017 11:37:58 -0800 (PST) X-Received: by 10.84.217.202 with SMTP id d10mr100083961plj.132.1483385878114; Mon, 02 Jan 2017 11:37:58 -0800 (PST) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id h11si5540308pln.240.2017.01.02.11.37.57 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 02 Jan 2017 11:37:58 -0800 (PST) Received-SPF: pass (google.com: domain of libc-alpha-return-76554-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org; spf=pass (google.com: domain of libc-alpha-return-76554-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-76554-patch=linaro.org@sourceware.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:reply-to:to:cc:from:subject:message-id:date :mime-version:content-type; q=dns; s=default; b=S0wNMdgNqdp1r8J3 Y7bCE8yp32QD/IGq/lrGS5JtkRg7kMCt99iQS42c1l25obyMCn7b+kz7wqwZ1uH8 W0FBXGoQk7Jkbzfri6tnlMxppxpPGTii6WAKTuU4JzrGiJEGvbkOzKEk4RP11481 rh7WSHBRMaNhZKKyePZvekgbzUo= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:reply-to:to:cc:from:subject:message-id:date :mime-version:content-type; s=default; bh=bJPr54YQBNu1J/KjZEoioX /lvs8=; b=Rg1cgCgwkAdXUZQ2HvAuIcnMcr3PKN0c009LkNRXyzq8TWsS8gvThn 9f2n7xYRml1Eu6DW/i2rj536HSsrFcFEV5m6dVifjD9CVx8ZSPV1Dgl8K5t2CnJS mA0EjJdhtIbRIxVSEOo7DC643ZZy4WNnRw/qlDXWYn0/I1yAT+qb0= Received: (qmail 30312 invoked by alias); 2 Jan 2017 19:37:48 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 30298 invoked by uid 89); 2 Jan 2017 19:37:47 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=1.6 required=5.0 tests=BAYES_50, RCVD_IN_DNSWL_NONE, SPF_NEUTRAL autolearn=no version=3.3.2 spammy=2.7.4, *namelen, envname, setgid X-HELO: homiemail-a47.g.dreamhost.com Reply-To: siddhesh@sourceware.org To: "libc-alpha@sourceware.org" Cc: Carlos O'Donell , Florian Weimer From: Siddhesh Poyarekar Subject: [PATCH] tunables: Avoid getenv calls and disable glibc.malloc.check by default Message-ID: <9a4f7ecd-e929-496f-8242-0793a74bc15a@sourceware.org> Date: Tue, 3 Jan 2017 01:07:38 +0530 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.5.1 MIME-Version: 1.0 Builds with --enable-tunables failed on i686 because a call to getenv got snuck into tunables, which pulled in strncmp. This patch fixes this build failure by making the glibc.malloc.check check even simpler. The previous approach was convoluted where the tunable was disabled using an unsetenv and overwriting the tunable value with colons. The easier way is to simply mark the tunable as insecure by default (i.e. won't be read for AT_SECURE programs) and then enabled only when the /etc/suid-debug file is found. This also ends up removing a bunch of functions that were specially reimplemented (strlen, unsetenv) to avoid calling into string routines. Tested on x86_64 and i686. * elf/dl-tunables.c (tunables_unsetenv): Remove function. (min_strlen): Likewise. (disable_tunable): Likewise. (maybe_disable_malloc_check): Rename to maybe_enable_malloc_check. (maybe_enable_malloc_check): Enable glibc.malloc.check tunable if /etc/suid-debug file exists. (__tunables_init): Update caller. * elf/dl-tunables.list (glibc.malloc.check): Don't mark as secure. --- elf/dl-tunables.c | 87 ++++++---------------------------------------------- elf/dl-tunables.list | 1 - 2 files changed, 10 insertions(+), 78 deletions(-) diff --git a/elf/dl-tunables.c b/elf/dl-tunables.c index c20a477..e0119d1 100644 --- a/elf/dl-tunables.c +++ b/elf/dl-tunables.c @@ -100,34 +100,6 @@ get_next_env (char **envp, char **name, size_t *namelen, char **val) return NULL; } -static int -tunables_unsetenv (char **ep, const char *name) -{ - while (*ep != NULL) - { - size_t cnt = 0; - - while ((*ep)[cnt] == name[cnt] && name[cnt] != '\0') - ++cnt; - - if (name[cnt] == '\0' && (*ep)[cnt] == '=') - { - /* Found it. Remove this pointer by moving later ones to - the front. */ - char **dp = ep; - - do - dp[0] = dp[1]; - while (*dp++); - /* Continue the loop in case NAME appears again. */ - } - else - ++ep; - } - - return 0; -} - /* A stripped down strtoul-like implementation for very early use. It does not set errno if the result is outside bounds because it gets called before errno may have been set up. */ @@ -316,57 +288,18 @@ parse_tunables (char *tunestr) } #endif -static size_t -min_strlen (const char *s) -{ - size_t i = 0; - while (*s++ != '\0') - i++; - - return i; -} - -/* Disable a tunable if it is set. */ -static void -disable_tunable (tunable_id_t id, char **envp) -{ - const char *env_alias = tunable_list[id].env_alias; - - if (env_alias != NULL) - tunables_unsetenv (envp, tunable_list[id].env_alias); - -#if TUNABLES_FRONTEND == TUNABLES_FRONTEND_valstring - char *tunable = getenv (GLIBC_TUNABLES); - const char *cmp = tunable_list[id].name; - const size_t len = min_strlen (cmp); - - while (tunable && *tunable != '\0' && *tunable != ':') - { - if (is_name (tunable, cmp)) - { - tunable += len; - /* Overwrite the = and the value with colons. */ - while (*tunable != '\0' && *tunable != ':') - *tunable++ = ':'; - break; - } - tunable++; - } -#endif -} - -/* Disable the glibc.malloc.check tunable in SETUID/SETGID programs unless - the system administrator overrides it by creating the /etc/suid-debug - file. This is a special case where we want to conditionally enable/disable - a tunable even for setuid binaries. We use the special version of access() - to avoid setting ERRNO, which is a TLS variable since TLS has not yet been - set up. */ +/* Enable the glibc.malloc.check tunable in SETUID/SETGID programs only when + the system administrator has created the /etc/suid-debug file. This is a + special case where we want to conditionally enable/disable a tunable even + for setuid binaries. We use the special version of access() to avoid + setting ERRNO, which is a TLS variable since TLS has not yet been set + up. */ static inline void __always_inline -maybe_disable_malloc_check (void) +maybe_enable_malloc_check (void) { - if (__libc_enable_secure && __access_noerrno ("/etc/suid-debug", F_OK) != 0) - disable_tunable (TUNABLE_ENUM_NAME(glibc, malloc, check), __environ); + if (__access_noerrno ("/etc/suid-debug", F_OK) == 0) + tunable_list[TUNABLE_ENUM_NAME(glibc, malloc, check)].is_secure = true; } /* Initialize the tunables list from the environment. For now we only use the @@ -379,7 +312,7 @@ __tunables_init (char **envp) char *envval = NULL; size_t len = 0; - maybe_disable_malloc_check (); + maybe_enable_malloc_check (); while ((envp = get_next_env (envp, &envname, &len, &envval)) != NULL) { diff --git a/elf/dl-tunables.list b/elf/dl-tunables.list index cbd1f4f..d8cd912 100644 --- a/elf/dl-tunables.list +++ b/elf/dl-tunables.list @@ -31,7 +31,6 @@ glibc { minval: 0 maxval: 3 env_alias: MALLOC_CHECK_ - is_secure: true } top_pad { type: SIZE_T -- 2.7.4