Skip to content

Commit 44a4c9e

Browse files
committed
parisc: Add wrapper syscalls to fix O_NONBLOCK flag usage
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 <deller@gmx.de> Tested-by: Meelis Roos <mroos@linux.ee> Tested-by: Jeroen Roovers <jer@xs4all.nl>
1 parent 879bc2d commit 44a4c9e

2 files changed

Lines changed: 78 additions & 7 deletions

File tree

arch/parisc/kernel/sys_parisc.c

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Copyright (C) 1999-2003 Matthew Wilcox <willy at parisc-linux.org>
77
* Copyright (C) 2000-2003 Paul Bame <bame at parisc-linux.org>
88
* Copyright (C) 2001 Thomas Bogendoerfer <tsbogend at parisc-linux.org>
9-
* Copyright (C) 1999-2014 Helge Deller <deller@gmx.de>
9+
* Copyright (C) 1999-2020 Helge Deller <deller@gmx.de>
1010
*/
1111

1212
#include <linux/uaccess.h>
@@ -23,6 +23,7 @@
2323
#include <linux/utsname.h>
2424
#include <linux/personality.h>
2525
#include <linux/random.h>
26+
#include <linux/compat.h>
2627

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

374375
return err;
375376
}
377+
378+
/*
379+
* Up to kernel v5.9 we defined O_NONBLOCK as 000200004,
380+
* since then O_NONBLOCK is defined as 000200000.
381+
*
382+
* The following wrapper functions mask out the old
383+
* O_NDELAY bit from calls which use O_NONBLOCK.
384+
*
385+
* XXX: Remove those in year 2022 (or later)?
386+
*/
387+
388+
#define O_NONBLOCK_OLD 000200004
389+
#define O_NONBLOCK_MASK_OUT (O_NONBLOCK_OLD & ~O_NONBLOCK)
390+
391+
static int FIX_O_NONBLOCK(int flags)
392+
{
393+
if (flags & O_NONBLOCK_MASK_OUT) {
394+
struct task_struct *tsk = current;
395+
pr_warn_once("%s(%d) uses a deprecated O_NONBLOCK value.\n",
396+
tsk->comm, tsk->pid);
397+
}
398+
return flags & ~O_NONBLOCK_MASK_OUT;
399+
}
400+
401+
asmlinkage long parisc_timerfd_create(int clockid, int flags)
402+
{
403+
flags = FIX_O_NONBLOCK(flags);
404+
return sys_timerfd_create(clockid, flags);
405+
}
406+
407+
asmlinkage long parisc_signalfd4(int ufd, sigset_t __user *user_mask,
408+
size_t sizemask, int flags)
409+
{
410+
flags = FIX_O_NONBLOCK(flags);
411+
return sys_signalfd4(ufd, user_mask, sizemask, flags);
412+
}
413+
414+
#ifdef CONFIG_COMPAT
415+
asmlinkage long parisc_compat_signalfd4(int ufd,
416+
compat_sigset_t __user *user_mask,
417+
compat_size_t sizemask, int flags)
418+
{
419+
flags = FIX_O_NONBLOCK(flags);
420+
return compat_sys_signalfd4(ufd, user_mask, sizemask, flags);
421+
}
422+
#endif
423+
424+
asmlinkage long parisc_eventfd2(unsigned int count, int flags)
425+
{
426+
flags = FIX_O_NONBLOCK(flags);
427+
return sys_eventfd2(count, flags);
428+
}
429+
430+
asmlinkage long parisc_userfaultfd(int flags)
431+
{
432+
flags = FIX_O_NONBLOCK(flags);
433+
return sys_userfaultfd(flags);
434+
}
435+
436+
asmlinkage long parisc_pipe2(int __user *fildes, int flags)
437+
{
438+
flags = FIX_O_NONBLOCK(flags);
439+
return sys_pipe2(fildes, flags);
440+
}
441+
442+
asmlinkage long parisc_inotify_init1(int flags)
443+
{
444+
flags = FIX_O_NONBLOCK(flags);
445+
return sys_inotify_init1(flags);
446+
}

arch/parisc/kernel/syscalls/syscall.tbl

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -344,17 +344,17 @@
344344
304 common eventfd sys_eventfd
345345
305 32 fallocate parisc_fallocate
346346
305 64 fallocate sys_fallocate
347-
306 common timerfd_create sys_timerfd_create
347+
306 common timerfd_create parisc_timerfd_create
348348
307 32 timerfd_settime sys_timerfd_settime32
349349
307 64 timerfd_settime sys_timerfd_settime
350350
308 32 timerfd_gettime sys_timerfd_gettime32
351351
308 64 timerfd_gettime sys_timerfd_gettime
352-
309 common signalfd4 sys_signalfd4 compat_sys_signalfd4
353-
310 common eventfd2 sys_eventfd2
352+
309 common signalfd4 parisc_signalfd4 parisc_compat_signalfd4
353+
310 common eventfd2 parisc_eventfd2
354354
311 common epoll_create1 sys_epoll_create1
355355
312 common dup3 sys_dup3
356-
313 common pipe2 sys_pipe2
357-
314 common inotify_init1 sys_inotify_init1
356+
313 common pipe2 parisc_pipe2
357+
314 common inotify_init1 parisc_inotify_init1
358358
315 common preadv sys_preadv compat_sys_preadv
359359
316 common pwritev sys_pwritev compat_sys_pwritev
360360
317 common rt_tgsigqueueinfo sys_rt_tgsigqueueinfo compat_sys_rt_tgsigqueueinfo
@@ -387,7 +387,7 @@
387387
341 common bpf sys_bpf
388388
342 common execveat sys_execveat compat_sys_execveat
389389
343 common membarrier sys_membarrier
390-
344 common userfaultfd sys_userfaultfd
390+
344 common userfaultfd parisc_userfaultfd
391391
345 common mlock2 sys_mlock2
392392
346 common copy_file_range sys_copy_file_range
393393
347 common preadv2 sys_preadv2 compat_sys_preadv2

0 commit comments

Comments
 (0)