* Re: [PATCH v2 4/5] pselect6: use __kernel_timespec
From: Deepa Dinamani @ 2018-09-15 18:37 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Alexander Viro, Thomas Gleixner, Linux Kernel Mailing List,
y2038 Mailman List, Linux FS-devel Mailing List, Linux API,
linux-aio
In-Reply-To: <CAK8P3a2Kkm2ubg_MVN_BJL=s7qpUB1-np=9zVpcJ2U-aPAJswg@mail.gmail.com>
On Sat, Sep 15, 2018 at 8:28 AM Arnd Bergmann <arnd@arndb.de> wrote:
>
> On Sat, Sep 15, 2018 at 7:09 AM Deepa Dinamani <deepa.kernel@gmail.com> wrote:
>
> > +#if defined(CONFIG_64BIT_TIME)
> > +
> > +COMPAT_SYSCALL_DEFINE6(pselect6_time64, int, n, compat_ulong_t __user *, inp,
> > + compat_ulong_t __user *, outp, compat_ulong_t __user *, exp,
> > + struct __kernel_timespec __user *, tsp, void __user *, sig)
>
> I got a link error here since compat_sys_pselect6_time64 and
> compat_sys_ppoll_time64 are only defined when CONFIG_64BIT_TIME
> is set.
>
> I did not think we would select this symbol on arm64, is that a mistake
> on my side, or should the #ifdef check be removed?
But, this is a compat syscall.
When we introduced this CONFIG_64BIT_TIME we planned to use it for
compat syscalls also is my understanding.
config 64BIT_TIME
def_bool ARCH_HAS_64BIT_TIME
help
This should be selected by all architectures that need to support
new system calls with a 64-bit time_t. This is relevant on all 32-bit
architectures, and 64-bit architectures as part of compat syscall
handling.
This means it should be set on 64 bit architechtures also right?
If we don't have the #ifdef here then we have an entry point from
userspace defined and Thomas had pointed out that it was a security
hole.
-Deepa
--
To unsubscribe, send a message with 'unsubscribe linux-aio' in
the body to majordomo@kvack.org. For more info on Linux AIO,
see: http://www.kvack.org/aio/
Don't email: <a href=mailto:"aart@kvack.org">aart@kvack.org</a>
^ permalink raw reply
* (no subject)
From: Arnd Bergmann @ 2018-09-15 15:47 UTC (permalink / raw)
To: Thomas Gleixner
Cc: y2038 Mailman List, Christoph Hellwig, Linux API, Deepa Dinamani,
Linux Kernel Mailing List
Hi Thomas,
Please pull the system call changes into a branch of the tip tree.
These are the ones I posted right after rc1, with the addition of
two bug fixes that were contributed by Guenther and the kbuild test
robot.
I've had the changes in linux-next since then and not received
any other bug reports or feedback.
I panicked a little at one point when I realized that there is
a sparc64 specific bug in some of my patches, but I then
found that at least this series is not affected at all.
Arnd
The following changes since commit 5b394b2ddf0347bef56e50c69a58773c94343ff3:
Linux 4.19-rc1 (2018-08-26 14:11:59 -0700)
are available in the Git repository at:
git+ssh://git@ra.kernel.org:/pub/scm/linux/kernel/git/arnd/playground.git
tags/y2038
for you to fetch changes up to 67314ec7b0250290cc85eaa7a2f88a8ddb9e8547:
RISC-V: Request newstat syscalls (2018-09-05 22:44:21 +0200)
----------------------------------------------------------------
y2038: convert more syscalls
Here is another set of system call changes to prepare the change over to
64-bit time_t. As before, the strategy is to change system calls that
take a 'struct timespec' argument over to 'struct __kernel_timespec',
which for now is defined to be the same but will get redefined to use a
64-bit time_t argument once we are ready to modify the system call tables.
The major change from previous patches is that the plan is no longer
to directly use the 'compat' system calls for providing compatibility
with the existing 32-bit time_t based entry points. Instead, we rename
the compat code to something that makes more sense on 32-bit architectures,
e.g. compat_timespec becomes old_timespec32.
With the renamed types in place, we change over the 'stat' and 'utimes'
families of system calls, sched_rr_get_interval, recvmmsg and
rt_sigtimedwait. Another series for poll, select and io_pgetevents is
currently being tested.
----------------------------------------------------------------
Arnd Bergmann (14):
y2038: remove unused time interfaces
y2038: make do_gettimeofday() and get_seconds() inline
y2038: globally rename compat_time to old_time32
y2038: Remove newstat family from default syscall set
y2038: Remove stat64 family from default syscall set
asm-generic: Move common compat types to asm-generic/compat.h
asm-generic: Remove unneeded __ARCH_WANT_SYS_LLSEEK macro
asm-generic: Remove empty asm/unistd.h
y2038: Change sys_utimensat() to use __kernel_timespec
y2038: Compile utimes()/futimesat() conditionally
y2038: utimes: Rework #ifdef guards for compat syscalls
y2038: sched: Change sched_rr_get_interval to use __kernel_timespec
y2038: socket: Change recvmmsg to use __kernel_timespec
y2038: signal: Change rt_sigtimedwait to use __kernel_timespec
Guenter Roeck (1):
RISC-V: Request newstat syscalls
kbuild test robot (1):
y2038: __get_old_timespec32() can be static
arch/alpha/include/asm/unistd.h | 2 ++
arch/arc/include/uapi/asm/unistd.h | 1 +
arch/arm/include/asm/unistd.h | 4 ++--
arch/arm64/include/asm/compat.h | 26 +++++---------------------
arch/arm64/include/asm/stat.h | 2 +-
arch/arm64/include/asm/unistd.h | 2 +-
arch/arm64/include/uapi/asm/unistd.h | 1 +
arch/c6x/include/uapi/asm/unistd.h | 1 +
arch/h8300/include/uapi/asm/unistd.h | 1 +
arch/hexagon/include/uapi/asm/unistd.h | 1 +
arch/ia64/include/asm/unistd.h | 3 +++
arch/m68k/include/asm/unistd.h | 2 +-
arch/microblaze/include/asm/unistd.h | 2 +-
arch/mips/include/asm/compat.h | 28 +++++-----------------------
arch/mips/include/asm/unistd.h | 3 ++-
arch/mips/kernel/binfmt_elfn32.c | 14 +++++++-------
arch/mips/kernel/binfmt_elfo32.c | 14 +++++++-------
arch/nds32/include/uapi/asm/unistd.h | 1 +
arch/nios2/include/uapi/asm/unistd.h | 1 +
arch/openrisc/include/uapi/asm/unistd.h | 1 +
arch/parisc/include/asm/compat.h | 24 +++++-------------------
arch/parisc/include/asm/unistd.h | 3 ++-
arch/powerpc/include/asm/compat.h | 24 +++++-------------------
arch/powerpc/include/asm/unistd.h | 3 ++-
arch/powerpc/kernel/asm-offsets.c | 8 ++++----
arch/powerpc/oprofile/backtrace.c | 2 +-
arch/riscv/include/asm/unistd.h | 1 +
arch/s390/include/asm/compat.h | 18 ++----------------
arch/s390/include/asm/unistd.h | 3 ++-
arch/sh/include/asm/unistd.h | 2 +-
arch/sparc/include/asm/compat.h | 25 +++++--------------------
arch/sparc/include/asm/unistd.h | 3 ++-
arch/unicore32/include/uapi/asm/unistd.h | 1 +
arch/x86/include/asm/compat.h | 19 ++-----------------
arch/x86/include/asm/unistd.h | 3 ++-
arch/xtensa/include/asm/unistd.h | 2 +-
fs/aio.c | 8 ++++----
fs/compat_binfmt_elf.c | 2 +-
fs/read_write.c | 2 +-
fs/select.c | 20 ++++++++++----------
fs/stat.c | 3 +++
fs/timerfd.c | 12 ++++++------
fs/utimes.c | 73
+++++++++++++++++++++++++++++++++++--------------------------------------
include/asm-generic/compat.h | 24 +++++++++++++++++++++++-
include/asm-generic/unistd.h | 13 -------------
include/linux/compat.h | 101
+++++++++++++++++++++++++++++++++++++++++++++++------------------------------------------------------
include/linux/compat_time.h | 32 --------------------------------
include/linux/elfcore-compat.h | 8 ++++----
include/linux/restart_block.h | 4 ++--
include/linux/socket.h | 4 ++--
include/linux/syscalls.h | 21 ++++++++++++---------
include/linux/time32.h | 78
+++++++++++++++++++++++++++++++++++++++++-------------------------------------
include/linux/timekeeping.h | 12 ------------
include/linux/timekeeping32.h | 53
+++++++----------------------------------------------
include/uapi/asm-generic/unistd.h | 2 ++
ipc/mqueue.c | 8 ++++----
ipc/msg.c | 6 +++---
ipc/sem.c | 10 +++++-----
ipc/shm.c | 6 +++---
ipc/syscall.c | 2 +-
ipc/util.h | 2 +-
kernel/compat.c | 8 ++++----
kernel/futex_compat.c | 2 +-
kernel/sched/core.c | 8 ++++----
kernel/signal.c | 19 ++++++++++---------
kernel/time/hrtimer.c | 8 ++++----
kernel/time/posix-stubs.c | 18 +++++++++---------
kernel/time/posix-timers.c | 30 +++++++++++++++---------------
kernel/time/time.c | 97
++++++++++++++++++++++++++++++++++++++-----------------------------------------------------------
kernel/time/timekeeping.c | 24 ------------------------
net/compat.c | 10 +++++-----
net/socket.c | 18 ++++++++----------
72 files changed, 398 insertions(+), 601 deletions(-)
delete mode 100644 include/asm-generic/unistd.h
delete mode 100644 include/linux/compat_time.h
Reply
Forward
_______________________________________________
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038
^ permalink raw reply
* Re: [PATCH v2 4/5] pselect6: use __kernel_timespec
From: Arnd Bergmann @ 2018-09-15 15:27 UTC (permalink / raw)
To: Deepa Dinamani
Cc: Al Viro, Thomas Gleixner, Linux Kernel Mailing List,
y2038 Mailman List, Linux FS-devel Mailing List, Linux API,
linux-aio
In-Reply-To: <20180915050843.19183-5-deepa.kernel@gmail.com>
On Sat, Sep 15, 2018 at 7:09 AM Deepa Dinamani <deepa.kernel@gmail.com> wrote:
> +#if defined(CONFIG_64BIT_TIME)
> +
> +COMPAT_SYSCALL_DEFINE6(pselect6_time64, int, n, compat_ulong_t __user *, inp,
> + compat_ulong_t __user *, outp, compat_ulong_t __user *, exp,
> + struct __kernel_timespec __user *, tsp, void __user *, sig)
I got a link error here since compat_sys_pselect6_time64 and
compat_sys_ppoll_time64 are only defined when CONFIG_64BIT_TIME
is set.
I did not think we would select this symbol on arm64, is that a mistake
on my side, or should the #ifdef check be removed?
Arnd
--
To unsubscribe, send a message with 'unsubscribe linux-aio' in
the body to majordomo@kvack.org. For more info on Linux AIO,
see: http://www.kvack.org/aio/
Don't email: <a href=mailto:"aart@kvack.org">aart@kvack.org</a>
^ permalink raw reply
* Re: [PATCH] [RFC] making uapi/linux/elfcore.h useful again
From: Ingo Molnar @ 2018-09-15 11:37 UTC (permalink / raw)
To: Arnd Bergmann
Cc: linux-arch, linux-api, Joseph Myers , David Howells,
libc-alpha, Thomas Gleixner, Ingo Molnar, H. Peter Anvin, x86,
linux-kernel
In-Reply-To: <20180914113929.953895-1-arnd@arndb.de>
* Arnd Bergmann <arnd@arndb.de> wrote:
> diff --git a/arch/x86/include/uapi/asm/elf.h b/arch/x86/include/uapi/asm/elf.h
> new file mode 100644
> index 000000000000..a640e1224939
> --- /dev/null
> +++ b/arch/x86/include/uapi/asm/elf.h
> @@ -0,0 +1,30 @@
> +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
> +#ifndef _UAPI_ASM_X86_ELF_H
> +#define _UAPI_ASM_X86_ELF_H
> +
> +#ifdef __i386__
> +
> +/*
> + * These are used to set parameters in the core dumps.
> + */
> +#define ELF_CLASS ELFCLASS32
> +#define ELF_DATA ELFDATA2LSB
> +#define ELF_ARCH EM_386
> +#define ELF_NGREG 17
> +
> +#else
> +
> +/*
> + * These are used to set parameters in the core dumps.
> + */
> +#define ELF_CLASS ELFCLASS64
> +#define ELF_DATA ELFDATA2LSB
> +#define ELF_ARCH EM_X86_64
> +#define ELF_NGREG 27
> +
> +#endif /* __i386__ */
> +
> +typedef unsigned long elf_greg_t;
> +typedef elf_greg_t elf_gregset_t[ELF_NGREG];
> +
> +#endif
On a second thought, maybe deduplicate the comments? Something like:
/*
* These are used to set parameters in core dumps:
*/
#ifdef __i386__
# define ELF_CLASS ELFCLASS32
# define ELF_DATA ELFDATA2LSB
# define ELF_ARCH EM_386
# define ELF_NGREG 17
#else
# define ELF_CLASS ELFCLASS64
# define ELF_DATA ELFDATA2LSB
# define ELF_ARCH EM_X86_64
# define ELF_NGREG 27
#endif
Note:
- I fixed a typo in the comment.
- Aligned the blocks vertically for better visibility.
- The closing #endif comment became unnecessary as well, due to the much more obvious
structure when written this way.
The type changes/cleanups look good otherwise: it's quite probable that it was never directly
included in any user-space library in any sane fashion before, so it's not really an UAPI that
was relied on, as long as it doesn't break the build anywhere.
Thanks,
Ingo
^ permalink raw reply
* [PATCH v2 5/5] io_pgetevents: use __kernel_timespec
From: Deepa Dinamani @ 2018-09-15 5:08 UTC (permalink / raw)
To: viro, tglx, linux-kernel; +Cc: arnd, y2038, linux-fsdevel, linux-api, linux-aio
In-Reply-To: <20180915050843.19183-1-deepa.kernel@gmail.com>
struct timespec is not y2038 safe.
struct __kernel_timespec is the new y2038 safe structure for all
syscalls that are using struct timespec.
Update io_pgetevents interfaces to use struct __kernel_timespec.
sigset_t also has different representations on 32 bit and 64 bit
architectures. Hence, we need to support the following different
syscalls:
New y2038 safe syscalls:
(Controlled by CONFIG_64BIT_TIME for 32 bit ABIs)
Native 64 bit(unchanged) and native 32 bit : sys_io_pgetevents
Compat : compat_sys_io_pgetevents_time64
Older y2038 unsafe syscalls:
(Controlled by CONFIG_32BIT_COMPAT_TIME for 32 bit ABIs)
Native 32 bit : sys_io_pgetevents_time32
Compat : compat_sys_io_pgetevents
Note that io_getevents syscalls do not have a y2038 safe solution.
Signed-off-by: Deepa Dinamani <deepa.kernel@gmail.com>
---
fs/aio.c | 88 ++++++++++++++++++++++++++++++++++++++--
include/linux/compat.h | 6 +++
include/linux/syscalls.h | 10 ++++-
3 files changed, 99 insertions(+), 5 deletions(-)
diff --git a/fs/aio.c b/fs/aio.c
index b81c216534d6..9560f147d7a5 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -2063,11 +2063,13 @@ static long do_io_getevents(aio_context_t ctx_id,
* specifies an infinite timeout. Note that the timeout pointed to by
* timeout is relative. Will fail with -ENOSYS if not implemented.
*/
+#if !defined(CONFIG_64BIT_TIME) || defined(CONFIG_64BIT)
+
SYSCALL_DEFINE5(io_getevents, aio_context_t, ctx_id,
long, min_nr,
long, nr,
struct io_event __user *, events,
- struct timespec __user *, timeout)
+ struct __kernel_timespec __user *, timeout)
{
struct timespec64 ts;
int ret;
@@ -2081,6 +2083,8 @@ SYSCALL_DEFINE5(io_getevents, aio_context_t, ctx_id,
return ret;
}
+#endif
+
struct __aio_sigset {
const sigset_t __user *sigmask;
size_t sigsetsize;
@@ -2091,7 +2095,7 @@ SYSCALL_DEFINE6(io_pgetevents,
long, min_nr,
long, nr,
struct io_event __user *, events,
- struct timespec __user *, timeout,
+ struct __kernel_timespec __user *, timeout,
const struct __aio_sigset __user *, usig)
{
struct __aio_sigset ksig = { NULL, };
@@ -2118,7 +2122,44 @@ SYSCALL_DEFINE6(io_pgetevents,
return ret;
}
-#ifdef CONFIG_COMPAT
+#if defined(CONFIG_COMPAT_32BIT_TIME) && !defined(CONFIG_64BIT)
+
+SYSCALL_DEFINE6(io_pgetevents_time32,
+ aio_context_t, ctx_id,
+ long, min_nr,
+ long, nr,
+ struct io_event __user *, events,
+ struct old_timespec32 __user *, timeout,
+ const struct __aio_sigset __user *, usig)
+{
+ struct __aio_sigset ksig = { NULL, };
+ sigset_t ksigmask, sigsaved;
+ struct timespec64 ts;
+ int ret;
+
+ if (timeout && unlikely(get_old_timespec32(&ts, timeout)))
+ return -EFAULT;
+
+ if (usig && copy_from_user(&ksig, usig, sizeof(ksig)))
+ return -EFAULT;
+
+
+ ret = set_user_sigmask(ksig.sigmask, &ksigmask, &sigsaved, ksig.sigsetsize);
+ if (ret)
+ return ret;
+
+ ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &ts : NULL);
+ restore_user_sigmask(ksig.sigmask, &sigsaved);
+ if (signal_pending(current) && !ret)
+ ret = -ERESTARTNOHAND;
+
+ return ret;
+}
+
+#endif
+
+#if defined(CONFIG_COMPAT_32BIT_TIME)
+
COMPAT_SYSCALL_DEFINE5(io_getevents, compat_aio_context_t, ctx_id,
compat_long_t, min_nr,
compat_long_t, nr,
@@ -2137,12 +2178,17 @@ COMPAT_SYSCALL_DEFINE5(io_getevents, compat_aio_context_t, ctx_id,
return ret;
}
+#endif
+
+#ifdef CONFIG_COMPAT
struct __compat_aio_sigset {
compat_sigset_t __user *sigmask;
compat_size_t sigsetsize;
};
+#if defined(CONFIG_COMPAT_32BIT_TIME)
+
COMPAT_SYSCALL_DEFINE6(io_pgetevents,
compat_aio_context_t, ctx_id,
compat_long_t, min_nr,
@@ -2173,4 +2219,40 @@ COMPAT_SYSCALL_DEFINE6(io_pgetevents,
return ret;
}
+
+#endif
+
+#if defined(CONFIG_64BIT_TIME)
+
+COMPAT_SYSCALL_DEFINE6(io_pgetevents_time64,
+ compat_aio_context_t, ctx_id,
+ compat_long_t, min_nr,
+ compat_long_t, nr,
+ struct io_event __user *, events,
+ struct __kernel_timespec __user *, timeout,
+ const struct __compat_aio_sigset __user *, usig)
+{
+ struct __compat_aio_sigset ksig = { NULL, };
+ sigset_t ksigmask, sigsaved;
+ struct timespec64 t;
+ int ret;
+
+ if (timeout && get_timespec64(&t, timeout))
+ return -EFAULT;
+
+ if (usig && copy_from_user(&ksig, usig, sizeof(ksig)))
+ return -EFAULT;
+
+ ret = set_compat_user_sigmask(ksig.sigmask, &ksigmask, &sigsaved, ksig.sigsetsize);
+ if (ret)
+ return ret;
+
+ ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &t : NULL);
+ restore_user_sigmask(ksig.sigmask, &sigsaved);
+ if (signal_pending(current) && !ret)
+ ret = -ERESTARTNOHAND;
+
+ return ret;
+}
+#endif
#endif
diff --git a/include/linux/compat.h b/include/linux/compat.h
index 6896e6e51c00..50cd0329c8bf 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -556,6 +556,12 @@ asmlinkage long compat_sys_io_pgetevents(compat_aio_context_t ctx_id,
struct io_event __user *events,
struct old_timespec32 __user *timeout,
const struct __compat_aio_sigset __user *usig);
+asmlinkage long compat_sys_io_pgetevents_time64(compat_aio_context_t ctx_id,
+ compat_long_t min_nr,
+ compat_long_t nr,
+ struct io_event __user *events,
+ struct __kernel_timespec __user *timeout,
+ const struct __compat_aio_sigset __user *usig);
/* fs/cookies.c */
asmlinkage long compat_sys_lookup_dcookie(u32, u32, char __user *, compat_size_t);
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index e9cd0409c3fe..3ff0e29c082c 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -297,12 +297,18 @@ asmlinkage long sys_io_getevents(aio_context_t ctx_id,
long min_nr,
long nr,
struct io_event __user *events,
- struct timespec __user *timeout);
+ struct __kernel_timespec __user *timeout);
asmlinkage long sys_io_pgetevents(aio_context_t ctx_id,
long min_nr,
long nr,
struct io_event __user *events,
- struct timespec __user *timeout,
+ struct __kernel_timespec __user *timeout,
+ const struct __aio_sigset *sig);
+asmlinkage long sys_io_pgetevents_time32(aio_context_t ctx_id,
+ long min_nr,
+ long nr,
+ struct io_event __user *events,
+ struct old_timespec32 __user *timeout,
const struct __aio_sigset *sig);
/* fs/xattr.c */
--
2.17.1
--
To unsubscribe, send a message with 'unsubscribe linux-aio' in
the body to majordomo@kvack.org. For more info on Linux AIO,
see: http://www.kvack.org/aio/
Don't email: <a href=mailto:"aart@kvack.org">aart@kvack.org</a>
^ permalink raw reply related
* [PATCH v2 4/5] pselect6: use __kernel_timespec
From: Deepa Dinamani @ 2018-09-15 5:08 UTC (permalink / raw)
To: viro, tglx, linux-kernel; +Cc: arnd, y2038, linux-fsdevel, linux-api, linux-aio
In-Reply-To: <20180915050843.19183-1-deepa.kernel@gmail.com>
struct timespec is not y2038 safe.
struct __kernel_timespec is the new y2038 safe structure for all
syscalls that are using struct timespec.
Update pselect interfaces to use struct __kernel_timespec.
sigset_t also has different representations on 32 bit and 64 bit
architectures. Hence, we need to support the following different
syscalls:
New y2038 safe syscalls:
(Controlled by CONFIG_64BIT_TIME for 32 bit ABIs)
Native 64 bit(unchanged) and native 32 bit : sys_pselect6
Compat : compat_sys_pselect6_time64
Older y2038 unsafe syscalls:
(Controlled by CONFIG_32BIT_COMPAT_TIME for 32 bit ABIs)
Native 32 bit : pselect6_time32
Compat : compat_sys_pselect6
Note that all other versions of select syscalls will not have
y2038 safe versions.
Signed-off-by: Deepa Dinamani <deepa.kernel@gmail.com>
---
fs/select.c | 98 ++++++++++++++++++++++++++++++++++------
include/linux/compat.h | 5 ++
include/linux/syscalls.h | 5 +-
3 files changed, 94 insertions(+), 14 deletions(-)
diff --git a/fs/select.c b/fs/select.c
index f3beef5e0eea..b338b40c43e6 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -729,16 +729,27 @@ SYSCALL_DEFINE5(select, int, n, fd_set __user *, inp, fd_set __user *, outp,
}
static long do_pselect(int n, fd_set __user *inp, fd_set __user *outp,
- fd_set __user *exp, struct timespec __user *tsp,
- const sigset_t __user *sigmask, size_t sigsetsize)
+ fd_set __user *exp, void __user *tsp,
+ const sigset_t __user *sigmask, size_t sigsetsize,
+ enum poll_time_type type)
{
sigset_t ksigmask, sigsaved;
struct timespec64 ts, end_time, *to = NULL;
int ret;
if (tsp) {
- if (get_timespec64(&ts, tsp))
- return -EFAULT;
+ switch (type) {
+ case PT_TIMESPEC:
+ if (get_timespec64(&ts, tsp))
+ return -EFAULT;
+ break;
+ case PT_OLD_TIMESPEC:
+ if (get_old_timespec32(&ts, tsp))
+ return -EFAULT;
+ break;
+ default:
+ BUG();
+ }
to = &end_time;
if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec))
@@ -750,7 +761,7 @@ static long do_pselect(int n, fd_set __user *inp, fd_set __user *outp,
return ret;
ret = core_sys_select(n, inp, outp, exp, to);
- ret = poll_select_copy_remaining(&end_time, tsp, PT_TIMESPEC, ret);
+ ret = poll_select_copy_remaining(&end_time, tsp, type, ret);
restore_user_sigmask(sigmask, &sigsaved);
@@ -764,7 +775,27 @@ static long do_pselect(int n, fd_set __user *inp, fd_set __user *outp,
* the sigset size.
*/
SYSCALL_DEFINE6(pselect6, int, n, fd_set __user *, inp, fd_set __user *, outp,
- fd_set __user *, exp, struct timespec __user *, tsp,
+ fd_set __user *, exp, struct __kernel_timespec __user *, tsp,
+ void __user *, sig)
+{
+ size_t sigsetsize = 0;
+ sigset_t __user *up = NULL;
+
+ if (sig) {
+ if (!access_ok(VERIFY_READ, sig, sizeof(void *)+sizeof(size_t))
+ || __get_user(up, (sigset_t __user * __user *)sig)
+ || __get_user(sigsetsize,
+ (size_t __user *)(sig+sizeof(void *))))
+ return -EFAULT;
+ }
+
+ return do_pselect(n, inp, outp, exp, tsp, up, sigsetsize, PT_TIMESPEC);
+}
+
+#if defined(CONFIG_COMPAT_32BIT_TIME) && !defined(CONFIG_64BIT)
+
+SYSCALL_DEFINE6(pselect6_time32, int, n, fd_set __user *, inp, fd_set __user *, outp,
+ fd_set __user *, exp, struct old_timespec32 __user *, tsp,
void __user *, sig)
{
size_t sigsetsize = 0;
@@ -778,9 +809,11 @@ SYSCALL_DEFINE6(pselect6, int, n, fd_set __user *, inp, fd_set __user *, outp,
return -EFAULT;
}
- return do_pselect(n, inp, outp, exp, tsp, up, sigsetsize);
+ return do_pselect(n, inp, outp, exp, tsp, up, sigsetsize, PT_OLD_TIMESPEC);
}
+#endif
+
#ifdef __ARCH_WANT_SYS_OLD_SELECT
struct sel_arg_struct {
unsigned long n;
@@ -1289,16 +1322,26 @@ COMPAT_SYSCALL_DEFINE1(old_select, struct compat_sel_arg_struct __user *, arg)
static long do_compat_pselect(int n, compat_ulong_t __user *inp,
compat_ulong_t __user *outp, compat_ulong_t __user *exp,
- struct old_timespec32 __user *tsp, compat_sigset_t __user *sigmask,
- compat_size_t sigsetsize)
+ void __user *tsp, compat_sigset_t __user *sigmask,
+ compat_size_t sigsetsize, enum poll_time_type type)
{
sigset_t ksigmask, sigsaved;
struct timespec64 ts, end_time, *to = NULL;
int ret;
if (tsp) {
- if (get_old_timespec32(&ts, tsp))
- return -EFAULT;
+ switch (type) {
+ case PT_OLD_TIMESPEC:
+ if (get_old_timespec32(&ts, tsp))
+ return -EFAULT;
+ break;
+ case PT_TIMESPEC:
+ if (get_old_timespec32(&ts, tsp))
+ return -EFAULT;
+ break;
+ default:
+ BUG();
+ }
to = &end_time;
if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec))
@@ -1310,13 +1353,39 @@ static long do_compat_pselect(int n, compat_ulong_t __user *inp,
return ret;
ret = compat_core_sys_select(n, inp, outp, exp, to);
- ret = poll_select_copy_remaining(&end_time, tsp, PT_OLD_TIMESPEC, ret);
+ ret = poll_select_copy_remaining(&end_time, tsp, type, ret);
restore_user_sigmask(sigmask, &sigsaved);
return ret;
}
+#if defined(CONFIG_64BIT_TIME)
+
+COMPAT_SYSCALL_DEFINE6(pselect6_time64, int, n, compat_ulong_t __user *, inp,
+ compat_ulong_t __user *, outp, compat_ulong_t __user *, exp,
+ struct __kernel_timespec __user *, tsp, void __user *, sig)
+{
+ compat_size_t sigsetsize = 0;
+ compat_uptr_t up = 0;
+
+ if (sig) {
+ if (!access_ok(VERIFY_READ, sig,
+ sizeof(compat_uptr_t)+sizeof(compat_size_t)) ||
+ __get_user(up, (compat_uptr_t __user *)sig) ||
+ __get_user(sigsetsize,
+ (compat_size_t __user *)(sig+sizeof(up))))
+ return -EFAULT;
+ }
+
+ return do_compat_pselect(n, inp, outp, exp, tsp, compat_ptr(up),
+ sigsetsize, PT_TIMESPEC);
+}
+
+#endif
+
+#if defined(CONFIG_COMPAT_32BIT_TIME)
+
COMPAT_SYSCALL_DEFINE6(pselect6, int, n, compat_ulong_t __user *, inp,
compat_ulong_t __user *, outp, compat_ulong_t __user *, exp,
struct old_timespec32 __user *, tsp, void __user *, sig)
@@ -1332,10 +1401,13 @@ COMPAT_SYSCALL_DEFINE6(pselect6, int, n, compat_ulong_t __user *, inp,
(compat_size_t __user *)(sig+sizeof(up))))
return -EFAULT;
}
+
return do_compat_pselect(n, inp, outp, exp, tsp, compat_ptr(up),
- sigsetsize);
+ sigsetsize, PT_OLD_TIMESPEC);
}
+#endif
+
#if defined(CONFIG_COMPAT_32BIT_TIME)
COMPAT_SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds,
unsigned int, nfds, struct old_timespec32 __user *, tsp,
diff --git a/include/linux/compat.h b/include/linux/compat.h
index 349a2d98e450..6896e6e51c00 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -641,6 +641,11 @@ asmlinkage long compat_sys_pselect6(int n, compat_ulong_t __user *inp,
compat_ulong_t __user *exp,
struct old_timespec32 __user *tsp,
void __user *sig);
+asmlinkage long compat_sys_pselect6_time64(int n, compat_ulong_t __user *inp,
+ compat_ulong_t __user *outp,
+ compat_ulong_t __user *exp,
+ struct __kernel_timespec __user *tsp,
+ void __user *sig);
asmlinkage long compat_sys_ppoll(struct pollfd __user *ufds,
unsigned int nfds,
struct old_timespec32 __user *tsp,
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 9755e70cfbb0..e9cd0409c3fe 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -467,7 +467,10 @@ asmlinkage long sys_sendfile64(int out_fd, int in_fd,
/* fs/select.c */
asmlinkage long sys_pselect6(int, fd_set __user *, fd_set __user *,
- fd_set __user *, struct timespec __user *,
+ fd_set __user *, struct __kernel_timespec __user *,
+ void __user *);
+asmlinkage long sys_pselect6_time32(int, fd_set __user *, fd_set __user *,
+ fd_set __user *, struct old_timespec32 __user *,
void __user *);
asmlinkage long sys_ppoll(struct pollfd __user *, unsigned int,
struct __kernel_timespec __user *, const sigset_t __user *,
--
2.17.1
--
To unsubscribe, send a message with 'unsubscribe linux-aio' in
the body to majordomo@kvack.org. For more info on Linux AIO,
see: http://www.kvack.org/aio/
Don't email: <a href=mailto:"aart@kvack.org">aart@kvack.org</a>
^ permalink raw reply related
* [PATCH v2 3/5] ppoll: use __kernel_timespec
From: Deepa Dinamani @ 2018-09-15 5:08 UTC (permalink / raw)
To: viro, tglx, linux-kernel; +Cc: arnd, y2038, linux-fsdevel, linux-api, linux-aio
In-Reply-To: <20180915050843.19183-1-deepa.kernel@gmail.com>
struct timespec is not y2038 safe.
struct __kernel_timespec is the new y2038 safe structure for all
syscalls that are using struct timespec.
Update ppoll interfaces to use struct __kernel_timespec.
sigset_t also has different representations on 32 bit and 64 bit
architectures. Hence, we need to support the following different
syscalls:
New y2038 safe syscalls:
(Controlled by CONFIG_64BIT_TIME for 32 bit ABIs)
Native 64 bit(unchanged) and native 32 bit : sys_ppoll
Compat : compat_sys_ppoll_time64
Older y2038 unsafe syscalls:
(Controlled by CONFIG_32BIT_COMPAT_TIME for 32 bit ABIs)
Native 32 bit : ppoll_time32
Compat : compat_sys_ppoll
Signed-off-by: Deepa Dinamani <deepa.kernel@gmail.com>
---
fs/select.c | 169 ++++++++++++++++++++++++++-------------
include/linux/compat.h | 5 ++
include/linux/syscalls.h | 5 +-
3 files changed, 123 insertions(+), 56 deletions(-)
diff --git a/fs/select.c b/fs/select.c
index eb9132520197..f3beef5e0eea 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -287,12 +287,18 @@ int poll_select_set_timeout(struct timespec64 *to, time64_t sec, long nsec)
return 0;
}
+enum poll_time_type {
+ PT_TIMEVAL = 0,
+ PT_OLD_TIMEVAL = 1,
+ PT_TIMESPEC = 2,
+ PT_OLD_TIMESPEC = 3,
+};
+
static int poll_select_copy_remaining(struct timespec64 *end_time,
void __user *p,
- int timeval, int ret)
+ enum poll_time_type pt_type, int ret)
{
struct timespec64 rts;
- struct timeval rtv;
if (!p)
return ret;
@@ -310,18 +316,40 @@ static int poll_select_copy_remaining(struct timespec64 *end_time,
rts.tv_sec = rts.tv_nsec = 0;
- if (timeval) {
- if (sizeof(rtv) > sizeof(rtv.tv_sec) + sizeof(rtv.tv_usec))
- memset(&rtv, 0, sizeof(rtv));
- rtv.tv_sec = rts.tv_sec;
- rtv.tv_usec = rts.tv_nsec / NSEC_PER_USEC;
+ switch (pt_type) {
+ case PT_TIMEVAL:
+ {
+ struct timeval rtv;
- if (!copy_to_user(p, &rtv, sizeof(rtv)))
+ if (sizeof(rtv) > sizeof(rtv.tv_sec) + sizeof(rtv.tv_usec))
+ memset(&rtv, 0, sizeof(rtv));
+ rtv.tv_sec = rts.tv_sec;
+ rtv.tv_usec = rts.tv_nsec / NSEC_PER_USEC;
+ if (!copy_to_user(p, &rtv, sizeof(rtv)))
+ return ret;
+ }
+ break;
+ case PT_OLD_TIMEVAL:
+ {
+ struct old_timeval32 rtv;
+
+ rtv.tv_sec = rts.tv_sec;
+ rtv.tv_usec = rts.tv_nsec / NSEC_PER_USEC;
+ if (!copy_to_user(p, &rtv, sizeof(rtv)))
+ return ret;
+ }
+ break;
+ case PT_TIMESPEC:
+ if (!put_timespec64(&rts, p))
return ret;
-
- } else if (!put_timespec64(&rts, p))
- return ret;
-
+ break;
+ case PT_OLD_TIMESPEC:
+ if (!put_old_timespec32(&rts, p))
+ return ret;
+ break;
+ default:
+ BUG();
+ }
/*
* If an application puts its timeval in read-only memory, we
* don't want the Linux-specific update to the timeval to
@@ -689,7 +717,7 @@ static int kern_select(int n, fd_set __user *inp, fd_set __user *outp,
}
ret = core_sys_select(n, inp, outp, exp, to);
- ret = poll_select_copy_remaining(&end_time, tvp, 1, ret);
+ ret = poll_select_copy_remaining(&end_time, tvp, PT_TIMEVAL, ret);
return ret;
}
@@ -722,7 +750,7 @@ static long do_pselect(int n, fd_set __user *inp, fd_set __user *outp,
return ret;
ret = core_sys_select(n, inp, outp, exp, to);
- ret = poll_select_copy_remaining(&end_time, tsp, 0, ret);
+ ret = poll_select_copy_remaining(&end_time, tsp, PT_TIMESPEC, ret);
restore_user_sigmask(sigmask, &sigsaved);
@@ -1026,7 +1054,7 @@ SYSCALL_DEFINE3(poll, struct pollfd __user *, ufds, unsigned int, nfds,
}
SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds, unsigned int, nfds,
- struct timespec __user *, tsp, const sigset_t __user *, sigmask,
+ struct __kernel_timespec __user *, tsp, const sigset_t __user *, sigmask,
size_t, sigsetsize)
{
sigset_t ksigmask, sigsaved;
@@ -1054,60 +1082,50 @@ SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds, unsigned int, nfds,
if (ret == -EINTR)
ret = -ERESTARTNOHAND;
- ret = poll_select_copy_remaining(&end_time, tsp, 0, ret);
+ ret = poll_select_copy_remaining(&end_time, tsp, PT_TIMESPEC, ret);
return ret;
}
-#ifdef CONFIG_COMPAT
-#define __COMPAT_NFDBITS (8 * sizeof(compat_ulong_t))
+#if defined(CONFIG_COMPAT_32BIT_TIME) && !defined(CONFIG_64BIT)
-static
-int compat_poll_select_copy_remaining(struct timespec64 *end_time, void __user *p,
- int timeval, int ret)
+SYSCALL_DEFINE5(ppoll_time32, struct pollfd __user *, ufds, unsigned int, nfds,
+ struct old_timespec32 __user *, tsp, const sigset_t __user *, sigmask,
+ size_t, sigsetsize)
{
- struct timespec64 ts;
+ sigset_t ksigmask, sigsaved;
+ struct timespec64 ts, end_time, *to = NULL;
+ int ret;
- if (!p)
- return ret;
+ if (tsp) {
+ if (get_old_timespec32(&ts, tsp))
+ return -EFAULT;
- if (current->personality & STICKY_TIMEOUTS)
- goto sticky;
+ to = &end_time;
+ if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec))
+ return -EINVAL;
+ }
- /* No update for zero timeout */
- if (!end_time->tv_sec && !end_time->tv_nsec)
+ ret = set_user_sigmask(sigmask, &ksigmask, &sigsaved, sigsetsize);
+ if (ret)
return ret;
- ktime_get_ts64(&ts);
- ts = timespec64_sub(*end_time, ts);
- if (ts.tv_sec < 0)
- ts.tv_sec = ts.tv_nsec = 0;
+ ret = do_sys_poll(ufds, nfds, to);
- if (timeval) {
- struct old_timeval32 rtv;
+ restore_user_sigmask(sigmask, &sigsaved);
- rtv.tv_sec = ts.tv_sec;
- rtv.tv_usec = ts.tv_nsec / NSEC_PER_USEC;
+ /* We can restart this syscall, usually */
+ if (ret == -EINTR)
+ ret = -ERESTARTNOHAND;
- if (!copy_to_user(p, &rtv, sizeof(rtv)))
- return ret;
- } else {
- if (!put_old_timespec32(&ts, p))
- return ret;
- }
- /*
- * If an application puts its timeval in read-only memory, we
- * don't want the Linux-specific update to the timeval to
- * cause a fault after the select has completed
- * successfully. However, because we're not updating the
- * timeval, we can't restart the system call.
- */
+ ret = poll_select_copy_remaining(&end_time, tsp, PT_OLD_TIMESPEC, ret);
-sticky:
- if (ret == -ERESTARTNOHAND)
- ret = -EINTR;
return ret;
}
+#endif
+
+#ifdef CONFIG_COMPAT
+#define __COMPAT_NFDBITS (8 * sizeof(compat_ulong_t))
/*
* Ooo, nasty. We need here to frob 32-bit unsigned longs to
@@ -1239,7 +1257,7 @@ static int do_compat_select(int n, compat_ulong_t __user *inp,
}
ret = compat_core_sys_select(n, inp, outp, exp, to);
- ret = compat_poll_select_copy_remaining(&end_time, tvp, 1, ret);
+ ret = poll_select_copy_remaining(&end_time, tvp, PT_OLD_TIMEVAL, ret);
return ret;
}
@@ -1292,7 +1310,7 @@ static long do_compat_pselect(int n, compat_ulong_t __user *inp,
return ret;
ret = compat_core_sys_select(n, inp, outp, exp, to);
- ret = compat_poll_select_copy_remaining(&end_time, tsp, 0, ret);
+ ret = poll_select_copy_remaining(&end_time, tsp, PT_OLD_TIMESPEC, ret);
restore_user_sigmask(sigmask, &sigsaved);
@@ -1318,6 +1336,7 @@ COMPAT_SYSCALL_DEFINE6(pselect6, int, n, compat_ulong_t __user *, inp,
sigsetsize);
}
+#if defined(CONFIG_COMPAT_32BIT_TIME)
COMPAT_SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds,
unsigned int, nfds, struct old_timespec32 __user *, tsp,
const compat_sigset_t __user *, sigmask, compat_size_t, sigsetsize)
@@ -1347,8 +1366,48 @@ COMPAT_SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds,
if (ret == -EINTR)
ret = -ERESTARTNOHAND;
- ret = compat_poll_select_copy_remaining(&end_time, tsp, 0, ret);
+ ret = poll_select_copy_remaining(&end_time, tsp, PT_OLD_TIMESPEC, ret);
+
+ return ret;
+}
+#endif
+
+/* New compat syscall for 64 bit time_t*/
+#if defined(CONFIG_64BIT_TIME)
+
+COMPAT_SYSCALL_DEFINE5(ppoll_time64, struct pollfd __user *, ufds,
+ unsigned int, nfds, struct __kernel_timespec __user *, tsp,
+ const compat_sigset_t __user *, sigmask, compat_size_t, sigsetsize)
+{
+ sigset_t ksigmask, sigsaved;
+ struct timespec64 ts, end_time, *to = NULL;
+ int ret;
+
+ if (tsp) {
+ if (get_timespec64(&ts, tsp))
+ return -EFAULT;
+
+ to = &end_time;
+ if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec))
+ return -EINVAL;
+ }
+
+ ret = set_compat_user_sigmask(sigmask, &ksigmask, &sigsaved, sigsetsize);
+ if (ret)
+ return ret;
+
+ ret = do_sys_poll(ufds, nfds, to);
+
+ restore_user_sigmask(sigmask, &sigsaved);
+
+ /* We can restart this syscall, usually */
+ if (ret == -EINTR)
+ ret = -ERESTARTNOHAND;
+
+ ret = poll_select_copy_remaining(&end_time, tsp, PT_TIMESPEC, ret);
return ret;
}
+
+#endif
#endif
diff --git a/include/linux/compat.h b/include/linux/compat.h
index 03d65c509eeb..349a2d98e450 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -646,6 +646,11 @@ asmlinkage long compat_sys_ppoll(struct pollfd __user *ufds,
struct old_timespec32 __user *tsp,
const compat_sigset_t __user *sigmask,
compat_size_t sigsetsize);
+asmlinkage long compat_sys_ppoll_time64(struct pollfd __user *ufds,
+ unsigned int nfds,
+ struct __kernel_timespec __user *tsp,
+ const compat_sigset_t __user *sigmask,
+ compat_size_t sigsetsize);
/* fs/signalfd.c */
asmlinkage long compat_sys_signalfd4(int ufd,
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 82682b69435e..9755e70cfbb0 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -470,7 +470,10 @@ asmlinkage long sys_pselect6(int, fd_set __user *, fd_set __user *,
fd_set __user *, struct timespec __user *,
void __user *);
asmlinkage long sys_ppoll(struct pollfd __user *, unsigned int,
- struct timespec __user *, const sigset_t __user *,
+ struct __kernel_timespec __user *, const sigset_t __user *,
+ size_t);
+asmlinkage long sys_ppoll_time32(struct pollfd __user *, unsigned int,
+ struct old_timespec32 __user *, const sigset_t __user *,
size_t);
/* fs/signalfd.c */
--
2.17.1
--
To unsubscribe, send a message with 'unsubscribe linux-aio' in
the body to majordomo@kvack.org. For more info on Linux AIO,
see: http://www.kvack.org/aio/
Don't email: <a href=mailto:"aart@kvack.org">aart@kvack.org</a>
^ permalink raw reply related
* [PATCH v2 2/5] signal: Add restore_user_sigmask()
From: Deepa Dinamani @ 2018-09-15 5:08 UTC (permalink / raw)
To: viro, tglx, linux-kernel; +Cc: arnd, y2038, linux-fsdevel, linux-api, linux-aio
In-Reply-To: <20180915050843.19183-1-deepa.kernel@gmail.com>
Refactor the logic to restore the sigmask before the syscall
returns into an api.
This is useful for versions of syscalls that pass in the
sigmask and expect the current->sigmask to be changed during
the execution and restored after the execution of the syscall.
With the advent of new y2038 syscalls in the subsequent patches,
we add 2 more new versions of the syscalls(for pselect, ppoll
and io_pgetevents) in addition to the existing native and compat
versions. Adding such an api reduces the logic that would need to
be replicated otherwise.
Signed-off-by: Deepa Dinamani <deepa.kernel@gmail.com>
---
fs/aio.c | 29 +++++---------------
fs/eventpoll.c | 30 ++-------------------
fs/select.c | 60 ++++++------------------------------------
include/linux/signal.h | 2 ++
kernel/signal.c | 33 +++++++++++++++++++++++
5 files changed, 51 insertions(+), 103 deletions(-)
diff --git a/fs/aio.c b/fs/aio.c
index 67e5b1f6fb0f..b81c216534d6 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -2111,18 +2111,9 @@ SYSCALL_DEFINE6(io_pgetevents,
return ret;
ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &ts : NULL);
- if (signal_pending(current)) {
- if (ksig.sigmask) {
- current->saved_sigmask = sigsaved;
- set_restore_sigmask();
- }
-
- if (!ret)
- ret = -ERESTARTNOHAND;
- } else {
- if (ksig.sigmask)
- sigprocmask(SIG_SETMASK, &sigsaved, NULL);
- }
+ restore_user_sigmask(ksig.sigmask, &sigsaved);
+ if (signal_pending(current) && !ret)
+ ret = -ERESTARTNOHAND;
return ret;
}
@@ -2176,17 +2167,9 @@ COMPAT_SYSCALL_DEFINE6(io_pgetevents,
return ret;
ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &t : NULL);
- if (signal_pending(current)) {
- if (ksig.sigmask) {
- current->saved_sigmask = sigsaved;
- set_restore_sigmask();
- }
- if (!ret)
- ret = -ERESTARTNOHAND;
- } else {
- if (ksig.sigmask)
- sigprocmask(SIG_SETMASK, &sigsaved, NULL);
- }
+ restore_user_sigmask(ksig.sigmask, &sigsaved);
+ if (signal_pending(current) && !ret)
+ ret = -ERESTARTNOHAND;
return ret;
}
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index 2d86eeba837b..8a5a1010886b 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -2229,20 +2229,7 @@ SYSCALL_DEFINE6(epoll_pwait, int, epfd, struct epoll_event __user *, events,
error = do_epoll_wait(epfd, events, maxevents, timeout);
- /*
- * If we changed the signal mask, we need to restore the original one.
- * In case we've got a signal while waiting, we do not restore the
- * signal mask yet, and we allow do_signal() to deliver the signal on
- * the way back to userspace, before the signal mask is restored.
- */
- if (sigmask) {
- if (error == -EINTR) {
- memcpy(¤t->saved_sigmask, &sigsaved,
- sizeof(sigsaved));
- set_restore_sigmask();
- } else
- set_current_blocked(&sigsaved);
- }
+ restore_user_sigmask(sigmask, &sigsaved);
return error;
}
@@ -2267,20 +2254,7 @@ COMPAT_SYSCALL_DEFINE6(epoll_pwait, int, epfd,
err = do_epoll_wait(epfd, events, maxevents, timeout);
- /*
- * If we changed the signal mask, we need to restore the original one.
- * In case we've got a signal while waiting, we do not restore the
- * signal mask yet, and we allow do_signal() to deliver the signal on
- * the way back to userspace, before the signal mask is restored.
- */
- if (sigmask) {
- if (err == -EINTR) {
- memcpy(¤t->saved_sigmask, &sigsaved,
- sizeof(sigsaved));
- set_restore_sigmask();
- } else
- set_current_blocked(&sigsaved);
- }
+ restore_user_sigmask(sigmask, &sigsaved);
return err;
}
diff --git a/fs/select.c b/fs/select.c
index 65c78b4147a2..eb9132520197 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -724,19 +724,7 @@ static long do_pselect(int n, fd_set __user *inp, fd_set __user *outp,
ret = core_sys_select(n, inp, outp, exp, to);
ret = poll_select_copy_remaining(&end_time, tsp, 0, ret);
- if (ret == -ERESTARTNOHAND) {
- /*
- * Don't restore the signal mask yet. Let do_signal() deliver
- * the signal on the way back to userspace, before the signal
- * mask is restored.
- */
- if (sigmask) {
- memcpy(¤t->saved_sigmask, &sigsaved,
- sizeof(sigsaved));
- set_restore_sigmask();
- }
- } else if (sigmask)
- sigprocmask(SIG_SETMASK, &sigsaved, NULL);
+ restore_user_sigmask(sigmask, &sigsaved);
return ret;
}
@@ -1060,21 +1048,11 @@ SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds, unsigned int, nfds,
ret = do_sys_poll(ufds, nfds, to);
+ restore_user_sigmask(sigmask, &sigsaved);
+
/* We can restart this syscall, usually */
- if (ret == -EINTR) {
- /*
- * Don't restore the signal mask yet. Let do_signal() deliver
- * the signal on the way back to userspace, before the signal
- * mask is restored.
- */
- if (sigmask) {
- memcpy(¤t->saved_sigmask, &sigsaved,
- sizeof(sigsaved));
- set_restore_sigmask();
- }
+ if (ret == -EINTR)
ret = -ERESTARTNOHAND;
- } else if (sigmask)
- sigprocmask(SIG_SETMASK, &sigsaved, NULL);
ret = poll_select_copy_remaining(&end_time, tsp, 0, ret);
@@ -1316,19 +1294,7 @@ static long do_compat_pselect(int n, compat_ulong_t __user *inp,
ret = compat_core_sys_select(n, inp, outp, exp, to);
ret = compat_poll_select_copy_remaining(&end_time, tsp, 0, ret);
- if (ret == -ERESTARTNOHAND) {
- /*
- * Don't restore the signal mask yet. Let do_signal() deliver
- * the signal on the way back to userspace, before the signal
- * mask is restored.
- */
- if (sigmask) {
- memcpy(¤t->saved_sigmask, &sigsaved,
- sizeof(sigsaved));
- set_restore_sigmask();
- }
- } else if (sigmask)
- sigprocmask(SIG_SETMASK, &sigsaved, NULL);
+ restore_user_sigmask(sigmask, &sigsaved);
return ret;
}
@@ -1375,21 +1341,11 @@ COMPAT_SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds,
ret = do_sys_poll(ufds, nfds, to);
+ restore_user_sigmask(sigmask, &sigsaved);
+
/* We can restart this syscall, usually */
- if (ret == -EINTR) {
- /*
- * Don't restore the signal mask yet. Let do_signal() deliver
- * the signal on the way back to userspace, before the signal
- * mask is restored.
- */
- if (sigmask) {
- memcpy(¤t->saved_sigmask, &sigsaved,
- sizeof(sigsaved));
- set_restore_sigmask();
- }
+ if (ret == -EINTR)
ret = -ERESTARTNOHAND;
- } else if (sigmask)
- sigprocmask(SIG_SETMASK, &sigsaved, NULL);
ret = compat_poll_select_copy_remaining(&end_time, tsp, 0, ret);
diff --git a/include/linux/signal.h b/include/linux/signal.h
index 403e63d01bcf..ed8be17afe89 100644
--- a/include/linux/signal.h
+++ b/include/linux/signal.h
@@ -265,6 +265,8 @@ extern int __group_send_sig_info(int, struct siginfo *, struct task_struct *);
extern int sigprocmask(int, sigset_t *, sigset_t *);
extern int set_user_sigmask(const sigset_t __user *usigmask, sigset_t *set,
sigset_t *oldset, size_t sigsetsize);
+extern void restore_user_sigmask(const void __user *usigmask,
+ sigset_t *sigsaved);
extern void set_current_blocked(sigset_t *);
extern void __set_current_blocked(const sigset_t *);
extern int show_unhandled_signals;
diff --git a/kernel/signal.c b/kernel/signal.c
index 1d72dcddcaaf..457d1abe62a4 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -2783,6 +2783,39 @@ int set_compat_user_sigmask(const compat_sigset_t __user *usigmask,
EXPORT_SYMBOL(set_compat_user_sigmask);
#endif
+/*
+ * restore_user_sigmask:
+ * usigmask: sigmask passed in from userland.
+ * sigsaved: saved sigmask when the syscall started and changed the sigmask to
+ * usigmask.
+ *
+ * This is useful for syscalls such as ppoll, pselect, io_pgetevents and
+ * epoll_pwait where a new sigmask is passed in from userland for the syscalls.
+ */
+void restore_user_sigmask(const void __user *usigmask, sigset_t *sigsaved)
+{
+
+ if (!usigmask)
+ return;
+ /*
+ * When signals are pending, do not restore them here.
+ * Restoring sigmask here can lead to delivering signals that the above
+ * syscalls are intended to block because of the sigmask passed in.
+ */
+ if (signal_pending(current)) {
+ current->saved_sigmask = *sigsaved;
+ set_restore_sigmask();
+ return;
+ }
+
+ /*
+ * This is needed because the fast syscall return path does not restore
+ * saved_sigmask when signals are not pending.
+ */
+ set_current_blocked(sigsaved);
+}
+EXPORT_SYMBOL(restore_user_sigmask);
+
/**
* sys_rt_sigprocmask - change the list of currently blocked signals
* @how: whether to add, remove, or set signals
--
2.17.1
--
To unsubscribe, send a message with 'unsubscribe linux-aio' in
the body to majordomo@kvack.org. For more info on Linux AIO,
see: http://www.kvack.org/aio/
Don't email: <a href=mailto:"aart@kvack.org">aart@kvack.org</a>
^ permalink raw reply related
* [PATCH v2 1/5] signal: Add set_user_sigmask()
From: Deepa Dinamani @ 2018-09-15 5:08 UTC (permalink / raw)
To: viro, tglx, linux-kernel; +Cc: arnd, y2038, linux-fsdevel, linux-api, linux-aio
In-Reply-To: <20180915050843.19183-1-deepa.kernel@gmail.com>
Refactor reading sigset from userspace and updating sigmask
into an api.
This is useful for versions of syscalls that pass in the
sigmask and expect the current->sigmask to be changed during
the execution and restored after the execution of the syscall.
With the advent of new y2038 syscalls in the subsequent patches,
we add 2 more new versions of the syscalls(for pselect, ppoll
and io_pgetevents) in addition to the existing native and compat
versions. Adding such an api reduces the logic that would need to
be replicated otherwise.
Note that the calls to sigprocmask() ignored the return value
from the api as the function only returns an error on an invalid
first argument that is hardcoded at these call sites.
The updated logic uses set_current_blocked() instead.
Signed-off-by: Deepa Dinamani <deepa.kernel@gmail.com>
---
fs/aio.c | 23 ++++++-------------
fs/eventpoll.c | 22 +++++--------------
fs/select.c | 50 ++++++++++--------------------------------
include/linux/compat.h | 4 ++++
include/linux/signal.h | 2 ++
kernel/signal.c | 45 +++++++++++++++++++++++++++++++++++++
6 files changed, 76 insertions(+), 70 deletions(-)
diff --git a/fs/aio.c b/fs/aio.c
index 2914e8c1b3d2..67e5b1f6fb0f 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -2105,14 +2105,10 @@ SYSCALL_DEFINE6(io_pgetevents,
if (usig && copy_from_user(&ksig, usig, sizeof(ksig)))
return -EFAULT;
- if (ksig.sigmask) {
- if (ksig.sigsetsize != sizeof(sigset_t))
- return -EINVAL;
- if (copy_from_user(&ksigmask, ksig.sigmask, sizeof(ksigmask)))
- return -EFAULT;
- sigdelsetmask(&ksigmask, sigmask(SIGKILL) | sigmask(SIGSTOP));
- sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
- }
+
+ ret = set_user_sigmask(ksig.sigmask, &ksigmask, &sigsaved, ksig.sigsetsize);
+ if (ret)
+ return ret;
ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &ts : NULL);
if (signal_pending(current)) {
@@ -2175,14 +2171,9 @@ COMPAT_SYSCALL_DEFINE6(io_pgetevents,
if (usig && copy_from_user(&ksig, usig, sizeof(ksig)))
return -EFAULT;
- if (ksig.sigmask) {
- if (ksig.sigsetsize != sizeof(compat_sigset_t))
- return -EINVAL;
- if (get_compat_sigset(&ksigmask, ksig.sigmask))
- return -EFAULT;
- sigdelsetmask(&ksigmask, sigmask(SIGKILL) | sigmask(SIGSTOP));
- sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
- }
+ ret = set_compat_user_sigmask(ksig.sigmask, &ksigmask, &sigsaved, ksig.sigsetsize);
+ if (ret)
+ return ret;
ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &t : NULL);
if (signal_pending(current)) {
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index 42bbe6824b4b..2d86eeba837b 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -2223,14 +2223,9 @@ SYSCALL_DEFINE6(epoll_pwait, int, epfd, struct epoll_event __user *, events,
* If the caller wants a certain signal mask to be set during the wait,
* we apply it here.
*/
- if (sigmask) {
- if (sigsetsize != sizeof(sigset_t))
- return -EINVAL;
- if (copy_from_user(&ksigmask, sigmask, sizeof(ksigmask)))
- return -EFAULT;
- sigsaved = current->blocked;
- set_current_blocked(&ksigmask);
- }
+ error = set_user_sigmask(sigmask, &ksigmask, &sigsaved, sigsetsize);
+ if (error)
+ return error;
error = do_epoll_wait(epfd, events, maxevents, timeout);
@@ -2266,14 +2261,9 @@ COMPAT_SYSCALL_DEFINE6(epoll_pwait, int, epfd,
* If the caller wants a certain signal mask to be set during the wait,
* we apply it here.
*/
- if (sigmask) {
- if (sigsetsize != sizeof(compat_sigset_t))
- return -EINVAL;
- if (get_compat_sigset(&ksigmask, sigmask))
- return -EFAULT;
- sigsaved = current->blocked;
- set_current_blocked(&ksigmask);
- }
+ err = set_compat_user_sigmask(sigmask, &ksigmask, &sigsaved, sigsetsize);
+ if (err)
+ return err;
err = do_epoll_wait(epfd, events, maxevents, timeout);
diff --git a/fs/select.c b/fs/select.c
index 22b3bf89f051..65c78b4147a2 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -717,16 +717,9 @@ static long do_pselect(int n, fd_set __user *inp, fd_set __user *outp,
return -EINVAL;
}
- if (sigmask) {
- /* XXX: Don't preclude handling different sized sigset_t's. */
- if (sigsetsize != sizeof(sigset_t))
- return -EINVAL;
- if (copy_from_user(&ksigmask, sigmask, sizeof(ksigmask)))
- return -EFAULT;
-
- sigdelsetmask(&ksigmask, sigmask(SIGKILL)|sigmask(SIGSTOP));
- sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
- }
+ ret = set_user_sigmask(sigmask, &ksigmask, &sigsaved, sigsetsize);
+ if (ret)
+ return ret;
ret = core_sys_select(n, inp, outp, exp, to);
ret = poll_select_copy_remaining(&end_time, tsp, 0, ret);
@@ -1061,16 +1054,9 @@ SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds, unsigned int, nfds,
return -EINVAL;
}
- if (sigmask) {
- /* XXX: Don't preclude handling different sized sigset_t's. */
- if (sigsetsize != sizeof(sigset_t))
- return -EINVAL;
- if (copy_from_user(&ksigmask, sigmask, sizeof(ksigmask)))
- return -EFAULT;
-
- sigdelsetmask(&ksigmask, sigmask(SIGKILL)|sigmask(SIGSTOP));
- sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
- }
+ ret = set_user_sigmask(sigmask, &ksigmask, &sigsaved, sigsetsize);
+ if (ret)
+ return ret;
ret = do_sys_poll(ufds, nfds, to);
@@ -1323,15 +1309,9 @@ static long do_compat_pselect(int n, compat_ulong_t __user *inp,
return -EINVAL;
}
- if (sigmask) {
- if (sigsetsize != sizeof(compat_sigset_t))
- return -EINVAL;
- if (get_compat_sigset(&ksigmask, sigmask))
- return -EFAULT;
-
- sigdelsetmask(&ksigmask, sigmask(SIGKILL)|sigmask(SIGSTOP));
- sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
- }
+ ret = set_compat_user_sigmask(sigmask, &ksigmask, &sigsaved, sigsetsize);
+ if (ret)
+ return ret;
ret = compat_core_sys_select(n, inp, outp, exp, to);
ret = compat_poll_select_copy_remaining(&end_time, tsp, 0, ret);
@@ -1389,15 +1369,9 @@ COMPAT_SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds,
return -EINVAL;
}
- if (sigmask) {
- if (sigsetsize != sizeof(compat_sigset_t))
- return -EINVAL;
- if (get_compat_sigset(&ksigmask, sigmask))
- return -EFAULT;
-
- sigdelsetmask(&ksigmask, sigmask(SIGKILL)|sigmask(SIGSTOP));
- sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
- }
+ ret = set_compat_user_sigmask(sigmask, &ksigmask, &sigsaved, sigsetsize);
+ if (ret)
+ return ret;
ret = do_sys_poll(ufds, nfds, to);
diff --git a/include/linux/compat.h b/include/linux/compat.h
index 6fb5abdb87be..03d65c509eeb 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -166,6 +166,10 @@ typedef struct {
compat_sigset_word sig[_COMPAT_NSIG_WORDS];
} compat_sigset_t;
+int set_compat_user_sigmask(const compat_sigset_t __user *usigmask,
+ sigset_t *set, sigset_t *oldset,
+ size_t sigsetsize);
+
struct compat_sigaction {
#ifndef __ARCH_HAS_IRIX_SIGACTION
compat_uptr_t sa_handler;
diff --git a/include/linux/signal.h b/include/linux/signal.h
index 3d4cd5db30a9..403e63d01bcf 100644
--- a/include/linux/signal.h
+++ b/include/linux/signal.h
@@ -263,6 +263,8 @@ extern int group_send_sig_info(int sig, struct siginfo *info,
struct task_struct *p, enum pid_type type);
extern int __group_send_sig_info(int, struct siginfo *, struct task_struct *);
extern int sigprocmask(int, sigset_t *, sigset_t *);
+extern int set_user_sigmask(const sigset_t __user *usigmask, sigset_t *set,
+ sigset_t *oldset, size_t sigsetsize);
extern void set_current_blocked(sigset_t *);
extern void __set_current_blocked(const sigset_t *);
extern int show_unhandled_signals;
diff --git a/kernel/signal.c b/kernel/signal.c
index 0831d56a731a..1d72dcddcaaf 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -2738,6 +2738,51 @@ int sigprocmask(int how, sigset_t *set, sigset_t *oldset)
return 0;
}
+/*
+ * The api helps set app-provided sigmasks.
+ *
+ * This is useful for syscalls such as ppoll, pselect, io_pgetevents and
+ * epoll_pwait where a new sigmask is passed from userland for the syscalls.
+ */
+int set_user_sigmask(const sigset_t __user *usigmask, sigset_t *set,
+ sigset_t *oldset, size_t sigsetsize)
+{
+ if (!usigmask)
+ return 0;
+
+ if (sigsetsize != sizeof(sigset_t))
+ return -EINVAL;
+ if (copy_from_user(set, usigmask, sizeof(sigset_t)))
+ return -EFAULT;
+
+ *oldset = current->blocked;
+ set_current_blocked(set);
+
+ return 0;
+}
+EXPORT_SYMBOL(set_user_sigmask);
+
+#ifdef CONFIG_COMPAT
+int set_compat_user_sigmask(const compat_sigset_t __user *usigmask,
+ sigset_t *set, sigset_t *oldset,
+ size_t sigsetsize)
+{
+ if (!usigmask)
+ return 0;
+
+ if (sigsetsize != sizeof(compat_sigset_t))
+ return -EINVAL;
+ if (get_compat_sigset(set, usigmask))
+ return -EFAULT;
+
+ *oldset = current->blocked;
+ set_current_blocked(set);
+
+ return 0;
+}
+EXPORT_SYMBOL(set_compat_user_sigmask);
+#endif
+
/**
* sys_rt_sigprocmask - change the list of currently blocked signals
* @how: whether to add, remove, or set signals
--
2.17.1
--
To unsubscribe, send a message with 'unsubscribe linux-aio' in
the body to majordomo@kvack.org. For more info on Linux AIO,
see: http://www.kvack.org/aio/
Don't email: <a href=mailto:"aart@kvack.org">aart@kvack.org</a>
^ permalink raw reply related
* [PATCH v2 0/5] y2038: Make ppoll, io_pgetevents and pselect y2038 safe
From: Deepa Dinamani @ 2018-09-15 5:08 UTC (permalink / raw)
To: viro, tglx, linux-kernel; +Cc: y2038, linux-fsdevel, linux-aio, arnd, linux-api
The series transitions the ppoll, io_getevents, and pselect syscalls
to be y2038 safe.
This is part of the work proceeding for syscalls for y2038.
It is based on the series [1] from Arnd Bergmann.
The overview of the series is as below:
1. Refactor sigmask handling logic for the above syscalls.
2. Provide y2038 safe versions of syscalls for all ABIs.
[1] https://lkml.org/lkml/2018/8/27/651
Changes since v1:
* fixed bug pointed out by arnd
Deepa Dinamani (5):
signal: Add set_user_sigmask()
signal: Add restore_user_sigmask()
ppoll: use __kernel_timespec
pselect6: use __kernel_timespec
io_pgetevents: use __kernel_timespec
fs/aio.c | 138 ++++++++++-----
fs/eventpoll.c | 52 +-----
fs/select.c | 367 +++++++++++++++++++++++----------------
include/linux/compat.h | 20 +++
include/linux/signal.h | 4 +
include/linux/syscalls.h | 20 ++-
kernel/signal.c | 78 +++++++++
7 files changed, 437 insertions(+), 242 deletions(-)
--
2.17.1
_______________________________________________
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038
^ permalink raw reply
* Re: [PATCH 3/5] ppoll: use __kernel_timespec
From: Deepa Dinamani @ 2018-09-14 22:07 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Alexander Viro, Thomas Gleixner, Linux Kernel Mailing List,
y2038 Mailman List, Linux FS-devel Mailing List, Linux API,
linux-aio
In-Reply-To: <CAK8P3a1zQBQz1ZtNZzkceut4k3eLjOjCwvOtBdEmc9cTsaFz+g@mail.gmail.com>
On Fri, Sep 14, 2018 at 8:57 AM Arnd Bergmann <arnd@arndb.de> wrote:
>
> On Sat, Sep 1, 2018 at 10:48 PM Deepa Dinamani <deepa.kernel@gmail.com> wrote:
>
> > +
> > + /* We can restart this syscall, usually */
> > + if (ret == -EINTR) {
> > + restore_user_sigmask(sigmask, &sigsaved);
> > + ret = -ERESTARTNOHAND;
> > + }
>
> I need a little help understanding this part: In the two existing copies of that
> function, you have changed it to
>
> restore_user_sigmask(sigmask, &sigsaved);
> if (ret == -EINTR)
> ret = -ERESTARTNOHAND;
>
> in the previous patch, but the new new copies you add here do
>
> if (ret == -EINTR) {
> restore_user_sigmask(sigmask, &sigsaved);
> ret = -ERESTARTNOHAND;
> }
>
> Is that intentional, or did you accidently leave a version in here that
> you had changed afterwards?
Oops, you are right. This wasn't intentional.
I will send out a v2.
Thanks,
Deepa
--
To unsubscribe, send a message with 'unsubscribe linux-aio' in
the body to majordomo@kvack.org. For more info on Linux AIO,
see: http://www.kvack.org/aio/
Don't email: <a href=mailto:"aart@kvack.org">aart@kvack.org</a>
^ permalink raw reply
* Re: [RFC PATCH v3 12/24] x86/mm: Modify ptep_set_wrprotect and pmdp_set_wrprotect for _PAGE_DIRTY_SW
From: Dave Hansen @ 2018-09-14 21:33 UTC (permalink / raw)
To: Yu-cheng Yu, Peter Zijlstra
Cc: Jann Horn, the arch/x86 maintainers, H . Peter Anvin,
Thomas Gleixner, Ingo Molnar, kernel list, linux-doc, Linux-MM,
linux-arch, Linux API, Arnd Bergmann, Andy Lutomirski,
Balbir Singh, Cyrill Gorcunov, Florian Weimer, hjl.tools,
Jonathan Corbet, keescook, Mike Kravetz, Nadav Amit,
Oleg Nesterov, Pavel Machek
In-Reply-To: <1536959337.12990.27.camel@intel.com>
On 09/14/2018 02:08 PM, Yu-cheng Yu wrote:
> On Fri, 2018-09-14 at 13:46 -0700, Dave Hansen wrote:
>> On 09/14/2018 01:39 PM, Yu-cheng Yu wrote:
>>>
>>> With the updated ptep_set_wrprotect() below, I did MADV_WILLNEED to a shadow
>>> stack of 8 MB, then 10,000 fork()'s, but could not prove it is more or less
>>> efficient than the other. So can we say this is probably fine in terms of
>>> efficiency?
BTW, I wasn't particularly concerned about shadow stacks. Plain old
memory is affected by this change too. Right?
>> Well, the first fork() will do all the hard work. I don't think
>> subsequent fork()s will be affected.
>
> Are you talking about a recent commit:
>
> 1b2de5d0 mm/cow: don't bother write protecting already write-protected pages
>
> With that, subsequent fork()s will not do all the hard work.
> However, I have not done that for shadow stack PTEs (do we want to do that?).
> I think the additional benefit for shadow stack is small?
You're right. mprotect() doesn't use this path.
But, that reminds me, can you take a quick look at change_pte_range()
and double-check that it's not affected by this issue?
^ permalink raw reply
* Re: [RFC PATCH v3 05/24] Documentation/x86: Add CET description
From: Yu-cheng Yu @ 2018-09-14 21:17 UTC (permalink / raw)
To: Pavel Machek
Cc: x86, H. Peter Anvin, Thomas Gleixner, Ingo Molnar, linux-kernel,
linux-doc, linux-mm, linux-arch, linux-api, Arnd Bergmann,
Andy Lutomirski, Balbir Singh, Cyrill Gorcunov, Dave Hansen,
Florian Weimer, H.J. Lu, Jann Horn, Jonathan Corbet, Kees Cook,
Mike Kravetz, Nadav Amit, Oleg Nesterov, Peter Zijlstra
In-Reply-To: <20180830203948.GB1936@amd>
On Thu, 2018-08-30 at 22:39 +0200, Pavel Machek wrote:
> Hi!
>
> >
> > diff --git a/Documentation/admin-guide/kernel-parameters.txt
> > b/Documentation/admin-guide/kernel-parameters.txt
> > index 9871e649ffef..b090787188b4 100644
> > --- a/Documentation/admin-guide/kernel-parameters.txt
> > +++ b/Documentation/admin-guide/kernel-parameters.txt
> > @@ -2764,6 +2764,12 @@
> > noexec=on: enable non-executable mappings (default)
> > noexec=off: disable non-executable mappings
> >
> > + no_cet_ibt [X86-64] Disable indirect branch tracking for
> > user-mode
> > + applications
> > +
> > + no_cet_shstk [X86-64] Disable shadow stack support for user-
> > mode
> > + applications
> Hmm, not too consistent with "nosmap" below. Would it make sense to
> have cet=on/off/ibt/shstk instead?
We also have noxsave, noxsaveopt, noxsaves, etc. This style is more decisive?
If "cet=" is preferred, we can change it later?
Yu-cheng
^ permalink raw reply
* Re: [RFC PATCH v3 12/24] x86/mm: Modify ptep_set_wrprotect and pmdp_set_wrprotect for _PAGE_DIRTY_SW
From: Yu-cheng Yu @ 2018-09-14 21:08 UTC (permalink / raw)
To: Dave Hansen, Peter Zijlstra
Cc: Jann Horn, the arch/x86 maintainers, H . Peter Anvin,
Thomas Gleixner, Ingo Molnar, kernel list, linux-doc, Linux-MM,
linux-arch, Linux API, Arnd Bergmann, Andy Lutomirski,
Balbir Singh, Cyrill Gorcunov, Florian Weimer, hjl.tools,
Jonathan Corbet, keescook, Mike Kravetz, Nadav Amit,
Oleg Nesterov, Pavel Machek
In-Reply-To: <8d9ce0e9-8fc7-8c68-4aa9-9aed9ee949f2@linux.intel.com>
On Fri, 2018-09-14 at 13:46 -0700, Dave Hansen wrote:
> On 09/14/2018 01:39 PM, Yu-cheng Yu wrote:
> >
> > With the updated ptep_set_wrprotect() below, I did MADV_WILLNEED to a shadow
> > stack of 8 MB, then 10,000 fork()'s, but could not prove it is more or less
> > efficient than the other. So can we say this is probably fine in terms of
> > efficiency?
> Well, the first fork() will do all the hard work. I don't think
> subsequent fork()s will be affected.
Are you talking about a recent commit:
1b2de5d0 mm/cow: don't bother write protecting already write-protected pages
With that, subsequent fork()s will not do all the hard work.
However, I have not done that for shadow stack PTEs (do we want to do that?).
I think the additional benefit for shadow stack is small?
>
> Did you do something to ensure this code was being run?
>
> I would guess that a loop like this:
>
> for (i = 0; i < 10000; i++) {
> mprotect(addr, len, PROT_READ);
> mprotect(addr, len, PROT_READ|PROT_WRITE);
> }
>
> might show it better.
Would mprotect() do copy_one_pte()? Otherwise it will not go through
ptep_set_wrprotect()?
^ permalink raw reply
* Re: [RFC PATCH v3 19/24] x86/cet/shstk: Introduce WRUSS instruction
From: Yu-cheng Yu @ 2018-09-14 20:46 UTC (permalink / raw)
To: Andy Lutomirski
Cc: Jann Horn, the arch/x86 maintainers, H . Peter Anvin,
Thomas Gleixner, Ingo Molnar, kernel list, linux-doc, Linux-MM,
linux-arch, Linux API, Arnd Bergmann, Balbir Singh,
Cyrill Gorcunov, Dave Hansen, Florian Weimer, H. J. Lu,
Jonathan Corbet, Kees Cook, Mike Kravetz, Nadav Amit,
Oleg Nesterov
In-Reply-To: <CALCETrV_aDasfkd6LD1cT11Hs1dO064uHjROLQPyhQfy_iuS8w@mail.gmail.com>
On Fri, 2018-08-31 at 15:16 -0700, Andy Lutomirski wrote:
> On Fri, Aug 31, 2018 at 2:49 PM, Yu-cheng Yu <yu-cheng.yu@intel.com> wrote:
> >
> > On Thu, 2018-08-30 at 09:22 -0700, Yu-cheng Yu wrote:
> > >
> > > On Thu, 2018-08-30 at 08:55 -0700, Andy Lutomirski wrote:
> > > >
> > > >
> > > > On Thu, Aug 30, 2018 at 8:39 AM, Jann Horn <jannh@google.com>
> > > > wrote:
> > > > >
> > > > >
> > > > >
> > > > > On Thu, Aug 30, 2018 at 4:44 PM Yu-cheng Yu <yu-cheng.yu@intel.c
> > > > > om
> > > > > >
> > > > > >
> > > > > > wrote:
> > > > > >
> > > > > >
> > > > > > WRUSS is a new kernel-mode instruction but writes directly
> > > > > > to user shadow stack memory. This is used to construct
> > > > > > a return address on the shadow stack for the signal
> > > > > > handler.
> > > > > >
> > > > > > This instruction can fault if the user shadow stack is
> > > > > > invalid shadow stack memory. In that case, the kernel does
> > > > > > fixup.
> > > > > >
> > > > > > Signed-off-by: Yu-cheng Yu <yu-cheng.yu@intel.com>
> > > > > [...]
> > > > > >
> > > > > >
> > > > > >
> > > > > > +static inline int write_user_shstk_64(unsigned long addr,
> > > > > > unsigned long val)
> > > > > > +{
> > > > > > + int err = 0;
> > > > > > +
> > > > > > + asm volatile("1: wrussq %1, (%0)\n"
> > > > > > + "2:\n"
> > > > > > + _ASM_EXTABLE_HANDLE(1b, 2b,
> > > > > > ex_handler_wruss)
> > > > > > + :
> > > > > > + : "r" (addr), "r" (val));
> > > > > > +
> > > > > > + return err;
> > > > > > +}
> > > > > What's up with "err"? You set it to zero, and then you return
> > > > > it,
> > > > > but
> > > > > nothing can ever set it to non-zero, right?
> > > > >
> > > > > >
> > > > > >
> > > > > >
> > > > > > +__visible bool ex_handler_wruss(const struct
> > > > > > exception_table_entry *fixup,
> > > > > > + struct pt_regs *regs, int
> > > > > > trapnr)
> > > > > > +{
> > > > > > + regs->ip = ex_fixup_addr(fixup);
> > > > > > + regs->ax = -1;
> > > > > > + return true;
> > > > > > +}
> > > > > And here you just write into regs->ax, but your "asm volatile"
> > > > > doesn't
> > > > > reserve that register. This looks wrong to me.
> > > > >
> > > > > I think you probably want to add something like an explicit
> > > > > `"+&a"(err)` output to the asm statements.
> > > > We require asm goto support these days. How about using
> > > > that? You
> > > > won't even need a special exception handler.
> > Maybe something like this? It looks simple now.
> >
> > static inline int write_user_shstk_64(unsigned long addr, unsigned
> > long val)
> > {
> > asm_volatile_goto("wrussq %1, (%0)\n"
> > "jmp %l[ok]\n"
> > ".section .fixup,\"ax\"n"
> > "jmp %l[fail]\n"
> > ".previous\n"
> > :: "r" (addr), "r" (val)
> > :: ok, fail);
> > ok:
> > return 0;
> > fail:
> > return -1;
> > }
> >
> I think you can get rid of 'jmp %l[ok]' and the ok label and just fall
> through. And you don't need an explicit jmp to fail -- just set the
> _EX_HANDLER entry to land on the fail label.
Thanks! This now looks simple and much better.
Yu-cheng
+static inline int write_user_shstk_64(unsigned long addr, unsigned long val)
+{
+ asm_volatile_goto("1: wrussq %1, (%0)\n"
+ _ASM_EXTABLE(1b, %l[fail])
+ :: "r" (addr), "r" (val)
+ :: fail);
+ return 0;
+fail:
+ return -1;
+}
^ permalink raw reply
* Re: [RFC PATCH v3 12/24] x86/mm: Modify ptep_set_wrprotect and pmdp_set_wrprotect for _PAGE_DIRTY_SW
From: Dave Hansen @ 2018-09-14 20:46 UTC (permalink / raw)
To: Yu-cheng Yu, Peter Zijlstra
Cc: Jann Horn, the arch/x86 maintainers, H . Peter Anvin,
Thomas Gleixner, Ingo Molnar, kernel list, linux-doc, Linux-MM,
linux-arch, Linux API, Arnd Bergmann, Andy Lutomirski,
Balbir Singh, Cyrill Gorcunov, Florian Weimer, hjl.tools,
Jonathan Corbet, keescook, Mike Kravetz, Nadav Amit,
Oleg Nesterov, Pavel Machek
In-Reply-To: <1536957543.12990.9.camel@intel.com>
On 09/14/2018 01:39 PM, Yu-cheng Yu wrote:
> With the updated ptep_set_wrprotect() below, I did MADV_WILLNEED to a shadow
> stack of 8 MB, then 10,000 fork()'s, but could not prove it is more or less
> efficient than the other. So can we say this is probably fine in terms of
> efficiency?
Well, the first fork() will do all the hard work. I don't think
subsequent fork()s will be affected.
Did you do something to ensure this code was being run?
I would guess that a loop like this:
for (i = 0; i < 10000; i++) {
mprotect(addr, len, PROT_READ);
mprotect(addr, len, PROT_READ|PROT_WRITE);
}
might show it better.
^ permalink raw reply
* Re: [RFC PATCH v3 12/24] x86/mm: Modify ptep_set_wrprotect and pmdp_set_wrprotect for _PAGE_DIRTY_SW
From: Yu-cheng Yu @ 2018-09-14 20:39 UTC (permalink / raw)
To: Peter Zijlstra, Dave Hansen
Cc: Jann Horn, the arch/x86 maintainers, H . Peter Anvin,
Thomas Gleixner, Ingo Molnar, kernel list, linux-doc, Linux-MM,
linux-arch, Linux API, Arnd Bergmann, Andy Lutomirski,
Balbir Singh, Cyrill Gorcunov, Florian Weimer, hjl.tools,
Jonathan Corbet, keescook, Mike Kravetz, Nadav Amit,
Oleg Nesterov, Pavel Machek
In-Reply-To: <20180831162920.GQ24124@hirez.programming.kicks-ass.net>
On Fri, 2018-08-31 at 18:29 +0200, Peter Zijlstra wrote:
> On Fri, Aug 31, 2018 at 08:58:39AM -0700, Dave Hansen wrote:
> >
> > On 08/31/2018 08:48 AM, Yu-cheng Yu wrote:
> > >
> > > To trigger a race in ptep_set_wrprotect(), we need to fork from one of
> > > three pthread siblings.
> > >
> > > Or do we measure only how much this affects fork?
> > > If there is no racing, the effect should be minimal.
> > We don't need a race.
> >
> > I think the cmpxchg will be slower, even without a race, than the code
> > that was there before. The cmpxchg is a simple, straightforward
> > solution, but we're putting it in place of a plain memory write, which
> > is suboptimal.
> Note quite, the clear_bit() is LOCK prefixed.
With the updated ptep_set_wrprotect() below, I did MADV_WILLNEED to a shadow
stack of 8 MB, then 10,000 fork()'s, but could not prove it is more or less
efficient than the other. So can we say this is probably fine in terms of
efficiency?
Yu-cheng
--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -1203,7 +1203,36 @@ static inline pte_t ptep_get_and_clear_full(struct
mm_struct *mm,
static inline void ptep_set_wrprotect(struct mm_struct *mm,
unsigned long addr, pte_t *ptep)
{
+#ifdef CONFIG_X86_INTEL_SHADOW_STACK_USER
+ pte_t new_pte, pte = READ_ONCE(*ptep);
+
+ /*
+ * Some processors can start a write, but end up
+ * seeing a read-only PTE by the time they get
+ * to the Dirty bit. In this case, they will
+ * set the Dirty bit, leaving a read-only, Dirty
+ * PTE which looks like a Shadow Stack PTE.
+ *
+ * However, this behavior has been improved and
+ * will not occur on processors supporting
+ * Shadow Stacks. Without this guarantee, a
+ * transition to a non-present PTE and flush the
+ * TLB would be needed.
+ *
+ * When changing a writable PTE to read-only and
+ * if the PTE has _PAGE_DIRTY_HW set, we move
+ * that bit to _PAGE_DIRTY_SW so that the PTE is
+ * not a valid Shadow Stack PTE.
+ */
+ do {
+ new_pte = pte_wrprotect(pte);
+ new_pte.pte |= (new_pte.pte & _PAGE_DIRTY_HW) >>
+ _PAGE_BIT_DIRTY_HW << _PAGE_BIT_DIRTY_SW;
+ new_pte.pte &= ~_PAGE_DIRTY_HW;
+ } while (!try_cmpxchg(ptep, &pte, new_pte));
+#else
clear_bit(_PAGE_BIT_RW, (unsigned long *)&ptep->pte);
+#endif
}
^ permalink raw reply
* Re: [PATCH] [RFC] making uapi/linux/elfcore.h useful again
From: Arnd Bergmann @ 2018-09-14 19:55 UTC (permalink / raw)
To: Ingo Molnar
Cc: linux-arch, Linux API, Joseph Myers, David Howells, GNU C Library,
Thomas Gleixner, Ingo Molnar, H. Peter Anvin,
the arch/x86 maintainers, Linux Kernel Mailing List
In-Reply-To: <20180914174528.GA35000@gmail.com>
On Fri, Sep 14, 2018 at 7:45 PM Ingo Molnar <mingo@kernel.org> wrote:
> * Arnd Bergmann <arnd@arndb.de> wrote:
> > - Move required data from the private x86 asm/elf.h file into
> > a new uapi/asm/elf.h. Some other architectures already do that,
> > but most of them do not. Before applying the patch, we have
> > to do this for all architectures
>
> Acked-by: Ingo Molnar <mingo@kernel.org>
Thanks,
> I suspect this wants to go through -mm, or do you want to carry it?
-mm is probably best. For now, I just want to see if there are any
concerns about this, and then I'd have to do the full version that
changes all architectures.
Arnd
^ permalink raw reply
* Re: [RFC PATCH] Add /proc/<pid>/numa_vamaps for numa node information
From: Jann Horn @ 2018-09-14 18:14 UTC (permalink / raw)
To: Prakash Sangappa
Cc: Michal Hocko, Dave Hansen, Anshuman Khandual, Andrew Morton,
kernel list, Linux-MM, Linux API, Kirill A . Shutemov,
n-horiguchi, Ulrich Drepper, David Rientjes, Horiguchi Naoya,
steven.sistare
In-Reply-To: <a1834be4-0f8e-9d07-1013-7477d3a5e6be@oracle.com>
On Fri, Sep 14, 2018 at 8:08 PM Prakash Sangappa
<prakash.sangappa@oracle.com> wrote:
> On 9/14/18 5:49 AM, Jann Horn wrote:
> > On Fri, Sep 14, 2018 at 8:21 AM Michal Hocko <mhocko@kernel.org> wrote:
> >> On Fri 14-09-18 03:33:28, Jann Horn wrote:
> >>> On Wed, Sep 12, 2018 at 10:43 PM prakash.sangappa
> >>> <prakash.sangappa@oracle.com> wrote:
> >>>> On 05/09/2018 04:31 PM, Dave Hansen wrote:
> >>>>> On 05/07/2018 06:16 PM, prakash.sangappa wrote:
> >>>>>> It will be /proc/<pid>/numa_vamaps. Yes, the behavior will be
> >>>>>> different with respect to seeking. Output will still be text and
> >>>>>> the format will be same.
> >>>>>>
> >>>>>> I want to get feedback on this approach.
> >>>>> I think it would be really great if you can write down a list of the
> >>>>> things you actually want to accomplish. Dare I say: you need a
> >>>>> requirements list.
> >>>>>
> >>>>> The numa_vamaps approach continues down the path of an ever-growing list
> >>>>> of highly-specialized /proc/<pid> files. I don't think that is
> >>>>> sustainable, even if it has been our trajectory for many years.
> >>>>>
> >>>>> Pagemap wasn't exactly a shining example of us getting new ABIs right,
> >>>>> but it sounds like something along those is what we need.
> >>>> Just sent out a V2 patch. This patch simplifies the file content. It
> >>>> only provides VA range to numa node id information.
> >>>>
> >>>> The requirement is basically observability for performance analysis.
> >>>>
> >>>> - Need to be able to determine VA range to numa node id information.
> >>>> Which also gives an idea of which range has memory allocated.
> >>>>
> >>>> - The proc file /proc/<pid>/numa_vamaps is in text so it is easy to
> >>>> directly view.
> >>>>
> >>>> The V2 patch supports seeking to a particular process VA from where
> >>>> the application could read the VA to numa node id information.
> >>>>
> >>>> Also added the 'PTRACE_MODE_READ_REALCREDS' check when opening the
> >>>> file /proc file as was indicated by Michal Hacko
> >>> procfs files should use PTRACE_MODE_*_FSCREDS, not PTRACE_MODE_*_REALCREDS.
> >> Out of my curiosity, what is the semantic difference? At least
> >> kernel_move_pages uses PTRACE_MODE_READ_REALCREDS. Is this a bug?
> > No, that's fine. REALCREDS basically means "look at the caller's real
> > UID for the access check", while FSCREDS means "look at the caller's
> > filesystem UID". The ptrace access check has historically been using
> > the real UID, which is sorta weird, but normally works fine. Given
> > that this is documented, I didn't see any reason to change it for most
> > things that do ptrace access checks, even if the EUID would IMO be
> > more appropriate. But things that capture caller credentials at points
> > like open() really shouldn't look at the real UID; instead, they
> > should use the filesystem UID (which in practice is basically the same
> > as the EUID).
> >
> > So in short, it depends on the interface you're coming through: Direct
> > syscalls use REALCREDS, things that go through the VFS layer use
> > FSCREDS.
>
> So in this case can the REALCREDS check be done in the read() system call
> when reading the /proc file instead of the open call?
No, REALCREDS shouldn't be used in open() and shouldn't be used in read().
FSCREDS can be used in open(); in theory, using ptrace_may_access() in
any way in read() is currently unsafe, but in practice, it's used that
way anyway. I have plans to clean that up eventually...
^ permalink raw reply
* Re: [RFC PATCH] Add /proc/<pid>/numa_vamaps for numa node information
From: Prakash Sangappa @ 2018-09-14 18:07 UTC (permalink / raw)
To: Jann Horn, Michal Hocko
Cc: Dave Hansen, Anshuman Khandual, Andrew Morton, kernel list,
Linux-MM, Linux API, Kirill A . Shutemov, n-horiguchi,
Ulrich Drepper, David Rientjes, Horiguchi Naoya, steven.sistare
In-Reply-To: <CAG48ez2RSn-EQkf-ahs41tOKpzt23JMGYZxUtWMRPe8c5jAq-A@mail.gmail.com>
On 9/14/18 5:49 AM, Jann Horn wrote:
> On Fri, Sep 14, 2018 at 8:21 AM Michal Hocko <mhocko@kernel.org> wrote:
>> On Fri 14-09-18 03:33:28, Jann Horn wrote:
>>> On Wed, Sep 12, 2018 at 10:43 PM prakash.sangappa
>>> <prakash.sangappa@oracle.com> wrote:
>>>> On 05/09/2018 04:31 PM, Dave Hansen wrote:
>>>>> On 05/07/2018 06:16 PM, prakash.sangappa wrote:
>>>>>> It will be /proc/<pid>/numa_vamaps. Yes, the behavior will be
>>>>>> different with respect to seeking. Output will still be text and
>>>>>> the format will be same.
>>>>>>
>>>>>> I want to get feedback on this approach.
>>>>> I think it would be really great if you can write down a list of the
>>>>> things you actually want to accomplish. Dare I say: you need a
>>>>> requirements list.
>>>>>
>>>>> The numa_vamaps approach continues down the path of an ever-growing list
>>>>> of highly-specialized /proc/<pid> files. I don't think that is
>>>>> sustainable, even if it has been our trajectory for many years.
>>>>>
>>>>> Pagemap wasn't exactly a shining example of us getting new ABIs right,
>>>>> but it sounds like something along those is what we need.
>>>> Just sent out a V2 patch. This patch simplifies the file content. It
>>>> only provides VA range to numa node id information.
>>>>
>>>> The requirement is basically observability for performance analysis.
>>>>
>>>> - Need to be able to determine VA range to numa node id information.
>>>> Which also gives an idea of which range has memory allocated.
>>>>
>>>> - The proc file /proc/<pid>/numa_vamaps is in text so it is easy to
>>>> directly view.
>>>>
>>>> The V2 patch supports seeking to a particular process VA from where
>>>> the application could read the VA to numa node id information.
>>>>
>>>> Also added the 'PTRACE_MODE_READ_REALCREDS' check when opening the
>>>> file /proc file as was indicated by Michal Hacko
>>> procfs files should use PTRACE_MODE_*_FSCREDS, not PTRACE_MODE_*_REALCREDS.
>> Out of my curiosity, what is the semantic difference? At least
>> kernel_move_pages uses PTRACE_MODE_READ_REALCREDS. Is this a bug?
> No, that's fine. REALCREDS basically means "look at the caller's real
> UID for the access check", while FSCREDS means "look at the caller's
> filesystem UID". The ptrace access check has historically been using
> the real UID, which is sorta weird, but normally works fine. Given
> that this is documented, I didn't see any reason to change it for most
> things that do ptrace access checks, even if the EUID would IMO be
> more appropriate. But things that capture caller credentials at points
> like open() really shouldn't look at the real UID; instead, they
> should use the filesystem UID (which in practice is basically the same
> as the EUID).
>
> So in short, it depends on the interface you're coming through: Direct
> syscalls use REALCREDS, things that go through the VFS layer use
> FSCREDS.
So in this case can the REALCREDS check be done in the read() system call
when reading the /proc file instead of the open call?
^ permalink raw reply
* Re: [PATCH] [RFC] making uapi/linux/elfcore.h useful again
From: Ingo Molnar @ 2018-09-14 17:45 UTC (permalink / raw)
To: Arnd Bergmann
Cc: linux-arch, linux-api, Joseph Myers , David Howells,
libc-alpha, Thomas Gleixner, Ingo Molnar, H. Peter Anvin, x86,
linux-kernel
In-Reply-To: <20180914113929.953895-1-arnd@arndb.de>
* Arnd Bergmann <arnd@arndb.de> wrote:
> After finding a bug in glibc the question came up how linux/elfcore.h
> is supposed to be used from user space. As far as I can tell, it's
> not possible, as it references data types that are simply unavailable
> there.
>
> The #ifndef __KERNEL__ section in that header dates back to when the
> file was introduced in linux-1.3.5, and presumably was meant to
> provide the structures for the libc sys/procfs.h implementation.
> However, this was never portable to architectures other than x86-32,
> and has been broken on that architecture at a later point.
>
> These are the steps that I needed to make it possible to include the
> header file, e.g. for libc self-testing in order to make sure the
> structures are compatible with its own:
>
> - drop the #ifndef __KERNEL__ section that are obviously useless
> and get in the way
>
> - change the pid_t references to __kernel_pid_t
>
> - Move required data from the private x86 asm/elf.h file into
> a new uapi/asm/elf.h. Some other architectures already do that,
> but most of them do not. Before applying the patch, we have
> to do this for all architectures
>
> - Change ELF_NGREG to an integer literal constant instead of
> a sizeof operation based on a private type.
>
> Cc: Joseph Myers <joseph@codesourcery.com>
> Cc: David Howells <dhowells@redhat.com>
> Cc: libc-alpha@sourceware.org
> Link: https://patchwork.ozlabs.org/patch/969540/
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
> arch/x86/include/asm/elf.h | 24 +-----------------------
> arch/x86/include/uapi/asm/elf.h | 30 ++++++++++++++++++++++++++++++
> arch/x86/include/uapi/asm/signal.h | 2 +-
> include/uapi/linux/elf.h | 1 +
> include/uapi/linux/elfcore.h | 26 +++++---------------------
> 5 files changed, 38 insertions(+), 45 deletions(-)
> create mode 100644 arch/x86/include/uapi/asm/elf.h
Acked-by: Ingo Molnar <mingo@kernel.org>
I suspect this wants to go through -mm, or do you want to carry it?
Thanks,
Ingo
^ permalink raw reply
* Re: [PATCH 0/5] y2038: Make ppoll, io_pgetevents and pselect y2038 safe
From: Arnd Bergmann @ 2018-09-14 16:06 UTC (permalink / raw)
To: Deepa Dinamani
Cc: Al Viro, Thomas Gleixner, Linux Kernel Mailing List,
y2038 Mailman List, Linux FS-devel Mailing List, Linux API,
linux-aio
In-Reply-To: <20180901204721.13117-1-deepa.kernel@gmail.com>
On Sat, Sep 1, 2018 at 10:48 PM Deepa Dinamani <deepa.kernel@gmail.com> wrote:
>
> The series transitions the ppoll, io_getevents, and pselect syscalls
> to be y2038 safe.
>
> This is part of the work proceeding for syscalls for y2038.
> It is based on the series [1] from Arnd Bergmann.
>
> The overview of the series is as below:
> 1. Refactor sigmask handling logic for the above syscalls.
> 2. Provide y2038 safe versions of syscalls for all ABIs.
>
> [1] https://lkml.org/lkml/2018/8/27/651
Hi Deepa,
This is a very nice series, sorry for taking way too long before
I had a good look at it.
The first two patches in particular are great. The third patch
looks like it has a small bug that I commented on, but given
how much more thought you have put into this than I did, it's
just as possible that I misunderstood it.
I've applied you series locally now, but have not pushed it out
yet for linux-next because of that one issue. I'll send a pull
request to Thomas for my other patches for now, and a
follow-up with these once we have clarified it.
Arnd
--
To unsubscribe, send a message with 'unsubscribe linux-aio' in
the body to majordomo@kvack.org. For more info on Linux AIO,
see: http://www.kvack.org/aio/
Don't email: <a href=mailto:"aart@kvack.org">aart@kvack.org</a>
^ permalink raw reply
* Re: [PATCH 3/5] ppoll: use __kernel_timespec
From: Arnd Bergmann @ 2018-09-14 15:57 UTC (permalink / raw)
To: Deepa Dinamani
Cc: Al Viro, Thomas Gleixner, Linux Kernel Mailing List,
y2038 Mailman List, Linux FS-devel Mailing List, Linux API,
linux-aio
In-Reply-To: <20180901204721.13117-4-deepa.kernel@gmail.com>
On Sat, Sep 1, 2018 at 10:48 PM Deepa Dinamani <deepa.kernel@gmail.com> wrote:
> +
> + /* We can restart this syscall, usually */
> + if (ret == -EINTR) {
> + restore_user_sigmask(sigmask, &sigsaved);
> + ret = -ERESTARTNOHAND;
> + }
I need a little help understanding this part: In the two existing copies of that
function, you have changed it to
restore_user_sigmask(sigmask, &sigsaved);
if (ret == -EINTR)
ret = -ERESTARTNOHAND;
in the previous patch, but the new new copies you add here do
if (ret == -EINTR) {
restore_user_sigmask(sigmask, &sigsaved);
ret = -ERESTARTNOHAND;
}
Is that intentional, or did you accidently leave a version in here that
you had changed afterwards?
Arnd
--
To unsubscribe, send a message with 'unsubscribe linux-aio' in
the body to majordomo@kvack.org. For more info on Linux AIO,
see: http://www.kvack.org/aio/
Don't email: <a href=mailto:"aart@kvack.org">aart@kvack.org</a>
^ permalink raw reply
* Re: [RFC PATCH] Add /proc/<pid>/numa_vamaps for numa node information
From: Michal Hocko @ 2018-09-14 13:49 UTC (permalink / raw)
To: Jann Horn
Cc: Prakash Sangappa, Dave Hansen, Anshuman Khandual, Andrew Morton,
kernel list, Linux-MM, Linux API, Kirill A . Shutemov,
n-horiguchi, Ulrich Drepper, David Rientjes, Horiguchi Naoya,
steven.sistare
In-Reply-To: <CAG48ez2RSn-EQkf-ahs41tOKpzt23JMGYZxUtWMRPe8c5jAq-A@mail.gmail.com>
On Fri 14-09-18 14:49:10, Jann Horn wrote:
> On Fri, Sep 14, 2018 at 8:21 AM Michal Hocko <mhocko@kernel.org> wrote:
> > On Fri 14-09-18 03:33:28, Jann Horn wrote:
> > > On Wed, Sep 12, 2018 at 10:43 PM prakash.sangappa
> > > <prakash.sangappa@oracle.com> wrote:
> > > > On 05/09/2018 04:31 PM, Dave Hansen wrote:
> > > > > On 05/07/2018 06:16 PM, prakash.sangappa wrote:
> > > > >> It will be /proc/<pid>/numa_vamaps. Yes, the behavior will be
> > > > >> different with respect to seeking. Output will still be text and
> > > > >> the format will be same.
> > > > >>
> > > > >> I want to get feedback on this approach.
> > > > > I think it would be really great if you can write down a list of the
> > > > > things you actually want to accomplish. Dare I say: you need a
> > > > > requirements list.
> > > > >
> > > > > The numa_vamaps approach continues down the path of an ever-growing list
> > > > > of highly-specialized /proc/<pid> files. I don't think that is
> > > > > sustainable, even if it has been our trajectory for many years.
> > > > >
> > > > > Pagemap wasn't exactly a shining example of us getting new ABIs right,
> > > > > but it sounds like something along those is what we need.
> > > >
> > > > Just sent out a V2 patch. This patch simplifies the file content. It
> > > > only provides VA range to numa node id information.
> > > >
> > > > The requirement is basically observability for performance analysis.
> > > >
> > > > - Need to be able to determine VA range to numa node id information.
> > > > Which also gives an idea of which range has memory allocated.
> > > >
> > > > - The proc file /proc/<pid>/numa_vamaps is in text so it is easy to
> > > > directly view.
> > > >
> > > > The V2 patch supports seeking to a particular process VA from where
> > > > the application could read the VA to numa node id information.
> > > >
> > > > Also added the 'PTRACE_MODE_READ_REALCREDS' check when opening the
> > > > file /proc file as was indicated by Michal Hacko
> > >
> > > procfs files should use PTRACE_MODE_*_FSCREDS, not PTRACE_MODE_*_REALCREDS.
> >
> > Out of my curiosity, what is the semantic difference? At least
> > kernel_move_pages uses PTRACE_MODE_READ_REALCREDS. Is this a bug?
>
> No, that's fine. REALCREDS basically means "look at the caller's real
> UID for the access check", while FSCREDS means "look at the caller's
> filesystem UID". The ptrace access check has historically been using
> the real UID, which is sorta weird, but normally works fine. Given
> that this is documented, I didn't see any reason to change it for most
> things that do ptrace access checks, even if the EUID would IMO be
> more appropriate. But things that capture caller credentials at points
> like open() really shouldn't look at the real UID; instead, they
> should use the filesystem UID (which in practice is basically the same
> as the EUID).
>
> So in short, it depends on the interface you're coming through: Direct
> syscalls use REALCREDS, things that go through the VFS layer use
> FSCREDS.
Ahh, OK, I see. Thanks for the clarification! Then I agree that the proc
interface should use FSCREDS.
--
Michal Hocko
SUSE Labs
^ permalink raw reply
* Re: [RFC PATCH] Add /proc/<pid>/numa_vamaps for numa node information
From: Jann Horn @ 2018-09-14 12:49 UTC (permalink / raw)
To: Michal Hocko
Cc: Prakash Sangappa, Dave Hansen, Anshuman Khandual, Andrew Morton,
kernel list, Linux-MM, Linux API, Kirill A . Shutemov,
n-horiguchi, Ulrich Drepper, David Rientjes, Horiguchi Naoya,
steven.sistare
In-Reply-To: <20180914062132.GI20287@dhcp22.suse.cz>
On Fri, Sep 14, 2018 at 8:21 AM Michal Hocko <mhocko@kernel.org> wrote:
> On Fri 14-09-18 03:33:28, Jann Horn wrote:
> > On Wed, Sep 12, 2018 at 10:43 PM prakash.sangappa
> > <prakash.sangappa@oracle.com> wrote:
> > > On 05/09/2018 04:31 PM, Dave Hansen wrote:
> > > > On 05/07/2018 06:16 PM, prakash.sangappa wrote:
> > > >> It will be /proc/<pid>/numa_vamaps. Yes, the behavior will be
> > > >> different with respect to seeking. Output will still be text and
> > > >> the format will be same.
> > > >>
> > > >> I want to get feedback on this approach.
> > > > I think it would be really great if you can write down a list of the
> > > > things you actually want to accomplish. Dare I say: you need a
> > > > requirements list.
> > > >
> > > > The numa_vamaps approach continues down the path of an ever-growing list
> > > > of highly-specialized /proc/<pid> files. I don't think that is
> > > > sustainable, even if it has been our trajectory for many years.
> > > >
> > > > Pagemap wasn't exactly a shining example of us getting new ABIs right,
> > > > but it sounds like something along those is what we need.
> > >
> > > Just sent out a V2 patch. This patch simplifies the file content. It
> > > only provides VA range to numa node id information.
> > >
> > > The requirement is basically observability for performance analysis.
> > >
> > > - Need to be able to determine VA range to numa node id information.
> > > Which also gives an idea of which range has memory allocated.
> > >
> > > - The proc file /proc/<pid>/numa_vamaps is in text so it is easy to
> > > directly view.
> > >
> > > The V2 patch supports seeking to a particular process VA from where
> > > the application could read the VA to numa node id information.
> > >
> > > Also added the 'PTRACE_MODE_READ_REALCREDS' check when opening the
> > > file /proc file as was indicated by Michal Hacko
> >
> > procfs files should use PTRACE_MODE_*_FSCREDS, not PTRACE_MODE_*_REALCREDS.
>
> Out of my curiosity, what is the semantic difference? At least
> kernel_move_pages uses PTRACE_MODE_READ_REALCREDS. Is this a bug?
No, that's fine. REALCREDS basically means "look at the caller's real
UID for the access check", while FSCREDS means "look at the caller's
filesystem UID". The ptrace access check has historically been using
the real UID, which is sorta weird, but normally works fine. Given
that this is documented, I didn't see any reason to change it for most
things that do ptrace access checks, even if the EUID would IMO be
more appropriate. But things that capture caller credentials at points
like open() really shouldn't look at the real UID; instead, they
should use the filesystem UID (which in practice is basically the same
as the EUID).
So in short, it depends on the interface you're coming through: Direct
syscalls use REALCREDS, things that go through the VFS layer use
FSCREDS.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox