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.
This commit is contained in:
parent
84233ddb80
commit
73cc817ec8
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=280713
@ -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 @@ apply: if (!*p)
|
||||
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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user