It's not possible to read the process umask without also modifying it,
which is what umask(2) does. A library cannot read umask safely,
especially if the main program might be multithreaded.
This patch series adds a trivial system call "getumask" which returns
the umask of the current process.
Another approach to this has been attempted before, adding something
to /proc, although it didn't go anywhere. See:
http://comments.gmane.org/gmane.linux.kernel/1292109
Another way to solve this would be to add a thread-safe getumask to
glibc. Since glibc could own the mutex, this would permit libraries
linked to this glibc to read umask safely.
I should also note that man-pages documents getumask(3), but no
version of glibc has ever implemented it.
Typical test script:
#include <stdio.h>
#include <stdlib.h>
#include <linux/unistd.h>
#include <sys/syscall.h>
int main(int argc, char *argv[])
{
int r = syscall(329);
if (r == -1) {
perror("getumask");
exit(1);
}
printf("umask = %o\n", r);
exit(0);
}
$ ./getumask
umask = 22
Rich.
Signed-off-by: Richard W.M. Jones <[email protected]>
---
arch/x86/entry/syscalls/syscall_32.tbl | 1 +
arch/x86/entry/syscalls/syscall_64.tbl | 1 +
2 files changed, 2 insertions(+)
diff --git a/arch/x86/entry/syscalls/syscall_32.tbl b/arch/x86/entry/syscalls/syscall_32.tbl
index b30dd81..af0a032 100644
--- a/arch/x86/entry/syscalls/syscall_32.tbl
+++ b/arch/x86/entry/syscalls/syscall_32.tbl
@@ -386,3 +386,4 @@
377 i386 copy_file_range sys_copy_file_range
378 i386 preadv2 sys_preadv2
379 i386 pwritev2 sys_pwritev2
+380 i386 getumask sys_getumask
diff --git a/arch/x86/entry/syscalls/syscall_64.tbl b/arch/x86/entry/syscalls/syscall_64.tbl
index cac6d17..47c1579 100644
--- a/arch/x86/entry/syscalls/syscall_64.tbl
+++ b/arch/x86/entry/syscalls/syscall_64.tbl
@@ -335,6 +335,7 @@
326 common copy_file_range sys_copy_file_range
327 64 preadv2 sys_preadv2
328 64 pwritev2 sys_pwritev2
+329 common getumask sys_getumask
#
# x32-specific system call numbers start at 512 to avoid cache impact
--
2.7.4
Define a system call for reading the current umask value.
Signed-off-by: Richard W.M. Jones <[email protected]>
---
include/linux/syscalls.h | 1 +
kernel/sys.c | 5 +++++
2 files changed, 6 insertions(+)
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index d795472..e96e88f 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -659,6 +659,7 @@ asmlinkage long sys_prlimit64(pid_t pid, unsigned int resource,
struct rlimit64 __user *old_rlim);
asmlinkage long sys_getrusage(int who, struct rusage __user *ru);
asmlinkage long sys_umask(int mask);
+asmlinkage long sys_getumask(void);
asmlinkage long sys_msgget(key_t key, int msgflg);
asmlinkage long sys_msgsnd(int msqid, struct msgbuf __user *msgp,
diff --git a/kernel/sys.c b/kernel/sys.c
index cf8ba54..026c146 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1649,6 +1649,11 @@ SYSCALL_DEFINE1(umask, int, mask)
return mask;
}
+SYSCALL_DEFINE0(getumask)
+{
+ return current->fs->umask;
+}
+
static int prctl_set_mm_exe_file(struct mm_struct *mm, unsigned int fd)
{
struct fd exe;
--
2.7.4
On 04/13/2016 02:43 PM, Richard W.M. Jones wrote:
> It's not possible to read the process umask without also modifying it,
> which is what umask(2) does. A library cannot read umask safely,
> especially if the main program might be multithreaded.
>
> This patch series adds a trivial system call "getumask" which returns
> the umask of the current process.
Ah! Thanks for this :)
Acked-by: Pavel Emelyanov <[email protected]>
Hi Richard,
[auto build test WARNING on v4.6-rc3]
[also build test WARNING on next-20160413]
[cannot apply to tip/x86/core tip/auto-latest]
[if your patch is applied to the wrong git tree, please drop us a note to help improving the system]
url: https://github.com/0day-ci/linux/commits/Richard-W-M-Jones/vfs-Define-new-syscall-getumask/20160413-194722
config: xtensa-allmodconfig (attached as .config)
reproduce:
wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=xtensa
All warnings (new ones prefixed by >>):
<stdin>:1298:2: warning: #warning syscall userfaultfd not implemented [-Wcpp]
<stdin>:1301:2: warning: #warning syscall membarrier not implemented [-Wcpp]
<stdin>:1304:2: warning: #warning syscall mlock2 not implemented [-Wcpp]
<stdin>:1307:2: warning: #warning syscall copy_file_range not implemented [-Wcpp]
<stdin>:1310:2: warning: #warning syscall preadv2 not implemented [-Wcpp]
<stdin>:1313:2: warning: #warning syscall pwritev2 not implemented [-Wcpp]
>> <stdin>:1316:2: warning: #warning syscall getumask not implemented [-Wcpp]
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
On Wed, Apr 13, 2016 at 02:21:35PM +0200, Florian Weimer wrote:
> * Richard W. M. Jones:
>
> > +SYSCALL_DEFINE0(getumask)
> > +{
> > + return current->fs->umask;
> > +}
>
> The convention seems to be to call current_umask(), instead of
> inlining its contents.
Yes, please use existing.
* Richard W. M. Jones:
> +SYSCALL_DEFINE0(getumask)
> +{
> + return current->fs->umask;
> +}
The convention seems to be to call current_umask(), instead of
inlining its contents.