From owner-svn-src-head@FreeBSD.ORG Thu Mar 26 21:58:07 2015 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 2F946713; Thu, 26 Mar 2015 21:58:07 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 00B4BF62; Thu, 26 Mar 2015 21:58:07 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t2QLw6Yw014615; Thu, 26 Mar 2015 21:58:06 GMT (envelope-from jilles@FreeBSD.org) Received: (from jilles@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t2QLw6v2014614; Thu, 26 Mar 2015 21:58:06 GMT (envelope-from jilles@FreeBSD.org) Message-Id: <201503262158.t2QLw6v2014614@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: jilles set sender to jilles@FreeBSD.org using -f From: Jilles Tjoelker Date: Thu, 26 Mar 2015 21:58:06 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r280713 - head/lib/libc/gen X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 26 Mar 2015 21:58:07 -0000 Author: jilles Date: Thu Mar 26 21:58:06 2015 New Revision: 280713 URL: https://svnweb.freebsd.org/changeset/base/280713 Log: setmode(): Use sysctl kern.proc.umask instead of umask() if possible. The kern.proc.umask. sysctl allows querying the umask without temporarily modifying it. Modified: head/lib/libc/gen/setmode.c Modified: head/lib/libc/gen/setmode.c ============================================================================== --- head/lib/libc/gen/setmode.c Thu Mar 26 21:13:53 2015 (r280712) +++ head/lib/libc/gen/setmode.c Thu Mar 26 21:58:06 2015 (r280713) @@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include +#include #include #include @@ -68,6 +69,7 @@ typedef struct bitcmd { #define CMD2_OBITS 0x08 #define CMD2_UBITS 0x10 +static mode_t getumask(void); static BITCMD *addcmd(BITCMD *, mode_t, mode_t, mode_t, mode_t); static void compress_mode(BITCMD *); #ifdef SETMODE_DEBUG @@ -169,7 +171,6 @@ setmode(const char *p) int serrno; char op, *ep; BITCMD *set, *saveset, *endset; - sigset_t sigset, sigoset; mode_t mask, perm, permXbits, who; long perml; int equalopdone; @@ -182,15 +183,9 @@ setmode(const char *p) /* * Get a copy of the mask for the permissions that are mask relative. - * Flip the bits, we want what's not set. Since it's possible that - * the caller is opening files inside a signal handler, protect them - * as best we can. + * Flip the bits, we want what's not set. */ - sigfillset(&sigset); - (void)_sigprocmask(SIG_BLOCK, &sigset, &sigoset); - (void)umask(mask = umask(0)); - mask = ~mask; - (void)_sigprocmask(SIG_SETMASK, &sigoset, NULL); + mask = ~getumask(); setlen = SET_LEN + 2; @@ -346,6 +341,35 @@ out: return NULL; } +static mode_t +getumask(void) +{ + sigset_t sigset, sigoset; + size_t len; + mode_t mask; + u_short smask; + + /* + * First try requesting the umask without temporarily modifying it. + * Note that this does not work if the sysctl + * security.bsd.unprivileged_proc_debug is set to 0. + */ + len = sizeof(smask); + if (sysctl((int[4]){ CTL_KERN, KERN_PROC, KERN_PROC_UMASK, getpid() }, + 4, &smask, &len, NULL, 0) == 0) + return (smask); + + /* + * Since it's possible that the caller is opening files inside a signal + * handler, protect them as best we can. + */ + sigfillset(&sigset); + (void)_sigprocmask(SIG_BLOCK, &sigset, &sigoset); + (void)umask(mask = umask(0)); + (void)_sigprocmask(SIG_SETMASK, &sigoset, NULL); + return (mask); +} + static BITCMD * addcmd(BITCMD *set, mode_t op, mode_t who, mode_t oparg, mode_t mask) {