Author: jilles
Date: Sat Aug 29 20:41:09 2015
New Revision: 287298
URL: https://svnweb.freebsd.org/changeset/base/287298

Log:
  MFC r279084,280713: setmode(): Use sysctl kern.proc.umask instead of umask()
  if possible.
  
  The kern.proc.umask.<pid> sysctl allows querying the umask without
  temporarily modifying it.
  
  r280713 is the actual change, while r279084 is a whitespace change.

Modified:
  stable/10/lib/libc/gen/setmode.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/lib/libc/gen/setmode.c
==============================================================================
--- stable/10/lib/libc/gen/setmode.c    Sat Aug 29 19:47:20 2015        
(r287297)
+++ stable/10/lib/libc/gen/setmode.c    Sat Aug 29 20:41:09 2015        
(r287298)
@@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
 #include "namespace.h"
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <sys/sysctl.h>
 
 #include <ctype.h>
 #include <errno.h>
@@ -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)
 {
_______________________________________________
svn-src-stable-10@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-stable-10
To unsubscribe, send any mail to "svn-src-stable-10-unsubscr...@freebsd.org"

Reply via email to