Skip to content
/ linux Public
forked from torvalds/linux

Commit

Permalink
parisc: Add wrapper syscalls to fix O_NONBLOCK flag usage
Browse files Browse the repository at this point in the history
The commit 75ae042 ("parisc: Define O_NONBLOCK to become
000200000") changed the O_NONBLOCK constant to have only one bit set
(like all other architectures). This change broke some existing
userspace code (e.g.  udevadm, systemd-udevd, elogind) which called
specific syscalls which do strict value checking on their flag
parameter.

This patch adds wrapper functions for the relevant syscalls. The
wrappers masks out any old invalid O_NONBLOCK flags, reports in the
syslog if the old O_NONBLOCK value was used and then calls the target
syscall with the new O_NONBLOCK value.

Fixes: 75ae042 ("parisc: Define O_NONBLOCK to become 000200000")
Signed-off-by: Helge Deller <[email protected]>
Tested-by: Meelis Roos <[email protected]>
Tested-by: Jeroen Roovers <[email protected]>
  • Loading branch information
hdeller committed Oct 23, 2020
1 parent 879bc2d commit 44a4c9e
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 7 deletions.
73 changes: 72 additions & 1 deletion arch/parisc/kernel/sys_parisc.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* Copyright (C) 1999-2003 Matthew Wilcox <willy at parisc-linux.org>
* Copyright (C) 2000-2003 Paul Bame <bame at parisc-linux.org>
* Copyright (C) 2001 Thomas Bogendoerfer <tsbogend at parisc-linux.org>
* Copyright (C) 1999-2014 Helge Deller <[email protected]>
* Copyright (C) 1999-2020 Helge Deller <[email protected]>
*/

#include <linux/uaccess.h>
Expand All @@ -23,6 +23,7 @@
#include <linux/utsname.h>
#include <linux/personality.h>
#include <linux/random.h>
#include <linux/compat.h>

/* we construct an artificial offset for the mapping based on the physical
* address of the kernel mapping variable */
Expand Down Expand Up @@ -373,3 +374,73 @@ long parisc_personality(unsigned long personality)

return err;
}

/*
* Up to kernel v5.9 we defined O_NONBLOCK as 000200004,
* since then O_NONBLOCK is defined as 000200000.
*
* The following wrapper functions mask out the old
* O_NDELAY bit from calls which use O_NONBLOCK.
*
* XXX: Remove those in year 2022 (or later)?
*/

#define O_NONBLOCK_OLD 000200004
#define O_NONBLOCK_MASK_OUT (O_NONBLOCK_OLD & ~O_NONBLOCK)

static int FIX_O_NONBLOCK(int flags)
{
if (flags & O_NONBLOCK_MASK_OUT) {
struct task_struct *tsk = current;
pr_warn_once("%s(%d) uses a deprecated O_NONBLOCK value.\n",
tsk->comm, tsk->pid);
}
return flags & ~O_NONBLOCK_MASK_OUT;
}

asmlinkage long parisc_timerfd_create(int clockid, int flags)
{
flags = FIX_O_NONBLOCK(flags);
return sys_timerfd_create(clockid, flags);
}

asmlinkage long parisc_signalfd4(int ufd, sigset_t __user *user_mask,
size_t sizemask, int flags)
{
flags = FIX_O_NONBLOCK(flags);
return sys_signalfd4(ufd, user_mask, sizemask, flags);
}

#ifdef CONFIG_COMPAT
asmlinkage long parisc_compat_signalfd4(int ufd,
compat_sigset_t __user *user_mask,
compat_size_t sizemask, int flags)
{
flags = FIX_O_NONBLOCK(flags);
return compat_sys_signalfd4(ufd, user_mask, sizemask, flags);
}
#endif

asmlinkage long parisc_eventfd2(unsigned int count, int flags)
{
flags = FIX_O_NONBLOCK(flags);
return sys_eventfd2(count, flags);
}

asmlinkage long parisc_userfaultfd(int flags)
{
flags = FIX_O_NONBLOCK(flags);
return sys_userfaultfd(flags);
}

asmlinkage long parisc_pipe2(int __user *fildes, int flags)
{
flags = FIX_O_NONBLOCK(flags);
return sys_pipe2(fildes, flags);
}

asmlinkage long parisc_inotify_init1(int flags)
{
flags = FIX_O_NONBLOCK(flags);
return sys_inotify_init1(flags);
}
12 changes: 6 additions & 6 deletions arch/parisc/kernel/syscalls/syscall.tbl
Original file line number Diff line number Diff line change
Expand Up @@ -344,17 +344,17 @@
304 common eventfd sys_eventfd
305 32 fallocate parisc_fallocate
305 64 fallocate sys_fallocate
306 common timerfd_create sys_timerfd_create
306 common timerfd_create parisc_timerfd_create
307 32 timerfd_settime sys_timerfd_settime32
307 64 timerfd_settime sys_timerfd_settime
308 32 timerfd_gettime sys_timerfd_gettime32
308 64 timerfd_gettime sys_timerfd_gettime
309 common signalfd4 sys_signalfd4 compat_sys_signalfd4
310 common eventfd2 sys_eventfd2
309 common signalfd4 parisc_signalfd4 parisc_compat_signalfd4
310 common eventfd2 parisc_eventfd2
311 common epoll_create1 sys_epoll_create1
312 common dup3 sys_dup3
313 common pipe2 sys_pipe2
314 common inotify_init1 sys_inotify_init1
313 common pipe2 parisc_pipe2
314 common inotify_init1 parisc_inotify_init1
315 common preadv sys_preadv compat_sys_preadv
316 common pwritev sys_pwritev compat_sys_pwritev
317 common rt_tgsigqueueinfo sys_rt_tgsigqueueinfo compat_sys_rt_tgsigqueueinfo
Expand Down Expand Up @@ -387,7 +387,7 @@
341 common bpf sys_bpf
342 common execveat sys_execveat compat_sys_execveat
343 common membarrier sys_membarrier
344 common userfaultfd sys_userfaultfd
344 common userfaultfd parisc_userfaultfd
345 common mlock2 sys_mlock2
346 common copy_file_range sys_copy_file_range
347 common preadv2 sys_preadv2 compat_sys_preadv2
Expand Down

0 comments on commit 44a4c9e

Please sign in to comment.