* Re: [RFC PATCH v4 1/5] glibc: Perform rseq(2) registration at nptl init and thread creation
From: Mathieu Desnoyers @ 2018-12-05 17:24 UTC (permalink / raw)
To: Rich Felker
Cc: Florian Weimer, carlos, Joseph Myers, Szabolcs Nagy, libc-alpha,
Thomas Gleixner, Ben Maurer, Peter Zijlstra, Paul E. McKenney,
Boqun Feng, Will Deacon, Dave Watson, Paul Turner, linux-kernel,
linux-api
In-Reply-To: <20181126170758.GP23599@brightrain.aerifal.cx>
----- On Nov 26, 2018, at 12:07 PM, Rich Felker dalias@libc.org wrote:
> On Mon, Nov 26, 2018 at 11:30:51AM -0500, Mathieu Desnoyers wrote:
>> ----- On Nov 26, 2018, at 10:51 AM, Mathieu Desnoyers
>> mathieu.desnoyers@efficios.com wrote:
>>
>> > ----- On Nov 26, 2018, at 3:28 AM, Florian Weimer fweimer@redhat.com wrote:
>> >
>> >> * Mathieu Desnoyers:
>> >>
>> >>> Using a "weak" symbol in early adopter libraries is important, so they
>> >>> can be loaded together into the same process without causing loader
>> >>> errors due to many definitions of the same strong symbol.
>> >>
>> >> This is not how ELF dynamic linking works. If the symbol name is the
>> >> same, one definition interposes the others.
>> >>
>> >> You need to ensure that the symbol has the same size everywhere, though.
>> >> There are some tricky interactions with symbol versions, too. (The
>> >> interposing libraries must not use symbol versioning.)
>> >
>> > I was under the impression that loading the same strong symbol into an
>> > application multiple times would cause some kind of warning if non-weak. I did
>> > some testing to figure out which case I remembered would cause this.
>> >
>> > When compiling with "-fno-common", dynamic and static linking work fine, but
>> > trying to add multiple instances of a given symbol into a single object fails
>> > with:
>> >
>> > /tmp/ccSakXZV.o:(.bss+0x0): multiple definition of `a'
>> > /tmp/ccQBJBOo.o:(.bss+0x0): first defined here
>> >
>> > Even if the symbol has the same size.
>> >
>> > So considering that we don't care about compiling into a single object here,
>> > and only care about static and dynamic linking of libraries, indeed the "weak"
>> > symbol is not useful.
>> >
>> > So let's make __rseq_abi and __rseq_refcount strong symbols then ?
>>
>> Actually, looking into ld(1) --warn-common, it looks like "weak" would be
>> cleaner
>> after all, especially for __rseq_abi which we needs to be initialized to a
>> specific
>> value, which is therefore not a common symbol.
>>
>> " --warn-common
>> Warn when a common symbol is combined with another common symbol or with a
>> symbol definition. Unix
>> linkers allow this somewhat sloppy practice, but linkers on some other operating
>> systems do not.
>> This option allows you to find potential problems from combining global symbols.
>> Unfortunately,
>> some C libraries use this practice, so you may get some warnings about symbols
>> in the libraries as
>> well as in your programs."
>>
>> Thoughts ?
>
> AFAIK this has nothing to do with dynamic linking.
Reading through the ELF specification, it seems to imply that "weak" only affects the link
editor behavior when combining relocatable objects, not the behavior of the dynamic linker.
Is that what you refer to when you say "weak" has nothing to do with dynamic linking ?
If that interpretation is correct, then indeed I should remove the "weak" from the __rseq_abi
and __rseq_refcount.
Thanks,
Mathieu
--
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com
^ permalink raw reply
* Re: pkeys: Reserve PKEY_DISABLE_READ
From: Andy Lutomirski @ 2018-12-05 16:21 UTC (permalink / raw)
To: linuxram; +Cc: Florian Weimer, Dave Hansen, Linux API, linuxppc-dev, Linux-MM
In-Reply-To: <20181203040249.GA11930@ram.oc3035372033.ibm.com>
> On Dec 2, 2018, at 8:02 PM, Ram Pai <linuxram@us.ibm.com> wrote:
>
>> On Thu, Nov 29, 2018 at 12:37:15PM +0100, Florian Weimer wrote:
>> * Dave Hansen:
>>
>>>> On 11/27/18 3:57 AM, Florian Weimer wrote:
>>>> I would have expected something that translates PKEY_DISABLE_WRITE |
>>>> PKEY_DISABLE_READ into PKEY_DISABLE_ACCESS, and also accepts
>>>> PKEY_DISABLE_ACCESS | PKEY_DISABLE_READ, for consistency with POWER.
>>>>
>>>> (My understanding is that PKEY_DISABLE_ACCESS does not disable all
>>>> access, but produces execute-only memory.)
>>>
>>> Correct, it disables all data access, but not execution.
>>
>> So I would expect something like this (completely untested, I did not
>> even compile this):
>
>
> Ok. I re-read through the entire email thread to understand the problem and
> the proposed solution. Let me summarize it below. Lets see if we are on the same
> plate.
>
> So the problem is as follows:
>
> Currently the kernel supports 'disable-write' and 'disable-access'.
>
> On x86, cpu supports 'disable-write' and 'disable-access'. This
> matches with what the kernel supports. All good.
>
> However on power, cpu supports 'disable-read' too. Since userspace can
> program the cpu directly, userspace has the ability to set
> 'disable-read' too. This can lead to inconsistency between the kernel
> and the userspace.
>
> We want the kernel to match userspace on all architectures.
>
> Proposed Solution:
>
> Enhance the kernel to understand 'disable-read', and facilitate architectures
> that understand 'disable-read' to allow it.
>
> Also explicitly define the semantics of disable-access as
> 'disable-read and disable-write'
>
> Did I get this right? Assuming I did, the implementation has to do
> the following --
>
> On power, sys_pkey_alloc() should succeed if the init_val
> is PKEY_DISABLE_READ, PKEY_DISABLE_WRITE, PKEY_DISABLE_ACCESS
> or any combination of the three.
>
> On x86, sys_pkey_alloc() should succeed if the init_val is
> PKEY_DISABLE_WRITE or PKEY_DISABLE_ACCESS or PKEY_DISABLE_READ
> or any combination of the three, except PKEY_DISABLE_READ
> specified all by itself.
>
> On all other arches, none of the flags are supported.
I don’t really love having a situation where you can use different
flag combinations to refer to the same mode.
Also, we should document the effect these flags have on execute permission.
^ permalink raw reply
* Re: [PATCH] Y2038: provide kernel support indication
From: Joseph Myers @ 2018-12-05 15:26 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Albert ARIBAUD, GNU C Library, Firoz Khan, Linux API,
Andy Lutomirski
In-Reply-To: <CAK8P3a25W8NXY9e=DMzL-jd4+69ecZMyrWGxYDPP4MuH-Ng-9Q@mail.gmail.com>
On Wed, 5 Dec 2018, Arnd Bergmann wrote:
> That would make it very hard to deploy a glibc based system
> with strict y2038 requirements. If we can no longer guarantee the
> basic assumption that old applications keep using the old system
> calls, then I think we instead need a way to build glibc itself without
> support for the 32-bit time_t interfaces, e.g. using a --disable-time32
> configuration switch to force a link-time error for any application
> or library that has not been built against the 64-bit time_t interfaces.
(There's never been a guarantee of keeping using the same system calls.
Cf. people trying to restrict the system calls some code can use and
running into issues with moves to use e.g. *at syscalls unconditionally on
all architectures to implement the non-*at functions.)
The set of interfaces that involve 32-bit time_t or other structures
including it is well-defined; an external checker can examine the dynamic
symbol table of any dynamically linked 32-bit application or shared
library to see if it has references to any of the symbols in question,
without needing to run the code at all (and so detect issues in code that
might not be frequently executed, not just in whatever code runs when
you're testing for 32-bit time uses). (Or if you control the build of the
whole system, do a local change to make a glibc header use #error if
_TIME_BITS is not defined to 64.)
I'd expect it to be a long time before we might consider making 32-bit
time_t (and thus 32-bit off_t) subject to something like
--enable-obsolete-rpc / --enable-obsolete-nsl being needed to make the
32-bit interfaces available at (static) link time at all.
--
Joseph S. Myers
joseph@codesourcery.com
^ permalink raw reply
* Re: [PATCH] Y2038: provide kernel support indication
From: Arnd Bergmann @ 2018-12-05 14:26 UTC (permalink / raw)
To: Joseph Myers
Cc: Albert ARIBAUD, GNU C Library, Firoz Khan, Linux API,
Andy Lutomirski
In-Reply-To: <alpine.DEB.2.21.1812051337210.13925@digraph.polyomino.org.uk>
On Wed, Dec 5, 2018 at 2:48 PM Joseph Myers <joseph@codesourcery.com> wrote:
> On Wed, 5 Dec 2018, Arnd Bergmann wrote:
>
> > I think it's important that we only do this when we are called from
> > an application with 64-bit time_t: When a user calls gettimeofday()
> > with 64-bit time_t, that should try clock_gettime64(2) and fall back
> > to clock_gettime(2) or gettimeofday(2) if that is unavailable. However
> > an application using gettimeofday() with a 32-bit time_t should
> > directly call gettimeofday(2) in the kernel but not try clock_gettime64()
> > first. Without that distinction, the kernel cannot return -ENOSYS
> > if we configure it to break compatibility with 32-bit time_t interfaces
> > and the application might seem to work correctly despite being
> > broken in 2038.
>
> By design, all nontrivial 32-bit time interfaces in glibc for 32-bit
> architectures should end up as simple wrappers round the implementations
> using 64-bit time internally, to avoid duplication of complicated code
> (previous versions of the Y2038 patches e.g. duplicated hundreds of lines
> of pthread_mutex_timedlock implementation, which is clearly not a
> maintainable approach). That means many 32-bit interfaces *will* end up
> using 64-bit syscalls (with fallback to 32-bit if the 64-bit syscalls are
> unavailable at runtime), even if some simple functions that really are
> just one syscall for 32-bit still call the old syscall.
That would make it very hard to deploy a glibc based system
with strict y2038 requirements. If we can no longer guarantee the
basic assumption that old applications keep using the old system
calls, then I think we instead need a way to build glibc itself without
support for the 32-bit time_t interfaces, e.g. using a --disable-time32
configuration switch to force a link-time error for any application
or library that has not been built against the 64-bit time_t interfaces.
The default would of course remain providing backwards compatibility
with all applications to allow a gradual migration from 32-bit time_t
to 64-bit time_t. If all 32-bit time_t calls are just wrappers around
either the internal implementation using 64-bit time_t or around
a simple system call, then it should at least be easy to make them
optional for users that need them not work.
Would that be something you can do?
Arnd
^ permalink raw reply
* Re: [PATCH] Y2038: provide kernel support indication
From: Joseph Myers @ 2018-12-05 13:48 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Albert ARIBAUD, GNU C Library, Firoz Khan, Linux API,
Andy Lutomirski
In-Reply-To: <CAK8P3a0vZhfW_o3OhYBhwRmKCXA0jAAuODxmzHt+rwJkKO45ZA@mail.gmail.com>
On Wed, 5 Dec 2018, Arnd Bergmann wrote:
> The most logical way to do this in the kernel now is actually to
> have the newly assigned number point to the same syscall
> implementation on all architectures, both 32-bit and 64-bit.
If you have (redundant) new numbers on 64-bit, glibc should not use those
at all on 64-bit until the minimum kernel version is new enough to be sure
they are available, to avoid unnecessary runtime fallback code. Cf. how
on socketcall architectures it made sense to keep using just socketcall
for accept4 / recvmmsg / sendmmsg, rather than using the separate syscalls
with runtime fallback to socketcall (in the cases where syscalls were
added later than socketcall support), unless the configured minimum kernel
version is recent enough to ensure the syscall is available.
(That does not prevent glibc having local #undef / #define to be able to
use the new *names* unconditionally while still using the old numbers, if
that proves useful.)
> I think it's important that we only do this when we are called from
> an application with 64-bit time_t: When a user calls gettimeofday()
> with 64-bit time_t, that should try clock_gettime64(2) and fall back
> to clock_gettime(2) or gettimeofday(2) if that is unavailable. However
> an application using gettimeofday() with a 32-bit time_t should
> directly call gettimeofday(2) in the kernel but not try clock_gettime64()
> first. Without that distinction, the kernel cannot return -ENOSYS
> if we configure it to break compatibility with 32-bit time_t interfaces
> and the application might seem to work correctly despite being
> broken in 2038.
By design, all nontrivial 32-bit time interfaces in glibc for 32-bit
architectures should end up as simple wrappers round the implementations
using 64-bit time internally, to avoid duplication of complicated code
(previous versions of the Y2038 patches e.g. duplicated hundreds of lines
of pthread_mutex_timedlock implementation, which is clearly not a
maintainable approach). That means many 32-bit interfaces *will* end up
using 64-bit syscalls (with fallback to 32-bit if the 64-bit syscalls are
unavailable at runtime), even if some simple functions that really are
just one syscall for 32-bit still call the old syscall.
--
Joseph S. Myers
joseph@codesourcery.com
^ permalink raw reply
* Re: [PATCH] Y2038: provide kernel support indication
From: Arnd Bergmann @ 2018-12-05 13:33 UTC (permalink / raw)
To: Albert ARIBAUD
Cc: Joseph Myers, GNU C Library, Firoz Khan, Linux API,
Andy Lutomirski
In-Reply-To: <20181205124926.7d433994@athena>
On Wed, Dec 5, 2018 at 12:49 PM Albert ARIBAUD <albert.aribaud@3adev.fr> wrote:
> On Tue, 25 Sep 2018 22:14:38 +0200, Arnd Bergmann <arnd@arndb.de> wrote :
> > On Tue, Sep 25, 2018 at 9:36 PM Albert ARIBAUD <albert.aribaud@3adev.fr> wrote:
> > I was undecided on this issue actually: it does make some sense to
> > me to have the syscall macros be the same in the long run, so that
> > glibc doesn't have to pick between __NR_clock_gettime and
> > __NR_clock_gettime64 in a few years, after all supported kernels
> > support __NR_clock_gettime64. Also, 64-bit architectures won't
> > reuse the number space that we reserve for the new calls on 32-bit
> > architectures, so the addition is essentially free.
> >
> > I don't have a strong preference here, and can do whichever
> > you like better in glibc.
>
> There does not seem to have been any other comment on this for a while,
> so, do we go for this approach? That is:
>
> - on 64-bit architectures, the kernel will define _NR symbols identical
> to those added for Y2038, so that, for instance, on X86_64, there
> will be an _NR_clock_gettime64 symbol (which will point to the same
> syscall number as _NR_clock_gettime does).
There are a few new considerations for things that happened over the
last few months, so I'd still like to get more people involved before
we finally decide on this one:
- For cleaning up the kernel headers to make them more easily
usable in glibc, I think it makes a lot of sense to define the new
new macro names (as I said above). If we do that, maybe we should
do it for other system calls (not time related) as well, in particular
fcntl64, {f,}statfs64, {f,}truncate64, llseek, sendfile64, fstat{at,}64,
mmap2, and fadvise64 as well as the associated structures.
I already plan to do it independently for socketcall and ipc, which
should be replaced with the separate entry points whenever we
have the recent enough kernel.
- The work that Firoz Khan did for generating the asm/unistd.h
kernel headers and syscall tables on all architectures makes it
a little awkward to redirect new syscall macros to existing numbers,
as the table file format uses the number as the primary key.
The most logical way to do this in the kernel now is actually to
have the newly assigned number point to the same syscall
implementation on all architectures, both 32-bit and 64-bit.
Not providing the number on 64-bit at all is fairly easy, but the
redirect would require a permanent workaround on ppc, sparc,
parisc, s390, and riscv as well as any future 64-bit architectures.
- Any Lutomirksi has some ideas for cleaning up the x86 syscall
table, which may be relevant here. Adding him to Cc.
> - on 64-bit architectures, GLIBC will set __ASSUME_KERNEL_Y2038_SUPPORT
> once the minimal kernel supported version for these architectures
> provides the 'new' syscall symbols.
>
> - on all architectures, if __ASSUME_KERNEL_Y2038_SUPPORT is defined,
> then GLIBC assumes the 'new' syscall symbols exist and can be used.
We have a couple of system calls that we add even on 64-bit architectures,
including statx() and likely the new version of waitid()/getrusage().
I think for those the logic has to be different, so a 64-bit architecture
will have to e.g. fall back to calling fstatat() when statx() is unavailable
on an older kernel.
> - on all architectures, if __ASSUME_KERNEL_Y2038_SUPPORT is NOT defined,
> then GLIBC will try to use new syscalls for which a _NR symbol is
> provided by the build-time kernel, and on ENOSYS, will fallback to old
> syscalls.
I think it's important that we only do this when we are called from
an application with 64-bit time_t: When a user calls gettimeofday()
with 64-bit time_t, that should try clock_gettime64(2) and fall back
to clock_gettime(2) or gettimeofday(2) if that is unavailable. However
an application using gettimeofday() with a 32-bit time_t should
directly call gettimeofday(2) in the kernel but not try clock_gettime64()
first. Without that distinction, the kernel cannot return -ENOSYS
if we configure it to break compatibility with 32-bit time_t interfaces
and the application might seem to work correctly despite being
broken in 2038.
Arnd
^ permalink raw reply
* Re: pkeys: Reserve PKEY_DISABLE_READ
From: Florian Weimer @ 2018-12-05 13:00 UTC (permalink / raw)
To: Ram Pai; +Cc: Dave Hansen, linux-api, linuxppc-dev, linux-mm
In-Reply-To: <20181204062318.GC11930@ram.oc3035372033.ibm.com>
* Ram Pai:
> Ok. here is a patch, compiled but not tested. See if this meets the
> specifications.
>
> -----------------------------------------------------------------------------------
>
> commit 3dc06e73f3795921265d5d1d935e428deab01616
> Author: Ram Pai <linuxram@us.ibm.com>
> Date: Tue Dec 4 00:04:11 2018 -0500
>
> pkeys: add support of PKEY_DISABLE_READ
Thanks. In the x86 code, the translation of PKEY_DISABLE_READ |
PKEY_DISABLE_WRITE to PKEY_DISABLE_ACCESS appears to be missing. I
believe the existing code produces PKEY_DISABLE_WRITE, which is wrong.
Rest looks okay to me (again not tested).
Thanks,
Florian
^ permalink raw reply
* [PATCH v3] signal: add procfd_send_signal() syscall
From: Christian Brauner @ 2018-12-05 9:22 UTC (permalink / raw)
To: linux-kernel, linux-api, luto, arnd, ebiederm
Cc: serge, jannh, akpm, oleg, cyphar, viro, linux-fsdevel, dancol,
timmurray, linux-man, keescook, fweimer, tglx, x86,
Christian Brauner
The kill() syscall operates on process identifiers (pid). After a process
has exited its pid can be reused by another process. If a caller sends a
signal to a reused pid it will end up signaling the wrong process. This
issue has often surfaced and there has been a push [1] to address this
problem.
This patch uses file descriptors (fd) from proc/<pid> as stable handles on
struct pid. Even if a pid is recycled the handle will not change. The fd
can be used to send signals to the process it refers to.
Thus, the new syscall procfd_send_signal() is introduced to solve this
problem. Instead of pids it operates on process fds (procfd).
/* prototype and argument /*
long procfd_send_signal(int fd, int sig, siginfo_t *info, unsigned int flags);
In addition to the procfd and signal argument it takes an additional
siginfo_t and flags argument. If the siginfo_t argument is NULL then
procfd_send_signal() behaves like kill(). If it is not NULL
procfd_send_signal() behaves like rt_sigqueueinfo().
The flags argument is added to allow for future extensions of this syscall.
It currently needs to be passed as 0. Failing to do so will cause EINVAL.
/* procfd_send_signal() replaces multiple pid-based syscalls */
The procfd_send_signal() syscall currently takes on the job of the
following syscalls that operate on pids:
- kill(2)
- rt_sigqueueinfo(2)
The syscall is defined in such a way that it can also operate on thread fds
instead of process fds. In a future patchset I will extend it to operate on
procfds from /proc/<pid>/task/<tid> at which point it will additionally
take on the job of:
- tgkill(2)
- rt_tgsigqueueinfo(2)
Right now this is intentionally left out to keep this patchset as simple as
possible (cf. [4]). If a procfd of /proc/<pid>/task/<tid> is passed
EOPNOTSUPP will be returned to give userspace a way to detect when I add
support for such procfds {cf. [10]).
/* naming */
The name procfd_send_signal() was chosen to reflect the fact that it takes
on the job of multiple syscalls. It is intentional that the name is not
reminiscent of neither kill(2) nor rt_sigqueueinfo(2). Not the fomer
because it might imply that procfd_send_signal() is only a replacement for
kill(2) and not the latter because it is a hazzle to remember the correct
spelling (especially for non-native speakers) and because it is not
descriptive enough of what the syscall actually does. The name
"procfd_send_signal" makes it very clear that its job is to send signals.
/* O_PATH file descriptors */
procfds opened as O_PATH fds cannot be used to send signals to a process
(cf. [2]). Signaling processes through procfds is the equivalent of writing
to a file. Thus, this is not an operation that operates "purely at the
file descriptor level" as required by the open(2) manpage.
/* zombies */
Zombies can be signaled just as any other process. No special error will be
reported since a zombie state is an unreliable state (cf. [3]).
/* cross-namespace signals */
The patch currently enforces that the signaler and signalee either are in
the same pid namespace or that the signaler's pid namespace is an ancestor
of the signalee's pid namespace. This is done for the sake of simplicity
and because it is unclear to what values certain members of struct
siginfo_t would need to be set to (cf. [5], [6]).
/* compat syscalls */
It became clear that we would like to avoid adding compat syscalls (cf.
[7]). The compat syscall handling is now done in kernel/signal.c itself by
adding __copy_siginfo_from_user_generic() which lets us avoid compat
syscalls (cf. [8]).
With upcoming rework for syscall handling things might improve even further
(cf. [11]).
This patch was tested on x64 and x86.
/* userspace usage */
An asciinema recording for the basic functionality can be found under [9].
With this patch a process can be killed via:
#define _GNU_SOURCE
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>
static inline int do_procfd_send_signal(int procfd, int sig, siginfo_t *info,
unsigned int flags)
{
#ifdef __NR_procfd_send_signal
return syscall(__NR_procfd_send_signal, procfd, sig, info, flags);
#else
return -ENOSYS;
#endif
}
int main(int argc, char *argv[])
{
int fd, ret, saved_errno, sig;
if (argc < 3)
exit(EXIT_FAILURE);
fd = open(argv[1], O_DIRECTORY | O_CLOEXEC);
if (fd < 0) {
printf("%s - Failed to open \"%s\"\n", strerror(errno), argv[1]);
exit(EXIT_FAILURE);
}
sig = atoi(argv[2]);
printf("Sending signal %d to process %s\n", sig, argv[1]);
ret = do_procfd_send_signal(fd, sig, NULL, 0);
saved_errno = errno;
close(fd);
errno = saved_errno;
if (ret < 0) {
printf("%s - Failed to send signal %d to process %s\n",
strerror(errno), sig, argv[1]);
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
[1]: https://lkml.org/lkml/2018/11/18/130
[2]: https://lore.kernel.org/lkml/874lbtjvtd.fsf@oldenburg2.str.redhat.com/
[3]: https://lore.kernel.org/lkml/20181204132604.aspfupwjgjx6fhva@brauner.io/
[4]: https://lore.kernel.org/lkml/20181203180224.fkvw4kajtbvru2ku@brauner.io/
[5]: https://lore.kernel.org/lkml/20181121213946.GA10795@mail.hallyn.com/
[6]: https://lore.kernel.org/lkml/20181120103111.etlqp7zop34v6nv4@brauner.io/
[7]: https://lore.kernel.org/lkml/36323361-90BD-41AF-AB5B-EE0D7BA02C21@amacapital.net/
[8]: https://lore.kernel.org/lkml/87tvjxp8pc.fsf@xmission.com/
[9]: https://asciinema.org/a/X1J8eGhe3vCfBE2b9TXtTaSJ7
[10]: https://lore.kernel.org/lkml/20181203180224.fkvw4kajtbvru2ku@brauner.io/
[11]: https://lore.kernel.org/lkml/F53D6D38-3521-4C20-9034-5AF447DF62FF@amacapital.net/
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Serge Hallyn <serge@hallyn.com>
Cc: Jann Horn <jannh@google.com>
Cc: Andy Lutomirsky <luto@kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Aleksa Sarai <cyphar@cyphar.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Florian Weimer <fweimer@redhat.com>
Signed-off-by: Christian Brauner <christian@brauner.io>
---
Changelog:
v3:
- add __copy_siginfo_from_user_generic() to avoid adding compat syscalls
- s/procfd_signal/procfd_send_signal/g
- change type of flags argument from int to unsigned int
- add comment about what happens to zombies
- add proc_is_tid_procfd()
- return EOPNOTSUPP when /proc/<pid>/task/<tid> fd is passed so userspace
has a way of knowing that tidfds are not supported currently.
v2:
- define __NR_procfd_signal in unistd.h
- wire up compat syscall
- s/proc_is_procfd/proc_is_tgid_procfd/g
- provide stubs when CONFIG_PROC_FS=n
- move proc_pid() to linux/proc_fs.h header
- use proc_pid() to grab struct pid from /proc/<pid> fd
v1:
- patch introduced
---
arch/x86/entry/syscalls/syscall_32.tbl | 1 +
arch/x86/entry/syscalls/syscall_64.tbl | 1 +
fs/proc/base.c | 17 +++-
fs/proc/internal.h | 5 -
include/linux/proc_fs.h | 18 ++++
include/linux/syscalls.h | 3 +
include/uapi/asm-generic/unistd.h | 4 +-
kernel/signal.c | 127 +++++++++++++++++++++++--
8 files changed, 163 insertions(+), 13 deletions(-)
diff --git a/arch/x86/entry/syscalls/syscall_32.tbl b/arch/x86/entry/syscalls/syscall_32.tbl
index 3cf7b533b3d1..9ab0477d6dc3 100644
--- a/arch/x86/entry/syscalls/syscall_32.tbl
+++ b/arch/x86/entry/syscalls/syscall_32.tbl
@@ -398,3 +398,4 @@
384 i386 arch_prctl sys_arch_prctl __ia32_compat_sys_arch_prctl
385 i386 io_pgetevents sys_io_pgetevents __ia32_compat_sys_io_pgetevents
386 i386 rseq sys_rseq __ia32_sys_rseq
+387 i386 procfd_send_signal sys_procfd_send_signal __ia32_sys_procfd_send_signal
diff --git a/arch/x86/entry/syscalls/syscall_64.tbl b/arch/x86/entry/syscalls/syscall_64.tbl
index f0b1709a5ffb..6d22b1130ed0 100644
--- a/arch/x86/entry/syscalls/syscall_64.tbl
+++ b/arch/x86/entry/syscalls/syscall_64.tbl
@@ -343,6 +343,7 @@
332 common statx __x64_sys_statx
333 common io_pgetevents __x64_sys_io_pgetevents
334 common rseq __x64_sys_rseq
+335 common procfd_send_signal __x64_sys_procfd_send_signal
#
# x32-specific system call numbers start at 512 to avoid cache impact
diff --git a/fs/proc/base.c b/fs/proc/base.c
index ce3465479447..906647d51f6d 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -716,7 +716,10 @@ static int proc_pid_permission(struct inode *inode, int mask)
return generic_permission(inode, mask);
}
-
+struct pid *proc_pid(const struct inode *inode)
+{
+ return PROC_I(inode)->pid;
+}
static const struct inode_operations proc_def_inode_operations = {
.setattr = proc_setattr,
@@ -3038,6 +3041,12 @@ static const struct file_operations proc_tgid_base_operations = {
.llseek = generic_file_llseek,
};
+bool proc_is_tgid_procfd(const struct file *file)
+{
+ return d_is_dir(file->f_path.dentry) &&
+ (file->f_op == &proc_tgid_base_operations);
+}
+
static struct dentry *proc_tgid_base_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
{
return proc_pident_lookup(dir, dentry,
@@ -3422,6 +3431,12 @@ static const struct file_operations proc_tid_base_operations = {
.llseek = generic_file_llseek,
};
+bool proc_is_tid_procfd(const struct file *file)
+{
+ return d_is_dir(file->f_path.dentry) &&
+ (file->f_op == &proc_tid_base_operations);
+}
+
static const struct inode_operations proc_tid_base_inode_operations = {
.lookup = proc_tid_base_lookup,
.getattr = pid_getattr,
diff --git a/fs/proc/internal.h b/fs/proc/internal.h
index 5185d7f6a51e..eb69afba83f3 100644
--- a/fs/proc/internal.h
+++ b/fs/proc/internal.h
@@ -113,11 +113,6 @@ static inline void *__PDE_DATA(const struct inode *inode)
return PDE(inode)->data;
}
-static inline struct pid *proc_pid(const struct inode *inode)
-{
- return PROC_I(inode)->pid;
-}
-
static inline struct task_struct *get_proc_task(const struct inode *inode)
{
return get_pid_task(proc_pid(inode), PIDTYPE_PID);
diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h
index d0e1f1522a78..ebc0e0ca5256 100644
--- a/include/linux/proc_fs.h
+++ b/include/linux/proc_fs.h
@@ -73,6 +73,9 @@ struct proc_dir_entry *proc_create_net_single_write(const char *name, umode_t mo
int (*show)(struct seq_file *, void *),
proc_write_t write,
void *data);
+extern bool proc_is_tgid_procfd(const struct file *file);
+extern bool proc_is_tid_procfd(const struct file *file);
+extern struct pid *proc_pid(const struct inode *inode);
#else /* CONFIG_PROC_FS */
@@ -114,6 +117,21 @@ static inline int remove_proc_subtree(const char *name, struct proc_dir_entry *p
#define proc_create_net(name, mode, parent, state_size, ops) ({NULL;})
#define proc_create_net_single(name, mode, parent, show, data) ({NULL;})
+static inline bool proc_is_tgid_procfd(const struct file *file)
+{
+ return false;
+}
+
+static inline bool proc_is_tid_procfd(const struct file *file)
+{
+ return false;
+}
+
+static inline struct pid *proc_pid(const struct inode *inode)
+{
+ return NULL;
+}
+
#endif /* CONFIG_PROC_FS */
struct net;
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 2ac3d13a915b..b3a02c6780d0 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -907,6 +907,9 @@ asmlinkage long sys_statx(int dfd, const char __user *path, unsigned flags,
unsigned mask, struct statx __user *buffer);
asmlinkage long sys_rseq(struct rseq __user *rseq, uint32_t rseq_len,
int flags, uint32_t sig);
+asmlinkage long sys_procfd_send_signal(int procfd, int sig,
+ siginfo_t __user *info,
+ unsigned int flags);
/*
* Architecture-specific system calls
diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h
index 538546edbfbd..b409ee26f8e9 100644
--- a/include/uapi/asm-generic/unistd.h
+++ b/include/uapi/asm-generic/unistd.h
@@ -738,9 +738,11 @@ __SYSCALL(__NR_statx, sys_statx)
__SC_COMP(__NR_io_pgetevents, sys_io_pgetevents, compat_sys_io_pgetevents)
#define __NR_rseq 293
__SYSCALL(__NR_rseq, sys_rseq)
+#define __NR_procfd_send_signal 294
+__SYSCALL(__NR_procfd_send_signal, sys_procfd_send_signal)
#undef __NR_syscalls
-#define __NR_syscalls 294
+#define __NR_syscalls 295
/*
* 32 bit systems traditionally used different
diff --git a/kernel/signal.c b/kernel/signal.c
index 9a32bc2088c9..79a7e0396b0f 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -19,7 +19,9 @@
#include <linux/sched/task.h>
#include <linux/sched/task_stack.h>
#include <linux/sched/cputime.h>
+#include <linux/file.h>
#include <linux/fs.h>
+#include <linux/proc_fs.h>
#include <linux/tty.h>
#include <linux/binfmts.h>
#include <linux/coredump.h>
@@ -3286,6 +3288,16 @@ COMPAT_SYSCALL_DEFINE4(rt_sigtimedwait, compat_sigset_t __user *, uthese,
}
#endif
+static inline void prepare_kill_siginfo(int sig, struct kernel_siginfo *info)
+{
+ clear_siginfo(info);
+ info->si_signo = sig;
+ info->si_errno = 0;
+ info->si_code = SI_USER;
+ info->si_pid = task_tgid_vnr(current);
+ info->si_uid = from_kuid_munged(current_user_ns(), current_uid());
+}
+
/**
* sys_kill - send a signal to a process
* @pid: the PID of the process
@@ -3295,16 +3307,119 @@ SYSCALL_DEFINE2(kill, pid_t, pid, int, sig)
{
struct kernel_siginfo info;
- clear_siginfo(&info);
- info.si_signo = sig;
- info.si_errno = 0;
- info.si_code = SI_USER;
- info.si_pid = task_tgid_vnr(current);
- info.si_uid = from_kuid_munged(current_user_ns(), current_uid());
+ prepare_kill_siginfo(sig, &info);
return kill_something_info(sig, &info, pid);
}
+/*
+ * Verify that the signaler and signalee either are in the same pid namespace
+ * or that the signaler's pid namespace is an ancestor of the signalee's pid
+ * namespace.
+ */
+static bool may_signal_procfd(struct pid *pid)
+{
+ struct pid_namespace *active = task_active_pid_ns(current);
+ struct pid_namespace *p = ns_of_pid(pid);
+
+ for (;;) {
+ if (!p)
+ return false;
+ if (p == active)
+ break;
+ p = p->parent;
+ }
+
+ return true;
+}
+
+static int __copy_siginfo_from_user_generic(int signo, kernel_siginfo_t *kinfo,
+ siginfo_t *info)
+{
+#ifdef CONFIG_COMPAT
+ /*
+ * Avoid hooking up compat syscalls and instead handle necessary
+ * conversions here.
+ */
+ if (in_compat_syscall())
+ return __copy_siginfo_from_user32(
+ signo, kinfo, (struct compat_siginfo __user *)info);
+#endif
+ return __copy_siginfo_from_user(signo, kinfo, info);
+}
+
+/**
+ * sys_procfd_send_signal - send a signal to a process through a process file
+ * descriptor
+ * @procfd: the file descriptor of the process
+ * @sig: signal to be sent
+ * @info: the signal info
+ * @flags: future flags to be passed
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+SYSCALL_DEFINE4(procfd_send_signal, int, procfd, int, sig,
+ siginfo_t __user *, info, unsigned int, flags)
+{
+ int ret;
+ struct fd f;
+ struct pid *pid;
+ kernel_siginfo_t kinfo;
+
+ /* Enforce flags be set to 0 until we add an extension. */
+ if (flags)
+ return -EINVAL;
+
+ f = fdget_raw(procfd);
+ if (!f.file)
+ return -EBADF;
+
+ /*
+ * Give userspace a way to detect whether /proc/<pid>/task/<tid> fds
+ * are supported.
+ */
+ ret = -EOPNOTSUPP;
+ if (proc_is_tid_procfd(f.file))
+ goto err;
+
+ /* Is this a procfd? */
+ ret = -EINVAL;
+ if (!proc_is_tgid_procfd(f.file))
+ goto err;
+
+ /* Without CONFIG_PROC_FS proc_pid() returns NULL. */
+ pid = proc_pid(file_inode(f.file));
+ if (!pid)
+ goto err;
+
+ if (!may_signal_procfd(pid))
+ goto err;
+
+ if (info) {
+ ret = __copy_siginfo_from_user_generic(sig, &kinfo, info);
+ if (unlikely(ret))
+ goto err;
+
+ /*
+ * Not even root can pretend to send signals from the kernel.
+ * Nor can they impersonate a kill()/tgkill(), which adds
+ * source info.
+ */
+ ret = -EPERM;
+ if ((kinfo.si_code >= 0 || kinfo.si_code == SI_TKILL) &&
+ (task_pid(current) != pid))
+ goto err;
+ } else {
+ prepare_kill_siginfo(sig, &kinfo);
+ }
+
+ ret = kill_pid_info(sig, &kinfo, pid);
+
+err:
+ fdput(f);
+ return ret;
+}
+
static int
do_send_specific(pid_t tgid, pid_t pid, int sig, struct kernel_siginfo *info)
{
--
2.19.1
^ permalink raw reply related
* Re: [RFC PATCH glibc 1/4] glibc: Perform rseq(2) registration at nptl init and thread creation (v4)
From: Mathieu Desnoyers @ 2018-12-04 19:50 UTC (permalink / raw)
To: Florian Weimer
Cc: carlos, Joseph Myers, Szabolcs Nagy, libc-alpha, Thomas Gleixner,
Ben Maurer, Peter Zijlstra, Paul E. McKenney, Boqun Feng,
Will Deacon, Dave Watson, Paul Turner, Rich Felker, linux-kernel,
linux-api
In-Reply-To: <8736rd13i7.fsf@oldenburg2.str.redhat.com>
----- On Dec 4, 2018, at 2:44 PM, Florian Weimer fweimer@redhat.com wrote:
> * Mathieu Desnoyers:
>
>> diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist
>> b/sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist
>> index c370fda73d..9da78d59d2 100644
>> --- a/sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist
>> +++ b/sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist
>> @@ -235,3 +235,4 @@ GLIBC_2.28 tss_create F
>> GLIBC_2.28 tss_delete F
>> GLIBC_2.28 tss_get F
>> GLIBC_2.28 tss_set F
>> +GLIBC_2.29 __rseq_refcount T 0x4
>
> This part looks buggy.
>
> It's unclear based on this patch whether you actually want to get rid of
> the __rseq_refcount symbol.
I want to keep the __rseq_refcount symbol so out-of-libc users can
register rseq if they are linked against a pre-2.29 libc.
Why does it look buggy ?
Thanks,
Mathieu
--
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com
^ permalink raw reply
* Re: [RFC PATCH glibc 1/4] glibc: Perform rseq(2) registration at nptl init and thread creation (v4)
From: Florian Weimer @ 2018-12-04 19:44 UTC (permalink / raw)
To: Mathieu Desnoyers
Cc: Carlos O'Donell, Joseph Myers, Szabolcs Nagy, libc-alpha,
Thomas Gleixner, Ben Maurer, Peter Zijlstra, Paul E. McKenney,
Boqun Feng, Will Deacon, Dave Watson, Paul Turner, Rich Felker,
linux-kernel, linux-api
In-Reply-To: <20181204192141.4684-1-mathieu.desnoyers@efficios.com>
* Mathieu Desnoyers:
> diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist
> index c370fda73d..9da78d59d2 100644
> --- a/sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist
> @@ -235,3 +235,4 @@ GLIBC_2.28 tss_create F
> GLIBC_2.28 tss_delete F
> GLIBC_2.28 tss_get F
> GLIBC_2.28 tss_set F
> +GLIBC_2.29 __rseq_refcount T 0x4
This part looks buggy.
It's unclear based on this patch whether you actually want to get rid of
the __rseq_refcount symbol.
Thanks,
Florian
^ permalink raw reply
* [RFC PATCH glibc 2/4] glibc: sched_getcpu(): use rseq cpu_id TLS on Linux
From: Mathieu Desnoyers @ 2018-12-04 19:21 UTC (permalink / raw)
To: Carlos O'Donell
Cc: Florian Weimer, Joseph Myers, Szabolcs Nagy, libc-alpha,
Mathieu Desnoyers, Thomas Gleixner, Ben Maurer, Peter Zijlstra,
Paul E. McKenney, Boqun Feng, Will Deacon, Dave Watson,
Paul Turner, linux-kernel, linux-api
In-Reply-To: <20181204192141.4684-1-mathieu.desnoyers@efficios.com>
When available, use the cpu_id field from __rseq_abi on Linux to
implement sched_getcpu(). Fall-back on the vgetcpu vDSO if unavailable.
Benchmarks:
x86-64: Intel E5-2630 v3@2.40GHz, 16-core, hyperthreading
glibc sched_getcpu(): 13.7 ns (baseline)
glibc sched_getcpu() using rseq: 2.5 ns (speedup: 5.5x)
inline load cpuid from __rseq_abi TLS: 0.8 ns (speedup: 17.1x)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
CC: Carlos O'Donell <carlos@redhat.com>
CC: Florian Weimer <fweimer@redhat.com>
CC: Joseph Myers <joseph@codesourcery.com>
CC: Szabolcs Nagy <szabolcs.nagy@arm.com>
CC: Thomas Gleixner <tglx@linutronix.de>
CC: Ben Maurer <bmaurer@fb.com>
CC: Peter Zijlstra <peterz@infradead.org>
CC: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
CC: Boqun Feng <boqun.feng@gmail.com>
CC: Will Deacon <will.deacon@arm.com>
CC: Dave Watson <davejwatson@fb.com>
CC: Paul Turner <pjt@google.com>
CC: libc-alpha@sourceware.org
CC: linux-kernel@vger.kernel.org
CC: linux-api@vger.kernel.org
---
sysdeps/unix/sysv/linux/sched_getcpu.c | 25 +++++++++++++++++++++++--
1 file changed, 23 insertions(+), 2 deletions(-)
diff --git a/sysdeps/unix/sysv/linux/sched_getcpu.c b/sysdeps/unix/sysv/linux/sched_getcpu.c
index b69eeda15c..37fda59d36 100644
--- a/sysdeps/unix/sysv/linux/sched_getcpu.c
+++ b/sysdeps/unix/sysv/linux/sched_getcpu.c
@@ -24,8 +24,8 @@
#endif
#include <sysdep-vdso.h>
-int
-sched_getcpu (void)
+static int
+vsyscall_sched_getcpu (void)
{
#ifdef __NR_getcpu
unsigned int cpu;
@@ -37,3 +37,24 @@ sched_getcpu (void)
return -1;
#endif
}
+
+#ifdef __NR_rseq
+#include <linux/rseq.h>
+
+extern __attribute__ ((tls_model ("initial-exec")))
+__thread volatile struct rseq __rseq_abi;
+
+int
+sched_getcpu (void)
+{
+ int cpu_id = __rseq_abi.cpu_id;
+
+ return cpu_id >= 0 ? cpu_id : vsyscall_sched_getcpu ();
+}
+#else
+int
+sched_getcpu (void)
+{
+ return vsyscall_sched_getcpu ();
+}
+#endif
--
2.17.1
^ permalink raw reply related
* [RFC PATCH glibc 1/4] glibc: Perform rseq(2) registration at nptl init and thread creation (v4)
From: Mathieu Desnoyers @ 2018-12-04 19:21 UTC (permalink / raw)
To: Carlos O'Donell
Cc: Florian Weimer, Joseph Myers, Szabolcs Nagy, libc-alpha,
Mathieu Desnoyers, Thomas Gleixner, Ben Maurer, Peter Zijlstra,
Paul E. McKenney, Boqun Feng, Will Deacon, Dave Watson,
Paul Turner, Rich Felker, linux-kernel, linux-api
Register rseq(2) TLS for each thread (including main), and unregister
for each thread (excluding main). "rseq" stands for Restartable
Sequences.
See the rseq(2) man page proposed here:
https://lkml.org/lkml/2018/9/19/647
This patch is based on glibc commit a502c5294. The rseq(2) system call
was merged into Linux 4.18.
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
CC: Carlos O'Donell <carlos@redhat.com>
CC: Florian Weimer <fweimer@redhat.com>
CC: Joseph Myers <joseph@codesourcery.com>
CC: Szabolcs Nagy <szabolcs.nagy@arm.com>
CC: Thomas Gleixner <tglx@linutronix.de>
CC: Ben Maurer <bmaurer@fb.com>
CC: Peter Zijlstra <peterz@infradead.org>
CC: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
CC: Boqun Feng <boqun.feng@gmail.com>
CC: Will Deacon <will.deacon@arm.com>
CC: Dave Watson <davejwatson@fb.com>
CC: Paul Turner <pjt@google.com>
CC: Rich Felker <dalias@libc.org>
CC: libc-alpha@sourceware.org
CC: linux-kernel@vger.kernel.org
CC: linux-api@vger.kernel.org
---
Changes since v1:
- Move __rseq_refcount to an extra field at the end of __rseq_abi to
eliminate one symbol.
All libraries/programs which try to register rseq (glibc,
early-adopter applications, early-adopter libraries) should use the
rseq refcount. It becomes part of the ABI within a user-space
process, but it's not part of the ABI shared with the kernel per se.
- Restructure how this code is organized so glibc keeps building on
non-Linux targets.
- Use non-weak symbol for __rseq_abi.
- Move rseq registration/unregistration implementation into its own
nptl/rseq.c compile unit.
- Move __rseq_abi symbol under GLIBC_2.29.
Changes since v2:
- Move __rseq_refcount to its own symbol, which is less ugly than
trying to play tricks with the rseq uapi.
- Move __rseq_abi from nptl to csu (C start up), so it can be used
across glibc, including memory allocator and sched_getcpu(). The
__rseq_refcount symbol is kept in nptl, because there is no reason
to use it elsewhere in glibc.
Changes since v3:
- Set __rseq_refcount TLS to 1 on register/set to 0 on unregister
because glibc is the first/last user.
- Unconditionally register/unregister rseq at thread start/exit, because
glibc is the first/last user.
- Add missing abilist items.
- Rebase on glibc master commit a502c5294.
- Add NEWS entry.
---
NEWS | 6 ++
csu/Makefile | 2 +-
csu/Versions | 3 +
csu/rseq.c | 38 ++++++++++
nptl/Makefile | 2 +-
nptl/Versions | 4 ++
nptl/nptl-init.c | 3 +
nptl/pthreadP.h | 3 +
nptl/pthread_create.c | 8 +++
nptl/rseq.c | 42 +++++++++++
sysdeps/nptl/rseq-internal.h | 34 +++++++++
sysdeps/unix/sysv/linux/aarch64/libc.abilist | 1 +
.../sysv/linux/aarch64/libpthread.abilist | 1 +
sysdeps/unix/sysv/linux/alpha/libc.abilist | 1 +
.../unix/sysv/linux/alpha/libpthread.abilist | 1 +
sysdeps/unix/sysv/linux/arm/libc.abilist | 1 +
.../unix/sysv/linux/arm/libpthread.abilist | 1 +
sysdeps/unix/sysv/linux/hppa/libc.abilist | 1 +
.../unix/sysv/linux/hppa/libpthread.abilist | 1 +
sysdeps/unix/sysv/linux/i386/libc.abilist | 1 +
.../unix/sysv/linux/i386/libpthread.abilist | 1 +
sysdeps/unix/sysv/linux/ia64/libc.abilist | 1 +
.../unix/sysv/linux/ia64/libpthread.abilist | 1 +
.../sysv/linux/m68k/coldfire/libc.abilist | 1 +
.../linux/m68k/coldfire/libpthread.abilist | 1 +
.../unix/sysv/linux/m68k/m680x0/libc.abilist | 1 +
.../sysv/linux/m68k/m680x0/libpthread.abilist | 1 +
.../unix/sysv/linux/microblaze/libc.abilist | 1 +
.../sysv/linux/microblaze/libpthread.abilist | 1 +
.../sysv/linux/mips/mips32/fpu/libc.abilist | 1 +
.../sysv/linux/mips/mips32/libpthread.abilist | 1 +
.../sysv/linux/mips/mips32/nofpu/libc.abilist | 1 +
.../sysv/linux/mips/mips64/libpthread.abilist | 1 +
.../sysv/linux/mips/mips64/n32/libc.abilist | 1 +
.../sysv/linux/mips/mips64/n64/libc.abilist | 1 +
sysdeps/unix/sysv/linux/nios2/libc.abilist | 1 +
.../unix/sysv/linux/nios2/libpthread.abilist | 1 +
.../linux/powerpc/powerpc32/fpu/libc.abilist | 1 +
.../powerpc/powerpc32/libpthread.abilist | 1 +
.../powerpc/powerpc32/nofpu/libc.abilist | 1 +
.../linux/powerpc/powerpc64/libc-le.abilist | 1 +
.../sysv/linux/powerpc/powerpc64/libc.abilist | 1 +
.../powerpc/powerpc64/libpthread-le.abilist | 1 +
.../powerpc/powerpc64/libpthread.abilist | 1 +
.../unix/sysv/linux/riscv/rv64/libc.abilist | 1 +
.../sysv/linux/riscv/rv64/libpthread.abilist | 1 +
sysdeps/unix/sysv/linux/rseq-internal.h | 71 +++++++++++++++++++
.../unix/sysv/linux/s390/s390-32/libc.abilist | 1 +
.../linux/s390/s390-32/libpthread.abilist | 1 +
.../unix/sysv/linux/s390/s390-64/libc.abilist | 1 +
.../linux/s390/s390-64/libpthread.abilist | 1 +
sysdeps/unix/sysv/linux/sh/libc.abilist | 1 +
sysdeps/unix/sysv/linux/sh/libpthread.abilist | 1 +
.../sysv/linux/sparc/sparc32/libc.abilist | 1 +
.../linux/sparc/sparc32/libpthread.abilist | 1 +
.../sysv/linux/sparc/sparc64/libc.abilist | 1 +
.../linux/sparc/sparc64/libpthread.abilist | 1 +
.../unix/sysv/linux/x86_64/64/libc.abilist | 1 +
.../sysv/linux/x86_64/64/libpthread.abilist | 1 +
.../unix/sysv/linux/x86_64/x32/libc.abilist | 1 +
.../sysv/linux/x86_64/x32/libpthread.abilist | 1 +
61 files changed, 263 insertions(+), 2 deletions(-)
create mode 100644 csu/rseq.c
create mode 100644 nptl/rseq.c
create mode 100644 sysdeps/nptl/rseq-internal.h
create mode 100644 sysdeps/unix/sysv/linux/rseq-internal.h
diff --git a/NEWS b/NEWS
index f488821af1..b238eaa391 100644
--- a/NEWS
+++ b/NEWS
@@ -35,6 +35,12 @@ Major new features:
different directory. This is a GNU extension and similar to the
Solaris function of the same name.
+* Support for automatically registering threads with the Linux rseq(2)
+ system call has been added. This system call is implemented starting
+ from Linux 4.18. In order to be activated, it requires that glibc is built
+ against kernel headers that include this system call, and that glibc
+ detects availability of that system call at runtime.
+
Deprecated and removed features, and other changes affecting compatibility:
* The glibc.tune tunable namespace has been renamed to glibc.cpu and the
diff --git a/csu/Makefile b/csu/Makefile
index 88fc77662e..81d471587f 100644
--- a/csu/Makefile
+++ b/csu/Makefile
@@ -28,7 +28,7 @@ include ../Makeconfig
routines = init-first libc-start $(libc-init) sysdep version check_fds \
libc-tls elf-init dso_handle
-aux = errno
+aux = errno rseq
elide-routines.os = libc-tls
static-only-routines = elf-init
csu-dummies = $(filter-out $(start-installed-name),crt1.o Mcrt1.o)
diff --git a/csu/Versions b/csu/Versions
index 43010c3443..0f44ebf991 100644
--- a/csu/Versions
+++ b/csu/Versions
@@ -7,6 +7,9 @@ libc {
# New special glibc functions.
gnu_get_libc_release; gnu_get_libc_version;
}
+ GLIBC_2.29 {
+ __rseq_abi;
+ }
GLIBC_PRIVATE {
errno;
}
diff --git a/csu/rseq.c b/csu/rseq.c
new file mode 100644
index 0000000000..ccc88e4582
--- /dev/null
+++ b/csu/rseq.c
@@ -0,0 +1,38 @@
+/* Copyright (C) 2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Mathieu Desnoyers <mathieu.desnoyers@efficios.com>, 2018.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <stdint.h>
+
+enum libc_rseq_cpu_id_state {
+ LIBC_RSEQ_CPU_ID_UNINITIALIZED = -1,
+ LIBC_RSEQ_CPU_ID_REGISTRATION_FAILED = -2,
+};
+
+/* linux/rseq.h defines struct rseq as aligned on 32 bytes. The kernel ABI
+ size is 20 bytes. */
+struct libc_rseq {
+ uint32_t cpu_id_start;
+ uint32_t cpu_id;
+ uint64_t rseq_cs;
+ uint32_t flags;
+} __attribute__ ((aligned(4 * sizeof(uint64_t))));
+
+__attribute__ ((weak))
+__thread volatile struct libc_rseq __rseq_abi = {
+ .cpu_id = LIBC_RSEQ_CPU_ID_UNINITIALIZED,
+};
diff --git a/nptl/Makefile b/nptl/Makefile
index 49b6faa330..3a5dc80c65 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -145,7 +145,7 @@ libpthread-routines = nptl-init nptlfreeres vars events version pt-interp \
mtx_destroy mtx_init mtx_lock mtx_timedlock \
mtx_trylock mtx_unlock call_once cnd_broadcast \
cnd_destroy cnd_init cnd_signal cnd_timedwait cnd_wait \
- tss_create tss_delete tss_get tss_set
+ tss_create tss_delete tss_get tss_set rseq
# pthread_setuid pthread_seteuid pthread_setreuid \
# pthread_setresuid \
# pthread_setgid pthread_setegid pthread_setregid \
diff --git a/nptl/Versions b/nptl/Versions
index e7f691da7a..f7890f73fc 100644
--- a/nptl/Versions
+++ b/nptl/Versions
@@ -277,6 +277,10 @@ libpthread {
cnd_timedwait; cnd_wait; tss_create; tss_delete; tss_get; tss_set;
}
+ GLIBC_2.29 {
+ __rseq_refcount;
+ }
+
GLIBC_PRIVATE {
__pthread_initialize_minimal;
__pthread_clock_gettime; __pthread_clock_settime;
diff --git a/nptl/nptl-init.c b/nptl/nptl-init.c
index 907411d5bc..ab17bbb6e4 100644
--- a/nptl/nptl-init.c
+++ b/nptl/nptl-init.c
@@ -279,6 +279,9 @@ __pthread_initialize_minimal_internal (void)
THREAD_SETMEM (pd, cpuclock_offset, GL(dl_cpuclock_offset));
#endif
+ /* Register rseq ABI to the kernel. */
+ (void) __rseq_register_current_thread ();
+
/* Initialize the robust mutex data. */
{
#if __PTHREAD_MUTEX_HAVE_PREV
diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h
index 19efe1e35f..7fb996f12d 100644
--- a/nptl/pthreadP.h
+++ b/nptl/pthreadP.h
@@ -609,6 +609,9 @@ extern void __shm_directory_freeres (void) attribute_hidden;
extern void __wait_lookup_done (void) attribute_hidden;
+extern int __rseq_register_current_thread (void) attribute_hidden;
+extern int __rseq_unregister_current_thread (void) attribute_hidden;
+
#ifdef SHARED
# define PTHREAD_STATIC_FN_REQUIRE(name)
#else
diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c
index fe75d04113..a5233cdf2f 100644
--- a/nptl/pthread_create.c
+++ b/nptl/pthread_create.c
@@ -378,6 +378,7 @@ __free_tcb (struct pthread *pd)
START_THREAD_DEFN
{
struct pthread *pd = START_THREAD_SELF;
+ bool has_rseq = false;
#if HP_TIMING_AVAIL
/* Remember the time when the thread was started. */
@@ -396,6 +397,9 @@ START_THREAD_DEFN
if (__glibc_unlikely (atomic_exchange_acq (&pd->setxid_futex, 0) == -2))
futex_wake (&pd->setxid_futex, 1, FUTEX_PRIVATE);
+ /* Register rseq TLS to the kernel. */
+ has_rseq = !__rseq_register_current_thread ();
+
#ifdef __NR_set_robust_list
# ifndef __ASSUME_SET_ROBUST_LIST
if (__set_robust_list_avail >= 0)
@@ -573,6 +577,10 @@ START_THREAD_DEFN
}
#endif
+ /* Unregister rseq TLS from kernel. */
+ if (has_rseq && __rseq_unregister_current_thread ())
+ abort();
+
advise_stack_range (pd->stackblock, pd->stackblock_size, (uintptr_t) pd,
pd->guardsize);
diff --git a/nptl/rseq.c b/nptl/rseq.c
new file mode 100644
index 0000000000..76e33c8e18
--- /dev/null
+++ b/nptl/rseq.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Mathieu Desnoyers <mathieu.desnoyers@efficios.com>, 2018.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include "pthreadP.h"
+
+__attribute__((weak))
+__thread volatile uint32_t __rseq_refcount;
+
+#ifdef __NR_rseq
+#include <sysdeps/unix/sysv/linux/rseq-internal.h>
+#else
+#include <sysdeps/nptl/rseq-internal.h>
+#endif /* __NR_rseq. */
+
+int
+attribute_hidden
+__rseq_register_current_thread (void)
+{
+ return sysdep_rseq_register_current_thread ();
+}
+
+int
+attribute_hidden
+__rseq_unregister_current_thread (void)
+{
+ return sysdep_rseq_unregister_current_thread ();
+}
diff --git a/sysdeps/nptl/rseq-internal.h b/sysdeps/nptl/rseq-internal.h
new file mode 100644
index 0000000000..96422ebd57
--- /dev/null
+++ b/sysdeps/nptl/rseq-internal.h
@@ -0,0 +1,34 @@
+/* Copyright (C) 2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Mathieu Desnoyers <mathieu.desnoyers@efficios.com>, 2018.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef RSEQ_INTERNAL_H
+#define RSEQ_INTERNAL_H
+
+static inline int
+sysdep_rseq_register_current_thread (void)
+{
+ return -1;
+}
+
+static inline int
+sysdep_rseq_unregister_current_thread (void)
+{
+ return -1;
+}
+
+#endif /* rseq-internal.h */
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
index e66c741d04..36af4d0e94 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
@@ -2138,4 +2138,5 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 __rseq_abi T 0x20
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
diff --git a/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist b/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist
index 9a9e4cee85..d5b010eee1 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist
@@ -243,3 +243,4 @@ GLIBC_2.28 tss_create F
GLIBC_2.28 tss_delete F
GLIBC_2.28 tss_get F
GLIBC_2.28 tss_set F
+GLIBC_2.29 __rseq_refcount T 0x4
diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
index 8df162fe99..cdf1d53e35 100644
--- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
@@ -2033,6 +2033,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 __rseq_abi T 0x20
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/alpha/libpthread.abilist b/sysdeps/unix/sysv/linux/alpha/libpthread.abilist
index b413007ccb..d477af8d10 100644
--- a/sysdeps/unix/sysv/linux/alpha/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libpthread.abilist
@@ -227,6 +227,7 @@ GLIBC_2.28 tss_create F
GLIBC_2.28 tss_delete F
GLIBC_2.28 tss_get F
GLIBC_2.28 tss_set F
+GLIBC_2.29 __rseq_refcount T 0x4
GLIBC_2.3.2 pthread_cond_broadcast F
GLIBC_2.3.2 pthread_cond_destroy F
GLIBC_2.3.2 pthread_cond_init F
diff --git a/sysdeps/unix/sysv/linux/arm/libc.abilist b/sysdeps/unix/sysv/linux/arm/libc.abilist
index 43c804f9dc..f11ff5c5cf 100644
--- a/sysdeps/unix/sysv/linux/arm/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/libc.abilist
@@ -123,6 +123,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 __rseq_abi T 0x20
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.4 _Exit F
GLIBC_2.4 _IO_2_1_stderr_ D 0xa0
diff --git a/sysdeps/unix/sysv/linux/arm/libpthread.abilist b/sysdeps/unix/sysv/linux/arm/libpthread.abilist
index af82a4c632..b49c38114a 100644
--- a/sysdeps/unix/sysv/linux/arm/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/arm/libpthread.abilist
@@ -27,6 +27,7 @@ GLIBC_2.28 tss_create F
GLIBC_2.28 tss_delete F
GLIBC_2.28 tss_get F
GLIBC_2.28 tss_set F
+GLIBC_2.29 __rseq_refcount T 0x4
GLIBC_2.4 _IO_flockfile F
GLIBC_2.4 _IO_ftrylockfile F
GLIBC_2.4 _IO_funlockfile F
diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
index 88b01c2e75..deb2dd860b 100644
--- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
@@ -1880,6 +1880,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 __rseq_abi T 0x20
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/hppa/libpthread.abilist b/sysdeps/unix/sysv/linux/hppa/libpthread.abilist
index bcba07f575..3a307653f4 100644
--- a/sysdeps/unix/sysv/linux/hppa/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libpthread.abilist
@@ -219,6 +219,7 @@ GLIBC_2.28 tss_create F
GLIBC_2.28 tss_delete F
GLIBC_2.28 tss_get F
GLIBC_2.28 tss_set F
+GLIBC_2.29 __rseq_refcount T 0x4
GLIBC_2.3.2 pthread_cond_broadcast F
GLIBC_2.3.2 pthread_cond_destroy F
GLIBC_2.3.2 pthread_cond_init F
diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
index 6d02f31612..156235898a 100644
--- a/sysdeps/unix/sysv/linux/i386/libc.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
@@ -2045,6 +2045,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 __rseq_abi T 0x20
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/i386/libpthread.abilist b/sysdeps/unix/sysv/linux/i386/libpthread.abilist
index bece86d246..e95ce92103 100644
--- a/sysdeps/unix/sysv/linux/i386/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libpthread.abilist
@@ -227,6 +227,7 @@ GLIBC_2.28 tss_create F
GLIBC_2.28 tss_delete F
GLIBC_2.28 tss_get F
GLIBC_2.28 tss_set F
+GLIBC_2.29 __rseq_refcount T 0x4
GLIBC_2.3.2 pthread_cond_broadcast F
GLIBC_2.3.2 pthread_cond_destroy F
GLIBC_2.3.2 pthread_cond_init F
diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
index 4249712611..39f291f97d 100644
--- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
@@ -1914,6 +1914,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 __rseq_abi T 0x20
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/ia64/libpthread.abilist b/sysdeps/unix/sysv/linux/ia64/libpthread.abilist
index ccc9449826..6e23c0e62d 100644
--- a/sysdeps/unix/sysv/linux/ia64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libpthread.abilist
@@ -219,6 +219,7 @@ GLIBC_2.28 tss_create F
GLIBC_2.28 tss_delete F
GLIBC_2.28 tss_get F
GLIBC_2.28 tss_set F
+GLIBC_2.29 __rseq_refcount T 0x4
GLIBC_2.3.2 pthread_cond_broadcast F
GLIBC_2.3.2 pthread_cond_destroy F
GLIBC_2.3.2 pthread_cond_init F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
index d47b808862..a18501e570 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
@@ -124,6 +124,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 __rseq_abi T 0x20
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.4 _Exit F
GLIBC_2.4 _IO_2_1_stderr_ D 0x98
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist
index af82a4c632..b49c38114a 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist
@@ -27,6 +27,7 @@ GLIBC_2.28 tss_create F
GLIBC_2.28 tss_delete F
GLIBC_2.28 tss_get F
GLIBC_2.28 tss_set F
+GLIBC_2.29 __rseq_refcount T 0x4
GLIBC_2.4 _IO_flockfile F
GLIBC_2.4 _IO_ftrylockfile F
GLIBC_2.4 _IO_funlockfile F
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
index d5e38308be..cf0f41ec70 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
@@ -1989,6 +1989,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 __rseq_abi T 0x20
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist
index bece86d246..e95ce92103 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist
@@ -227,6 +227,7 @@ GLIBC_2.28 tss_create F
GLIBC_2.28 tss_delete F
GLIBC_2.28 tss_get F
GLIBC_2.28 tss_set F
+GLIBC_2.29 __rseq_refcount T 0x4
GLIBC_2.3.2 pthread_cond_broadcast F
GLIBC_2.3.2 pthread_cond_destroy F
GLIBC_2.3.2 pthread_cond_init F
diff --git a/sysdeps/unix/sysv/linux/microblaze/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/libc.abilist
index 8596b84399..1405f27555 100644
--- a/sysdeps/unix/sysv/linux/microblaze/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/libc.abilist
@@ -2130,4 +2130,5 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 __rseq_abi T 0x20
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
diff --git a/sysdeps/unix/sysv/linux/microblaze/libpthread.abilist b/sysdeps/unix/sysv/linux/microblaze/libpthread.abilist
index 5067375d23..2a94d9e588 100644
--- a/sysdeps/unix/sysv/linux/microblaze/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/libpthread.abilist
@@ -243,3 +243,4 @@ GLIBC_2.28 tss_create F
GLIBC_2.28 tss_delete F
GLIBC_2.28 tss_get F
GLIBC_2.28 tss_set F
+GLIBC_2.29 __rseq_refcount T 0x4
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
index 88e0f896d5..7b0144392f 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
@@ -1967,6 +1967,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 __rseq_abi T 0x20
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist b/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist
index 02144967c6..e507b677ee 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist
@@ -227,6 +227,7 @@ GLIBC_2.28 tss_create F
GLIBC_2.28 tss_delete F
GLIBC_2.28 tss_get F
GLIBC_2.28 tss_set F
+GLIBC_2.29 __rseq_refcount T 0x4
GLIBC_2.3.2 pthread_cond_broadcast F
GLIBC_2.3.2 pthread_cond_destroy F
GLIBC_2.3.2 pthread_cond_init F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
index aff7462c34..430426e03e 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
@@ -1965,6 +1965,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 __rseq_abi T 0x20
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist b/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
index 02144967c6..e507b677ee 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
@@ -227,6 +227,7 @@ GLIBC_2.28 tss_create F
GLIBC_2.28 tss_delete F
GLIBC_2.28 tss_get F
GLIBC_2.28 tss_set F
+GLIBC_2.29 __rseq_refcount T 0x4
GLIBC_2.3.2 pthread_cond_broadcast F
GLIBC_2.3.2 pthread_cond_destroy F
GLIBC_2.3.2 pthread_cond_init F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
index 71d82444aa..60915c4d81 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
@@ -1973,6 +1973,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 __rseq_abi T 0x20
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
index de6c53d293..958488bf19 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
@@ -1968,6 +1968,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 __rseq_abi T 0x20
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
index e724bab9fb..9f4be44396 100644
--- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
@@ -2171,4 +2171,5 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 __rseq_abi T 0x20
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
diff --git a/sysdeps/unix/sysv/linux/nios2/libpthread.abilist b/sysdeps/unix/sysv/linux/nios2/libpthread.abilist
index 78cac2ae27..79fbbec7bb 100644
--- a/sysdeps/unix/sysv/linux/nios2/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libpthread.abilist
@@ -241,3 +241,4 @@ GLIBC_2.28 tss_create F
GLIBC_2.28 tss_delete F
GLIBC_2.28 tss_get F
GLIBC_2.28 tss_set F
+GLIBC_2.29 __rseq_refcount T 0x4
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
index e9ecbccb71..758a88cb40 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
@@ -1993,6 +1993,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 __rseq_abi T 0x20
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
index 09e8447b06..2def055dec 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
@@ -227,6 +227,7 @@ GLIBC_2.28 tss_create F
GLIBC_2.28 tss_delete F
GLIBC_2.28 tss_get F
GLIBC_2.28 tss_set F
+GLIBC_2.29 __rseq_refcount T 0x4
GLIBC_2.3.2 pthread_cond_broadcast F
GLIBC_2.3.2 pthread_cond_destroy F
GLIBC_2.3.2 pthread_cond_init F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
index da83ea6028..ab8d68446a 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
@@ -1997,6 +1997,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 __rseq_abi T 0x20
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
index 4535b40d15..d9dc159d85 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
@@ -2228,4 +2228,5 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 __rseq_abi T 0x20
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
index 65725de4f0..cc47390688 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
@@ -123,6 +123,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 __rseq_abi T 0x20
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 _Exit F
GLIBC_2.3 _IO_2_1_stderr_ D 0xe0
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libpthread-le.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libpthread-le.abilist
index 9a9e4cee85..d5b010eee1 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libpthread-le.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libpthread-le.abilist
@@ -243,3 +243,4 @@ GLIBC_2.28 tss_create F
GLIBC_2.28 tss_delete F
GLIBC_2.28 tss_get F
GLIBC_2.28 tss_set F
+GLIBC_2.29 __rseq_refcount T 0x4
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libpthread.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libpthread.abilist
index 8300958d47..26a5ced7a2 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libpthread.abilist
@@ -27,6 +27,7 @@ GLIBC_2.28 tss_create F
GLIBC_2.28 tss_delete F
GLIBC_2.28 tss_get F
GLIBC_2.28 tss_set F
+GLIBC_2.29 __rseq_refcount T 0x4
GLIBC_2.3 _IO_flockfile F
GLIBC_2.3 _IO_ftrylockfile F
GLIBC_2.3 _IO_funlockfile F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
index bbb3c4a8e7..a59d67aca2 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
@@ -2100,4 +2100,5 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 __rseq_abi T 0x20
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist
index c370fda73d..9da78d59d2 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist
@@ -235,3 +235,4 @@ GLIBC_2.28 tss_create F
GLIBC_2.28 tss_delete F
GLIBC_2.28 tss_get F
GLIBC_2.28 tss_set F
+GLIBC_2.29 __rseq_refcount T 0x4
diff --git a/sysdeps/unix/sysv/linux/rseq-internal.h b/sysdeps/unix/sysv/linux/rseq-internal.h
new file mode 100644
index 0000000000..2367926def
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/rseq-internal.h
@@ -0,0 +1,71 @@
+/* Copyright (C) 2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Mathieu Desnoyers <mathieu.desnoyers@efficios.com>, 2018.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef RSEQ_INTERNAL_H
+#define RSEQ_INTERNAL_H
+
+#include <stdint.h>
+#include <linux/rseq.h>
+
+#define RSEQ_SIG 0x53053053
+
+extern __thread volatile struct rseq __rseq_abi
+__attribute__ ((tls_model ("initial-exec")));
+
+extern __thread volatile uint32_t __rseq_refcount
+__attribute__ ((tls_model ("initial-exec")));
+
+static inline int
+sysdep_rseq_register_current_thread (void)
+{
+ int rc, ret = 0;
+ INTERNAL_SYSCALL_DECL (err);
+
+ if (__rseq_abi.cpu_id == RSEQ_CPU_ID_REGISTRATION_FAILED)
+ return -1;
+ rc = INTERNAL_SYSCALL_CALL (rseq, err, &__rseq_abi, sizeof (struct rseq),
+ 0, RSEQ_SIG);
+ if (!rc)
+ {
+ __rseq_refcount = 1;
+ goto end;
+ }
+ if (INTERNAL_SYSCALL_ERRNO (rc, err) != EBUSY)
+ __rseq_abi.cpu_id = RSEQ_CPU_ID_REGISTRATION_FAILED;
+ ret = -1;
+end:
+ return ret;
+}
+
+static inline int
+sysdep_rseq_unregister_current_thread (void)
+{
+ int rc, ret = 0;
+ INTERNAL_SYSCALL_DECL (err);
+
+ __rseq_refcount = 0;
+ rc = INTERNAL_SYSCALL_CALL (rseq, err, &__rseq_abi, sizeof (struct rseq),
+ RSEQ_FLAG_UNREGISTER, RSEQ_SIG);
+ if (!rc)
+ goto end;
+ ret = -1;
+end:
+ return ret;
+}
+
+#endif /* rseq-internal.h */
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
index e85ac2a178..fca7f6de8d 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
@@ -2002,6 +2002,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 __rseq_abi T 0x20
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist
index d05468f3b2..8876434f46 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist
@@ -229,6 +229,7 @@ GLIBC_2.28 tss_create F
GLIBC_2.28 tss_delete F
GLIBC_2.28 tss_get F
GLIBC_2.28 tss_set F
+GLIBC_2.29 __rseq_refcount T 0x4
GLIBC_2.3.2 pthread_cond_broadcast F
GLIBC_2.3.2 pthread_cond_destroy F
GLIBC_2.3.2 pthread_cond_init F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
index d56931022c..74eebccbd0 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
@@ -1908,6 +1908,7 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 __fentry__ F
+GLIBC_2.29 __rseq_abi T 0x20
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
index e8161aa747..2ae3980aba 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
@@ -221,6 +221,7 @@ GLIBC_2.28 tss_create F
GLIBC_2.28 tss_delete F
GLIBC_2.28 tss_get F
GLIBC_2.28 tss_set F
+GLIBC_2.29 __rseq_refcount T 0x4
GLIBC_2.3.2 pthread_cond_broadcast F
GLIBC_2.3.2 pthread_cond_destroy F
GLIBC_2.3.2 pthread_cond_init F
diff --git a/sysdeps/unix/sysv/linux/sh/libc.abilist b/sysdeps/unix/sysv/linux/sh/libc.abilist
index ff939a15c4..e614aa9f0c 100644
--- a/sysdeps/unix/sysv/linux/sh/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/libc.abilist
@@ -1884,6 +1884,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 __rseq_abi T 0x20
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/sh/libpthread.abilist b/sysdeps/unix/sysv/linux/sh/libpthread.abilist
index bcba07f575..3a307653f4 100644
--- a/sysdeps/unix/sysv/linux/sh/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/sh/libpthread.abilist
@@ -219,6 +219,7 @@ GLIBC_2.28 tss_create F
GLIBC_2.28 tss_delete F
GLIBC_2.28 tss_get F
GLIBC_2.28 tss_set F
+GLIBC_2.29 __rseq_refcount T 0x4
GLIBC_2.3.2 pthread_cond_broadcast F
GLIBC_2.3.2 pthread_cond_destroy F
GLIBC_2.3.2 pthread_cond_init F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
index 64fa9e10a5..03b0c2dc32 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
@@ -1996,6 +1996,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 __rseq_abi T 0x20
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist
index b413007ccb..d477af8d10 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist
@@ -227,6 +227,7 @@ GLIBC_2.28 tss_create F
GLIBC_2.28 tss_delete F
GLIBC_2.28 tss_get F
GLIBC_2.28 tss_set F
+GLIBC_2.29 __rseq_refcount T 0x4
GLIBC_2.3.2 pthread_cond_broadcast F
GLIBC_2.3.2 pthread_cond_destroy F
GLIBC_2.3.2 pthread_cond_init F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
index db909d1506..800ea4d98b 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
@@ -1937,6 +1937,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 __rseq_abi T 0x20
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
index ccc9449826..6e23c0e62d 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
@@ -219,6 +219,7 @@ GLIBC_2.28 tss_create F
GLIBC_2.28 tss_delete F
GLIBC_2.28 tss_get F
GLIBC_2.28 tss_set F
+GLIBC_2.29 __rseq_refcount T 0x4
GLIBC_2.3.2 pthread_cond_broadcast F
GLIBC_2.3.2 pthread_cond_destroy F
GLIBC_2.3.2 pthread_cond_init F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
index 3b175f104b..b694817e55 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
@@ -1895,6 +1895,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 __rseq_abi T 0x20
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
index 931c8277a8..889b71fb92 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
@@ -219,6 +219,7 @@ GLIBC_2.28 tss_create F
GLIBC_2.28 tss_delete F
GLIBC_2.28 tss_get F
GLIBC_2.28 tss_set F
+GLIBC_2.29 __rseq_refcount T 0x4
GLIBC_2.3.2 pthread_cond_broadcast F
GLIBC_2.3.2 pthread_cond_destroy F
GLIBC_2.3.2 pthread_cond_init F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
index 1b57710477..e885d3c6eb 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
@@ -2146,4 +2146,5 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 __rseq_abi T 0x20
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist
index c09c9b015a..68886246a2 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist
@@ -243,3 +243,4 @@ GLIBC_2.28 tss_create F
GLIBC_2.28 tss_delete F
GLIBC_2.28 tss_get F
GLIBC_2.28 tss_set F
+GLIBC_2.29 __rseq_refcount T 0x4
--
2.17.1
^ permalink raw reply related
* Re: [RFC PATCH v6 04/26] x86/fpu/xstate: Introduce XSAVES system states
From: Borislav Petkov @ 2018-12-04 18:16 UTC (permalink / raw)
To: Yu-cheng Yu
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,
Eugene Syromiatnikov, Florian Weimer, H.J. Lu, Jann Horn,
Jonathan Corbet, Kees Cook, Mike Kravetz, Nadav Amit,
Oleg Nesterov, Pa
In-Reply-To: <752c38422a6536d8df99b619214f935e4bc882ad.camel@intel.com>
On Tue, Dec 04, 2018 at 09:08:11AM -0800, Yu-cheng Yu wrote:
> Then we will do this very often. Why don't we create all three in the
> beginning: xfeatures_mask_all, xfeatures_mask_user, and xfeatures_mask_system?
Because the _all thing is the OR-ed product of the two and then you
don't have to update it when the _user and the _system ones change
because you'll be creating it on the fly each time.
--
Regards/Gruss,
Boris.
Good mailing practices for 400: avoid top-posting and trim the reply.
^ permalink raw reply
* Re: [RFC PATCH v6 04/26] x86/fpu/xstate: Introduce XSAVES system states
From: Yu-cheng Yu @ 2018-12-04 17:08 UTC (permalink / raw)
To: Borislav Petkov
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,
Eugene Syromiatnikov, Florian Weimer, H.J. Lu, Jann Horn,
Jonathan Corbet, Kees Cook, Mike Kravetz, Nadav Amit,
Oleg Nesterov, Pa
In-Reply-To: <20181204160144.GG11803@zn.tnic>
On Tue, 2018-12-04 at 17:01 +0100, Borislav Petkov wrote:
> On Mon, Nov 19, 2018 at 01:47:47PM -0800, Yu-cheng Yu wrote:
> > Control-flow Enforcement (CET) MSR contents are XSAVES system states.
> > To support CET, introduce XSAVES system states first.
> >
> > Signed-off-by: Yu-cheng Yu <yu-cheng.yu@intel.com>
> > ---
> > arch/x86/include/asm/fpu/internal.h | 3 +-
> > arch/x86/include/asm/fpu/xstate.h | 4 +-
> > arch/x86/kernel/fpu/core.c | 6 +-
> > arch/x86/kernel/fpu/init.c | 10 ---
> > arch/x86/kernel/fpu/xstate.c | 94 +++++++++++++++++++----------
> > 5 files changed, 69 insertions(+), 48 deletions(-)
>
> ...
>
> > @@ -704,6 +710,7 @@ static int init_xstate_size(void)
> > */
> > static void fpu__init_disable_system_xstate(void)
> > {
> > + xfeatures_mask_all = 0;
> > xfeatures_mask_user = 0;
> > cr4_clear_bits(X86_CR4_OSXSAVE);
> > fpu__xstate_clear_all_cpu_caps();
> > @@ -717,6 +724,8 @@ void __init fpu__init_system_xstate(void)
> > {
> > unsigned int eax, ebx, ecx, edx;
> > static int on_boot_cpu __initdata = 1;
> > + u64 cpu_system_xfeatures_mask;
> > + u64 cpu_user_xfeatures_mask;
>
> So what I had in mind is to not have those local vars but use
> xfeatures_mask_user and xfeatures_mask_system here directly...
Ok, I will re-write it.
...
> >
> > @@ -739,10 +748,23 @@ void __init fpu__init_system_xstate(void)
> > return;
> > }
> >
> > + /*
> > + * Find user states supported by the processor.
> > + * Only these bits can be set in XCR0.
> > + */
> > cpuid_count(XSTATE_CPUID, 0, &eax, &ebx, &ecx, &edx);
> > - xfeatures_mask_user = eax + ((u64)edx << 32);
> > + cpu_user_xfeatures_mask = eax + ((u64)edx << 32);
> >
> > - if ((xfeatures_mask_user & XFEATURE_MASK_FPSSE) !=
> > XFEATURE_MASK_FPSSE) {
> > + /*
> > + * Find system states supported by the processor.
> > + * Only these bits can be set in IA32_XSS MSR.
> > + */
> > + cpuid_count(XSTATE_CPUID, 1, &eax, &ebx, &ecx, &edx);
> > + cpu_system_xfeatures_mask = ecx + ((u64)edx << 32);
> > +
> > + xfeatures_mask_all = cpu_user_xfeatures_mask |
> > cpu_system_xfeatures_mask;
>
> ... and not introduce xfeatures_mask_all at all but everywhere you need
> all features, to do:
>
> (xfeatures_mask_user | xfeatures_mask_system)
>
> and work with that.
Then we will do this very often. Why don't we create all three in the
beginning: xfeatures_mask_all, xfeatures_mask_user, and xfeatures_mask_system?
> ...
>
> > @@ -1178,7 +1208,7 @@ int copy_kernel_to_xstate(struct xregs_state *xsave,
> > const void *kbuf)
> > * The state that came in from userspace was user-state only.
> > * Mask all the user states out of 'xfeatures':
> > */
> > - xsave->header.xfeatures &= XFEATURE_MASK_SUPERVISOR;
> > + xsave->header.xfeatures &= (xfeatures_mask_all &
> > ~xfeatures_mask_user);
>
> ... and this would be
>
> xsave->header.xfeatures &= xfeatures_mask_system;
Yes.
>
> >
> > /*
> > * Add back in the features that came in from userspace:
> > @@ -1234,7 +1264,7 @@ int copy_user_to_xstate(struct xregs_state *xsave,
> > const void __user *ubuf)
> > * The state that came in from userspace was user-state only.
> > * Mask all the user states out of 'xfeatures':
> > */
> > - xsave->header.xfeatures &= XFEATURE_MASK_SUPERVISOR;
> > + xsave->header.xfeatures &= (xfeatures_mask_all &
> > ~xfeatures_mask_user);
>
> Ditto here.
>
> This way you have *two* mask variables and code queries them only.
>
> Hmmm?
>
> Or am I missing something?
We actually have three.
Yu-cheng
^ permalink raw reply
* Re: [PATCH v5 0/4] Fix unsafe BPF_PROG_TEST_RUN interface
From: Alexei Starovoitov @ 2018-12-04 16:22 UTC (permalink / raw)
To: Lorenz Bauer; +Cc: ast, daniel, netdev, linux-api
In-Reply-To: <20181203113126.2591-1-lmb@cloudflare.com>
On Mon, Dec 03, 2018 at 11:31:22AM +0000, Lorenz Bauer wrote:
> Right now, there is no safe way to use BPF_PROG_TEST_RUN with data_out.
> This is because bpf_test_finish copies the output buffer to user space
> without checking its size. This can lead to the kernel overwriting
> data in user space after the buffer if xdp_adjust_head and friends are
> in play.
>
> Thanks to everyone for their advice and patience with this patch set!
>
> Changes in v5:
> * Fix up libbpf.map
>
> Changes in v4:
> * Document bpf_prog_test_run and bpf_prog_test_run_xattr
> * Use struct bpf_prog_test_run_attr for return values
>
> Changes in v3:
> * Introduce bpf_prog_test_run_xattr instead of modifying the existing
> function
>
> Changes in v2:
> * Make the syscall return ENOSPC if data_size_out is too small
> * Make bpf_prog_test_run return EINVAL if size_out is missing
> * Document the new behaviour of data_size_out
Applied, Thanks
^ permalink raw reply
* Re: [RFC PATCH v6 04/26] x86/fpu/xstate: Introduce XSAVES system states
From: Borislav Petkov @ 2018-12-04 16:01 UTC (permalink / raw)
To: Yu-cheng Yu
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,
Eugene Syromiatnikov, Florian Weimer, H.J. Lu, Jann Horn,
Jonathan Corbet, Kees Cook, Mike Kravetz, Nadav Amit,
Oleg Nesterov, Pa
In-Reply-To: <20181119214809.6086-5-yu-cheng.yu@intel.com>
On Mon, Nov 19, 2018 at 01:47:47PM -0800, Yu-cheng Yu wrote:
> Control-flow Enforcement (CET) MSR contents are XSAVES system states.
> To support CET, introduce XSAVES system states first.
>
> Signed-off-by: Yu-cheng Yu <yu-cheng.yu@intel.com>
> ---
> arch/x86/include/asm/fpu/internal.h | 3 +-
> arch/x86/include/asm/fpu/xstate.h | 4 +-
> arch/x86/kernel/fpu/core.c | 6 +-
> arch/x86/kernel/fpu/init.c | 10 ---
> arch/x86/kernel/fpu/xstate.c | 94 +++++++++++++++++++----------
> 5 files changed, 69 insertions(+), 48 deletions(-)
...
> @@ -704,6 +710,7 @@ static int init_xstate_size(void)
> */
> static void fpu__init_disable_system_xstate(void)
> {
> + xfeatures_mask_all = 0;
> xfeatures_mask_user = 0;
> cr4_clear_bits(X86_CR4_OSXSAVE);
> fpu__xstate_clear_all_cpu_caps();
> @@ -717,6 +724,8 @@ void __init fpu__init_system_xstate(void)
> {
> unsigned int eax, ebx, ecx, edx;
> static int on_boot_cpu __initdata = 1;
> + u64 cpu_system_xfeatures_mask;
> + u64 cpu_user_xfeatures_mask;
So what I had in mind is to not have those local vars but use
xfeatures_mask_user and xfeatures_mask_system here directly...
> int err;
> int i;
>
> @@ -739,10 +748,23 @@ void __init fpu__init_system_xstate(void)
> return;
> }
>
> + /*
> + * Find user states supported by the processor.
> + * Only these bits can be set in XCR0.
> + */
> cpuid_count(XSTATE_CPUID, 0, &eax, &ebx, &ecx, &edx);
> - xfeatures_mask_user = eax + ((u64)edx << 32);
> + cpu_user_xfeatures_mask = eax + ((u64)edx << 32);
>
> - if ((xfeatures_mask_user & XFEATURE_MASK_FPSSE) != XFEATURE_MASK_FPSSE) {
> + /*
> + * Find system states supported by the processor.
> + * Only these bits can be set in IA32_XSS MSR.
> + */
> + cpuid_count(XSTATE_CPUID, 1, &eax, &ebx, &ecx, &edx);
> + cpu_system_xfeatures_mask = ecx + ((u64)edx << 32);
> +
> + xfeatures_mask_all = cpu_user_xfeatures_mask | cpu_system_xfeatures_mask;
... and not introduce xfeatures_mask_all at all but everywhere you need
all features, to do:
(xfeatures_mask_user | xfeatures_mask_system)
and work with that.
...
> @@ -1178,7 +1208,7 @@ int copy_kernel_to_xstate(struct xregs_state *xsave, const void *kbuf)
> * The state that came in from userspace was user-state only.
> * Mask all the user states out of 'xfeatures':
> */
> - xsave->header.xfeatures &= XFEATURE_MASK_SUPERVISOR;
> + xsave->header.xfeatures &= (xfeatures_mask_all & ~xfeatures_mask_user);
... and this would be
xsave->header.xfeatures &= xfeatures_mask_system;
>
> /*
> * Add back in the features that came in from userspace:
> @@ -1234,7 +1264,7 @@ int copy_user_to_xstate(struct xregs_state *xsave, const void __user *ubuf)
> * The state that came in from userspace was user-state only.
> * Mask all the user states out of 'xfeatures':
> */
> - xsave->header.xfeatures &= XFEATURE_MASK_SUPERVISOR;
> + xsave->header.xfeatures &= (xfeatures_mask_all & ~xfeatures_mask_user);
Ditto here.
This way you have *two* mask variables and code queries them only.
Hmmm?
Or am I missing something?
--
Regards/Gruss,
Boris.
Good mailing practices for 400: avoid top-posting and trim the reply.
^ permalink raw reply
* Re: [PATCH v2] signal: add procfd_signal() syscall
From: Christian Brauner @ 2018-12-04 13:26 UTC (permalink / raw)
To: Florian Weimer
Cc: ebiederm, linux-kernel, serge, jannh, luto, akpm, oleg, cyphar,
viro, linux-fsdevel, linux-api, dancol, timmurray, linux-man,
Kees Cook
In-Reply-To: <874lbtjvtd.fsf@oldenburg2.str.redhat.com>
On Tue, Dec 04, 2018 at 01:55:10PM +0100, Florian Weimer wrote:
> * Christian Brauner:
>
> > On Mon, Dec 03, 2018 at 05:57:51PM +0100, Florian Weimer wrote:
> >> * Christian Brauner:
> >>
> >> > Ok, I finally have access to source code again. Scratch what I said above!
> >> > I looked at the code and tested it. If the process has exited but not
> >> > yet waited upon aka is a zombie procfd_send_signal() will return 0. This
> >> > is identical to kill(2) behavior. It should've been sort-of obvious
> >> > since when a process is in zombie state /proc/<pid> will still be around
> >> > which means that struct pid must still be around.
> >>
> >> Should we make this state more accessible, by providing a different
> >> error code?
> >
> > No, I don't think we want that. Imho, It's not really helpful. Signals
> > are still delivered to zombies. If zombie state were to always mean that
> > no-one is going to wait on this thread anymore then it would make sense
> > to me. But given that zombie can also mean that someone put a
> > sleep(1000) right before their wait() call in the parent it seems odd to
> > report back that it is a zombie.
>
> It allows for error checking that the recipient of a signal is still
> running. It's obviously not reliable, but I think it could be helpful
> in the context of closely cooperating processes.
>
> >> Will the system call ever return ESRCH, given that you have a handle for
> >> the process?
> >
> > Yes, whenever you signal a process that has already been waited upon:
> > - get procfd handle referring to <proc>
> > - <proc> exits and is waited upon
> > - procfd_send_signal(procfd, ...) returns -1 with errno == ESRCH
>
> I see, thanks.
>
> >> Do you want to land all this in one kernel release? I wonder how
> >> applications are supposed to discover kernel support if functionality is
> >> split across several kernel releases. If you get EINVAL or EBADF, it
> >> may not be obvious what is going on.
> >
> > Sigh, I get that but I really don't want to have to land this in one big
> > chunk. I want this syscall to go in in a as soon as we can to fulfill
> > the most basic need: having a way that guarantees us that we signal the
> > process that we intended to signal.
> >
> > The thread case is easy to implement on top of it. But I suspect we will
> > quibble about the exact semantics for a long time. Even now we have been
> > on multiple - justified - detrous. That's all pefectly fine and
> > expected. But if we have the basic functionality in we have time to do
> > all of that. We might even land it in the same kernel release still. I
> > really don't want to come of as tea-party-kernel-conservative here but I
> > have time-and-time again seen that making something fancy and cover ever
> > interesting feature in one patchset takes a very very long time.
> >
> > If you care about userspace being able to detect that case I can return
> > EOPNOTSUPP when a tid descriptor is passed.
>
> I suppose that's fine. Or alternatively, when thread group support is
> added, introduce a flag that applications have to use to enable it, so
> that they can probe for support by checking support for the flag.
>
> I wouldn't be opposed to a new system call like this either:
>
> int procfd_open (pid_t thread_group, pid_t thread_id, unsigned flags);
>
> But I think this is frowned upon on the kernel side.
If this is purely about getting a procfd then I think this isn't really
necessary since you can get it from /proc/<pid> and
/proc/<pid>/task/<tid> so a syscall just for that is likely overkill.
However, I started to pick up the CLONE_FD patchset but ideally I would
like it to be way simpler to what was proposed back in the day (which is
not a critique, I just don't feel comfortable with bringing massive
patches to the table that I can barely judge wrt to their correctness.
:)). I have toyed around with this a little and I'm tempted to simply
have the syscall always return an fd for the process and not require a
separate flag for this. But I need to work through the details and this
is really far out into the (kernel) future.
>
> >> What happens if you use the new interface with an O_PATH descriptor?
> >
> > You get EINVAL. When an O_PATH file descriptor is created the kernel
> > will set file->f_op = &empty_fops at which point the check I added
> > if (!proc_is_tgid_procfd(f.file))
> > goto err;
> > will fail. Imho this is correct behavior since technically signaling a
> > struct pid is the equivalent of writing to a file and hence doesn't
> > purely operate on the file descriptor level.
>
> Yes, that's quite reasonable. Thanks.
>
> Florian
^ permalink raw reply
* Re: [PATCH v2] signal: add procfd_signal() syscall
From: Florian Weimer @ 2018-12-04 12:55 UTC (permalink / raw)
To: Christian Brauner
Cc: ebiederm, linux-kernel, serge, jannh, luto, akpm, oleg, cyphar,
viro, linux-fsdevel, linux-api, dancol, timmurray, linux-man,
Kees Cook
In-Reply-To: <20181203180224.fkvw4kajtbvru2ku@brauner.io>
* Christian Brauner:
> On Mon, Dec 03, 2018 at 05:57:51PM +0100, Florian Weimer wrote:
>> * Christian Brauner:
>>
>> > Ok, I finally have access to source code again. Scratch what I said above!
>> > I looked at the code and tested it. If the process has exited but not
>> > yet waited upon aka is a zombie procfd_send_signal() will return 0. This
>> > is identical to kill(2) behavior. It should've been sort-of obvious
>> > since when a process is in zombie state /proc/<pid> will still be around
>> > which means that struct pid must still be around.
>>
>> Should we make this state more accessible, by providing a different
>> error code?
>
> No, I don't think we want that. Imho, It's not really helpful. Signals
> are still delivered to zombies. If zombie state were to always mean that
> no-one is going to wait on this thread anymore then it would make sense
> to me. But given that zombie can also mean that someone put a
> sleep(1000) right before their wait() call in the parent it seems odd to
> report back that it is a zombie.
It allows for error checking that the recipient of a signal is still
running. It's obviously not reliable, but I think it could be helpful
in the context of closely cooperating processes.
>> Will the system call ever return ESRCH, given that you have a handle for
>> the process?
>
> Yes, whenever you signal a process that has already been waited upon:
> - get procfd handle referring to <proc>
> - <proc> exits and is waited upon
> - procfd_send_signal(procfd, ...) returns -1 with errno == ESRCH
I see, thanks.
>> Do you want to land all this in one kernel release? I wonder how
>> applications are supposed to discover kernel support if functionality is
>> split across several kernel releases. If you get EINVAL or EBADF, it
>> may not be obvious what is going on.
>
> Sigh, I get that but I really don't want to have to land this in one big
> chunk. I want this syscall to go in in a as soon as we can to fulfill
> the most basic need: having a way that guarantees us that we signal the
> process that we intended to signal.
>
> The thread case is easy to implement on top of it. But I suspect we will
> quibble about the exact semantics for a long time. Even now we have been
> on multiple - justified - detrous. That's all pefectly fine and
> expected. But if we have the basic functionality in we have time to do
> all of that. We might even land it in the same kernel release still. I
> really don't want to come of as tea-party-kernel-conservative here but I
> have time-and-time again seen that making something fancy and cover ever
> interesting feature in one patchset takes a very very long time.
>
> If you care about userspace being able to detect that case I can return
> EOPNOTSUPP when a tid descriptor is passed.
I suppose that's fine. Or alternatively, when thread group support is
added, introduce a flag that applications have to use to enable it, so
that they can probe for support by checking support for the flag.
I wouldn't be opposed to a new system call like this either:
int procfd_open (pid_t thread_group, pid_t thread_id, unsigned flags);
But I think this is frowned upon on the kernel side.
>> What happens if you use the new interface with an O_PATH descriptor?
>
> You get EINVAL. When an O_PATH file descriptor is created the kernel
> will set file->f_op = &empty_fops at which point the check I added
> if (!proc_is_tgid_procfd(f.file))
> goto err;
> will fail. Imho this is correct behavior since technically signaling a
> struct pid is the equivalent of writing to a file and hence doesn't
> purely operate on the file descriptor level.
Yes, that's quite reasonable. Thanks.
Florian
^ permalink raw reply
* Re: pkeys: Reserve PKEY_DISABLE_READ
From: Ram Pai @ 2018-12-04 6:23 UTC (permalink / raw)
To: Florian Weimer; +Cc: Dave Hansen, linux-api, linuxppc-dev, linux-mm
In-Reply-To: <87pnuibobh.fsf@oldenburg.str.redhat.com>
On Mon, Dec 03, 2018 at 04:52:02PM +0100, Florian Weimer wrote:
> * Ram Pai:
>
> > So the problem is as follows:
> >
> > Currently the kernel supports 'disable-write' and 'disable-access'.
> >
> > On x86, cpu supports 'disable-write' and 'disable-access'. This
> > matches with what the kernel supports. All good.
> >
> > However on power, cpu supports 'disable-read' too. Since userspace can
> > program the cpu directly, userspace has the ability to set
> > 'disable-read' too. This can lead to inconsistency between the kernel
> > and the userspace.
> >
> > We want the kernel to match userspace on all architectures.
>
> Correct.
>
> > Proposed Solution:
> >
> > Enhance the kernel to understand 'disable-read', and facilitate architectures
> > that understand 'disable-read' to allow it.
> >
> > Also explicitly define the semantics of disable-access as
> > 'disable-read and disable-write'
> >
> > Did I get this right? Assuming I did, the implementation has to do
> > the following --
> >
> > On power, sys_pkey_alloc() should succeed if the init_val
> > is PKEY_DISABLE_READ, PKEY_DISABLE_WRITE, PKEY_DISABLE_ACCESS
> > or any combination of the three.
>
> Agreed.
>
> > On x86, sys_pkey_alloc() should succeed if the init_val is
> > PKEY_DISABLE_WRITE or PKEY_DISABLE_ACCESS or PKEY_DISABLE_READ
> > or any combination of the three, except PKEY_DISABLE_READ
> > specified all by itself.
>
> Again agreed. That's a clever way of phrasing it actually.
>
> > On all other arches, none of the flags are supported.
> >
> >
> > Are we on the same plate?
>
> I think so, thanks.
>
> Florian
Ok. here is a patch, compiled but not tested. See if this meets the
specifications.
-----------------------------------------------------------------------------------
commit 3dc06e73f3795921265d5d1d935e428deab01616
Author: Ram Pai <linuxram@us.ibm.com>
Date: Tue Dec 4 00:04:11 2018 -0500
pkeys: add support of PKEY_DISABLE_READ
Kernel supports 'disable-write' and 'disable-access'.
x86 cpu supports 'disable-write' and 'disable-access'. This
matches with the kernel support.
However POWER cpu supports 'disable-read' too. Since userspace can
program the cpu directly, userspace has the ability to set
'disable-read' too. This can lead to inconsistency between the kernel
and the userspace.
Make kernel match userspace on all architectures.
Enhance the kernel to understand 'disable-read', and facilitate architectures
that understand 'disable-read' to allow it.
Define the semantics of disable-access as 'disable-read and disable-write'
Signed-off-by: Ram Pai <linuxram@us.ibm.com>
diff --git a/arch/powerpc/include/asm/pkeys.h b/arch/powerpc/include/asm/pkeys.h
index 20ebf15..4bd09d0 100644
--- a/arch/powerpc/include/asm/pkeys.h
+++ b/arch/powerpc/include/asm/pkeys.h
@@ -19,11 +19,7 @@
#define ARCH_VM_PKEY_FLAGS (VM_PKEY_BIT0 | VM_PKEY_BIT1 | VM_PKEY_BIT2 | \
VM_PKEY_BIT3 | VM_PKEY_BIT4)
-/* Override any generic PKEY permission defines */
#define PKEY_DISABLE_EXECUTE 0x4
-#define PKEY_ACCESS_MASK (PKEY_DISABLE_ACCESS | \
- PKEY_DISABLE_WRITE | \
- PKEY_DISABLE_EXECUTE)
static inline u64 pkey_to_vmflag_bits(u16 pkey)
{
@@ -199,6 +195,16 @@ static inline bool arch_pkeys_enabled(void)
return !static_branch_likely(&pkey_disabled);
}
+extern bool __arch_pkey_access_rights_valid(unsigned long rights);
+
+static inline bool arch_pkey_access_rights_valid(unsigned long rights)
+{
+ if (static_branch_likely(&pkey_disabled))
+ return false;
+
+ return __arch_pkey_access_rights_valid(rights);
+}
+
extern void pkey_mm_init(struct mm_struct *mm);
extern bool arch_supports_pkeys(int cap);
extern unsigned int arch_usable_pkeys(void);
diff --git a/arch/powerpc/include/uapi/asm/mman.h b/arch/powerpc/include/uapi/asm/mman.h
index 65065ce..e63bc37 100644
--- a/arch/powerpc/include/uapi/asm/mman.h
+++ b/arch/powerpc/include/uapi/asm/mman.h
@@ -30,10 +30,4 @@
#define MAP_STACK 0x20000 /* give out an address that is best suited for process/thread stacks */
#define MAP_HUGETLB 0x40000 /* create a huge page mapping */
-/* Override any generic PKEY permission defines */
-#define PKEY_DISABLE_EXECUTE 0x4
-#undef PKEY_ACCESS_MASK
-#define PKEY_ACCESS_MASK (PKEY_DISABLE_ACCESS |\
- PKEY_DISABLE_WRITE |\
- PKEY_DISABLE_EXECUTE)
#endif /* _UAPI_ASM_POWERPC_MMAN_H */
diff --git a/arch/powerpc/mm/pkeys.c b/arch/powerpc/mm/pkeys.c
index 5d65c47..a4f288b 100644
--- a/arch/powerpc/mm/pkeys.c
+++ b/arch/powerpc/mm/pkeys.c
@@ -67,7 +67,7 @@ int pkey_initialize(void)
* Ensure that the bits a distinct.
*/
BUILD_BUG_ON(PKEY_DISABLE_EXECUTE &
- (PKEY_DISABLE_ACCESS | PKEY_DISABLE_WRITE));
+ (PKEY_DISABLE_READ | PKEY_DISABLE_WRITE | PKEY_DISABLE_ACCESS));
/*
* pkey_to_vmflag_bits() assumes that the pkey bits are contiguous
@@ -259,11 +259,20 @@ int __arch_set_user_pkey_access(struct task_struct *tsk, int pkey,
new_amr_bits |= AMR_RD_BIT | AMR_WR_BIT;
else if (init_val & PKEY_DISABLE_WRITE)
new_amr_bits |= AMR_WR_BIT;
+ else if (init_val & PKEY_DISABLE_READ)
+ new_amr_bits |= AMR_RD_BIT;
init_amr(pkey, new_amr_bits);
return 0;
}
+bool __arch_pkey_access_rights_valid(unsigned long rights)
+{
+ unsigned long mask = PKEY_DISABLE_READ | PKEY_DISABLE_WRITE |\
+ PKEY_DISABLE_ACCESS;
+ return (rights & mask);
+}
+
void thread_pkey_regs_save(struct thread_struct *thread)
{
if (static_branch_likely(&pkey_disabled))
diff --git a/arch/x86/include/asm/pkeys.h b/arch/x86/include/asm/pkeys.h
index 19b137f..4f36a7e 100644
--- a/arch/x86/include/asm/pkeys.h
+++ b/arch/x86/include/asm/pkeys.h
@@ -14,6 +14,15 @@ static inline bool arch_pkeys_enabled(void)
return boot_cpu_has(X86_FEATURE_OSPKE);
}
+extern bool __arch_pkey_access_rights_valid(unsigned long rights);
+static inline bool arch_pkey_access_rights_valid(unsigned long rights)
+{
+ if (!boot_cpu_has(X86_FEATURE_OSPKE))
+ return false;
+
+ return __arch_pkey_access_rights_valid(rights);
+}
+
/*
* Try to dedicate one of the protection keys to be used as an
* execute-only protection key.
diff --git a/arch/x86/mm/pkeys.c b/arch/x86/mm/pkeys.c
index 6e98e0a..fcfe1b2 100644
--- a/arch/x86/mm/pkeys.c
+++ b/arch/x86/mm/pkeys.c
@@ -72,6 +72,17 @@ int __execute_only_pkey(struct mm_struct *mm)
return execute_only_pkey;
}
+bool __arch_pkey_access_rights_valid(unsigned long rights)
+{
+ unsigned long mask = PKEY_DISABLE_READ | PKEY_DISABLE_WRITE |\
+ PKEY_DISABLE_ACCESS;
+ if (!(rights & mask))
+ return false;
+
+ /* return failure if only PKEY_DISABLE_READ is specified */
+ return ((rights & mask) != PKEY_DISABLE_READ);
+}
+
static inline bool vma_is_pkey_exec_only(struct vm_area_struct *vma)
{
/* Do this check first since the vm_flags should be hot */
diff --git a/include/linux/pkeys.h b/include/linux/pkeys.h
index 2955ba97..2c330fa 100644
--- a/include/linux/pkeys.h
+++ b/include/linux/pkeys.h
@@ -48,6 +48,11 @@ static inline void copy_init_pkru_to_fpregs(void)
{
}
+static inline bool arch_pkey_access_rights_valid(unsigned long rights)
+{
+ return false;
+}
+
#endif /* ! CONFIG_ARCH_HAS_PKEYS */
#endif /* _LINUX_PKEYS_H */
diff --git a/include/uapi/asm-generic/mman-common.h b/include/uapi/asm-generic/mman-common.h
index e7ee328..d2e1a5e 100644
--- a/include/uapi/asm-generic/mman-common.h
+++ b/include/uapi/asm-generic/mman-common.h
@@ -71,7 +71,5 @@
#define PKEY_DISABLE_ACCESS 0x1
#define PKEY_DISABLE_WRITE 0x2
-#define PKEY_ACCESS_MASK (PKEY_DISABLE_ACCESS |\
- PKEY_DISABLE_WRITE)
-
+#define PKEY_DISABLE_READ 0x10
#endif /* __ASM_GENERIC_MMAN_COMMON_H */
diff --git a/mm/mprotect.c b/mm/mprotect.c
index 6d33162..f4cefc3 100644
--- a/mm/mprotect.c
+++ b/mm/mprotect.c
@@ -597,7 +597,7 @@ static int do_mprotect_pkey(unsigned long start, size_t len,
if (flags)
return -EINVAL;
/* check for unsupported init values */
- if (init_val & ~PKEY_ACCESS_MASK)
+ if (!arch_pkey_access_rights_valid(init_val))
return -EINVAL;
down_write(¤t->mm->mmap_sem);
-----------------------------------------------------------------------------
^ permalink raw reply related
* Re: [PATCH v2] signal: add procfd_signal() syscall
From: Aleksa Sarai @ 2018-12-04 6:03 UTC (permalink / raw)
To: Christian Brauner
Cc: Florian Weimer, ebiederm, linux-kernel, serge, jannh, luto, akpm,
oleg, viro, linux-fsdevel, linux-api, dancol, timmurray,
linux-man, Kees Cook
In-Reply-To: <20181203180224.fkvw4kajtbvru2ku@brauner.io>
[-- Attachment #1: Type: text/plain, Size: 2424 bytes --]
On 2018-12-03, Christian Brauner <christian@brauner.io> wrote:
> > > As I pointed out in another mail my I is to make this work by using
> > > file descriptors for /proc/<pid>/task/<tid>. I don't want this in the
> > > initial patchset though. I prefer to slowly add those features once
> > > we have gotten the basic functionality in.
> >
> > Do you want to land all this in one kernel release? I wonder how
> > applications are supposed to discover kernel support if functionality is
> > split across several kernel releases. If you get EINVAL or EBADF, it
> > may not be obvious what is going on.
>
> Sigh, I get that but I really don't want to have to land this in one big
> chunk. I want this syscall to go in in a as soon as we can to fulfill
> the most basic need: having a way that guarantees us that we signal the
> process that we intended to signal.
>
> The thread case is easy to implement on top of it. But I suspect we will
> quibble about the exact semantics for a long time. Even now we have been
> on multiple - justified - detrous. That's all pefectly fine and
> expected. But if we have the basic functionality in we have time to do
> all of that. We might even land it in the same kernel release still. I
> really don't want to come of as tea-party-kernel-conservative here but I
> have time-and-time again seen that making something fancy and cover ever
> interesting feature in one patchset takes a very very long time.
>
> If you care about userspace being able to detect that case I can return
> EOPNOTSUPP when a tid descriptor is passed.
Personally, I'm +1 on -EOPNOTSUPP so we can get an MVP merged, and add
new features in later patches.
> > What happens if you use the new interface with an O_PATH descriptor?
>
> You get EINVAL. When an O_PATH file descriptor is created the kernel
> will set file->f_op = &empty_fops at which point the check I added
> if (!proc_is_tgid_procfd(f.file))
> goto err;
> will fail. Imho this is correct behavior since technically signaling a
> struct pid is the equivalent of writing to a file and hence doesn't
> purely operate on the file descriptor level.
Not to mention that O_PATH file descriptors are a whole kettle of fish
when it comes to permission checking semantics.
--
Aleksa Sarai
Senior Software Engineer (Containers)
SUSE Linux GmbH
<https://www.cyphar.com/>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* Re: [PATCH v9 2/4] seccomp: switch system call argument type to void *
From: Tycho Andersen @ 2018-12-04 2:34 UTC (permalink / raw)
To: kbuild test robot
Cc: kbuild-all, Kees Cook, Andy Lutomirski, Oleg Nesterov,
Eric W . Biederman, Serge E . Hallyn, Christian Brauner,
Tyler Hicks, Akihiro Suda, Aleksa Sarai, Jann Horn, linux-kernel,
containers, linux-api
In-Reply-To: <20181204021726.GG3504@cisco>
On Mon, Dec 03, 2018 at 07:17:26PM -0700, Tycho Andersen wrote:
> On Tue, Dec 04, 2018 at 10:07:38AM +0800, kbuild test robot wrote:
> > Hi Tycho,
> >
> > I love your patch! Yet something to improve:
> >
> > [auto build test ERROR on linus/master]
> > [also build test ERROR on v4.20-rc5 next-20181203]
> > [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
> >
> > url: https://github.com/0day-ci/linux/commits/Tycho-Andersen/seccomp-hoist-struct-seccomp_data-recalculation-higher/20181204-013450
> > config: i386-randconfig-x005-201848 (attached as .config)
> > compiler: gcc-7 (Debian 7.3.0-1) 7.3.0
> > reproduce:
> > # save the attached .config to linux build tree
> > make ARCH=i386
> >
> > All errors (new ones prefixed by >>):
> >
> > In file included from kernel/seccomp.c:28:0:
> > >> include/linux/syscalls.h:239:18: error: conflicting types for 'sys_seccomp'
> > asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) \
> > ^
> > include/linux/syscalls.h:225:2: note: in expansion of macro '__SYSCALL_DEFINEx'
> > __SYSCALL_DEFINEx(x, sname, __VA_ARGS__)
> > ^~~~~~~~~~~~~~~~~
> > include/linux/syscalls.h:216:36: note: in expansion of macro 'SYSCALL_DEFINEx'
> > #define SYSCALL_DEFINE3(name, ...) SYSCALL_DEFINEx(3, _##name, __VA_ARGS__)
> > ^~~~~~~~~~~~~~~
> > kernel/seccomp.c:946:1: note: in expansion of macro 'SYSCALL_DEFINE3'
> > SYSCALL_DEFINE3(seccomp, unsigned int, op, unsigned int, flags,
> > ^~~~~~~~~~~~~~~
> > In file included from kernel/seccomp.c:28:0:
> > include/linux/syscalls.h:881:17: note: previous declaration of 'sys_seccomp' was here
> > asmlinkage long sys_seccomp(unsigned int op, unsigned int flags,
> > ^~~~~~~~~~~
>
> Huh, I have no idea why I don't see this, but even with the attached
> config it still doesn't cause a problem for me. Anyway, I'll fix it up
> and do some more investigating...
Oh, because it's "make ARCH=i386". Whoosh :)
Anyway, it's fixed for v10.
Tycho
^ permalink raw reply
* Re: [PATCH v9 2/4] seccomp: switch system call argument type to void *
From: Tycho Andersen @ 2018-12-04 2:17 UTC (permalink / raw)
To: kbuild test robot
Cc: kbuild-all, Kees Cook, Andy Lutomirski, Oleg Nesterov,
Eric W . Biederman, Serge E . Hallyn, Christian Brauner,
Tyler Hicks, Akihiro Suda, Aleksa Sarai, Jann Horn, linux-kernel,
containers, linux-api
In-Reply-To: <201812041031.7kJxvTuh%fengguang.wu@intel.com>
On Tue, Dec 04, 2018 at 10:07:38AM +0800, kbuild test robot wrote:
> Hi Tycho,
>
> I love your patch! Yet something to improve:
>
> [auto build test ERROR on linus/master]
> [also build test ERROR on v4.20-rc5 next-20181203]
> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
>
> url: https://github.com/0day-ci/linux/commits/Tycho-Andersen/seccomp-hoist-struct-seccomp_data-recalculation-higher/20181204-013450
> config: i386-randconfig-x005-201848 (attached as .config)
> compiler: gcc-7 (Debian 7.3.0-1) 7.3.0
> reproduce:
> # save the attached .config to linux build tree
> make ARCH=i386
>
> All errors (new ones prefixed by >>):
>
> In file included from kernel/seccomp.c:28:0:
> >> include/linux/syscalls.h:239:18: error: conflicting types for 'sys_seccomp'
> asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) \
> ^
> include/linux/syscalls.h:225:2: note: in expansion of macro '__SYSCALL_DEFINEx'
> __SYSCALL_DEFINEx(x, sname, __VA_ARGS__)
> ^~~~~~~~~~~~~~~~~
> include/linux/syscalls.h:216:36: note: in expansion of macro 'SYSCALL_DEFINEx'
> #define SYSCALL_DEFINE3(name, ...) SYSCALL_DEFINEx(3, _##name, __VA_ARGS__)
> ^~~~~~~~~~~~~~~
> kernel/seccomp.c:946:1: note: in expansion of macro 'SYSCALL_DEFINE3'
> SYSCALL_DEFINE3(seccomp, unsigned int, op, unsigned int, flags,
> ^~~~~~~~~~~~~~~
> In file included from kernel/seccomp.c:28:0:
> include/linux/syscalls.h:881:17: note: previous declaration of 'sys_seccomp' was here
> asmlinkage long sys_seccomp(unsigned int op, unsigned int flags,
> ^~~~~~~~~~~
Huh, I have no idea why I don't see this, but even with the attached
config it still doesn't cause a problem for me. Anyway, I'll fix it up
and do some more investigating...
Tycho
^ permalink raw reply
* Re: [PATCH v9 2/4] seccomp: switch system call argument type to void *
From: kbuild test robot @ 2018-12-04 2:07 UTC (permalink / raw)
Cc: kbuild-all, Kees Cook, Andy Lutomirski, Oleg Nesterov,
Eric W . Biederman, Serge E . Hallyn, Christian Brauner,
Tyler Hicks, Akihiro Suda, Aleksa Sarai, Jann Horn, linux-kernel,
containers, linux-api, Tycho Andersen
In-Reply-To: <20181203032827.27978-3-tycho@tycho.ws>
[-- Attachment #1: Type: text/plain, Size: 4432 bytes --]
Hi Tycho,
I love your patch! Yet something to improve:
[auto build test ERROR on linus/master]
[also build test ERROR on v4.20-rc5 next-20181203]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Tycho-Andersen/seccomp-hoist-struct-seccomp_data-recalculation-higher/20181204-013450
config: i386-randconfig-x005-201848 (attached as .config)
compiler: gcc-7 (Debian 7.3.0-1) 7.3.0
reproduce:
# save the attached .config to linux build tree
make ARCH=i386
All errors (new ones prefixed by >>):
In file included from kernel/seccomp.c:28:0:
>> include/linux/syscalls.h:239:18: error: conflicting types for 'sys_seccomp'
asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) \
^
include/linux/syscalls.h:225:2: note: in expansion of macro '__SYSCALL_DEFINEx'
__SYSCALL_DEFINEx(x, sname, __VA_ARGS__)
^~~~~~~~~~~~~~~~~
include/linux/syscalls.h:216:36: note: in expansion of macro 'SYSCALL_DEFINEx'
#define SYSCALL_DEFINE3(name, ...) SYSCALL_DEFINEx(3, _##name, __VA_ARGS__)
^~~~~~~~~~~~~~~
kernel/seccomp.c:946:1: note: in expansion of macro 'SYSCALL_DEFINE3'
SYSCALL_DEFINE3(seccomp, unsigned int, op, unsigned int, flags,
^~~~~~~~~~~~~~~
In file included from kernel/seccomp.c:28:0:
include/linux/syscalls.h:881:17: note: previous declaration of 'sys_seccomp' was here
asmlinkage long sys_seccomp(unsigned int op, unsigned int flags,
^~~~~~~~~~~
vim +/sys_seccomp +239 include/linux/syscalls.h
1bd21c6c2 Dominik Brodowski 2018-04-05 228
e145242ea Dominik Brodowski 2018-04-09 229 /*
e145242ea Dominik Brodowski 2018-04-09 230 * The asmlinkage stub is aliased to a function named __se_sys_*() which
e145242ea Dominik Brodowski 2018-04-09 231 * sign-extends 32-bit ints to longs whenever needed. The actual work is
e145242ea Dominik Brodowski 2018-04-09 232 * done within __do_sys_*().
e145242ea Dominik Brodowski 2018-04-09 233 */
1bd21c6c2 Dominik Brodowski 2018-04-05 234 #ifndef __SYSCALL_DEFINEx
bed1ffca0 Frederic Weisbecker 2009-03-13 235 #define __SYSCALL_DEFINEx(x, name, ...) \
bee200317 Arnd Bergmann 2018-06-19 236 __diag_push(); \
bee200317 Arnd Bergmann 2018-06-19 237 __diag_ignore(GCC, 8, "-Wattribute-alias", \
bee200317 Arnd Bergmann 2018-06-19 238 "Type aliasing is used to sanitize syscall arguments");\
83460ec8d Andi Kleen 2013-11-12 @239 asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) \
e145242ea Dominik Brodowski 2018-04-09 240 __attribute__((alias(__stringify(__se_sys##name)))); \
c9a211951 Howard McLauchlan 2018-03-21 241 ALLOW_ERROR_INJECTION(sys##name, ERRNO); \
e145242ea Dominik Brodowski 2018-04-09 242 static inline long __do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__));\
e145242ea Dominik Brodowski 2018-04-09 243 asmlinkage long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)); \
e145242ea Dominik Brodowski 2018-04-09 244 asmlinkage long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)) \
1a94bc347 Heiko Carstens 2009-01-14 245 { \
e145242ea Dominik Brodowski 2018-04-09 246 long ret = __do_sys##name(__MAP(x,__SC_CAST,__VA_ARGS__));\
07fe6e00f Al Viro 2013-01-21 247 __MAP(x,__SC_TEST,__VA_ARGS__); \
2cf096668 Al Viro 2013-01-21 248 __PROTECT(x, ret,__MAP(x,__SC_ARGS,__VA_ARGS__)); \
2cf096668 Al Viro 2013-01-21 249 return ret; \
1a94bc347 Heiko Carstens 2009-01-14 250 } \
bee200317 Arnd Bergmann 2018-06-19 251 __diag_pop(); \
e145242ea Dominik Brodowski 2018-04-09 252 static inline long __do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))
1bd21c6c2 Dominik Brodowski 2018-04-05 253 #endif /* __SYSCALL_DEFINEx */
1a94bc347 Heiko Carstens 2009-01-14 254
:::::: The code at line 239 was first introduced by commit
:::::: 83460ec8dcac14142e7860a01fa59c267ac4657c syscalls.h: use gcc alias instead of assembler aliases for syscalls
:::::: TO: Andi Kleen <ak@linux.intel.com>
:::::: CC: Linus Torvalds <torvalds@linux-foundation.org>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 29159 bytes --]
^ permalink raw reply
* Re: [PATCH v9 3/4] seccomp: add a return code to trap to userspace
From: Serge E. Hallyn @ 2018-12-04 0:10 UTC (permalink / raw)
To: Tycho Andersen
Cc: Serge E. Hallyn, Kees Cook, Andy Lutomirski, Oleg Nesterov,
Eric W . Biederman, Christian Brauner, Tyler Hicks, Akihiro Suda,
Aleksa Sarai, Jann Horn, linux-kernel, containers, linux-api
In-Reply-To: <20181203155211.GB3504@cisco>
On Mon, Dec 03, 2018 at 08:52:11AM -0700, Tycho Andersen wrote:
> On Sun, Dec 02, 2018 at 11:26:50PM -0600, Serge E. Hallyn wrote:
> > On Sun, Dec 02, 2018 at 08:28:26PM -0700, Tycho Andersen wrote:
> > > +struct seccomp_knotif {
> > > + /* The struct pid of the task whose filter triggered the notification */
> > > + struct task_struct *task;
> > > +
> > > + /* The "cookie" for this request; this is unique for this filter. */
> > > + u64 id;
> > > +
> > > + /*
> > > + * The seccomp data. This pointer is valid the entire time this
> > > + * notification is active, since it comes from __seccomp_filter which
> >
> > define 'active' - is a notification in state REPLIED still active?
>
> Yes,
>
> > Actually while looking at that, I came to wondering - when are knotifs
> > freed? Seems like only during seccomp_notify_release(), i.e. when the
> > tracing task stops polling for events? Is that going to be a problem?
> > Or am I misreading this?
>
> they're stack allocated in do_user_notification(). So "active" in this
> sense really means "somewhere in do_user_notification()".
D'oh! I see, thanks :)
> > > + if (ret == 0 && copy_to_user(buf, &unotif, sizeof(unotif))) {
> > > + ret = -EFAULT;
> > > +
> > > + /*
> > > + * Userspace screwed up. To make sure that we keep this
> > > + * notification alive, let's reset it back to INIT. It
> >
> > Is keeping the notification alive the right thing to do?
> >
> > If userspace has messed up in something this touchy, it seems unlikely
> > that it'll to better if we give it a do-over... I'm not sure whether
> > killing the whole thing (victim and tracer) is the right thing or not.
>
> I suppose we could do that too. I just didn't want to get into a
> situation where the notification is lost and the task is stuck because
> userspace screwed up here.
Yeah, that's probably best - I'm just trying to see whether there is
any way that this could be abused. My underactive imagination hasn't
come up with anything yet.
-serge
^ permalink raw reply
* Re: [PATCH v9 2/4] seccomp: switch system call argument type to void *
From: Paul Moore @ 2018-12-04 0:03 UTC (permalink / raw)
To: Serge Hallyn
Cc: Tycho Andersen, mtk.manpages, keescook, luto, oleg, ebiederm,
christian, tyhicks, suda.akihiro, asarai, jannh, linux-kernel,
containers, linux-api
In-Reply-To: <20181203050108.GB31406@mail.hallyn.com>
On Mon, Dec 3, 2018 at 12:01 AM Serge E. Hallyn <serge@hallyn.com> wrote:
> On Sun, Dec 02, 2018 at 08:28:25PM -0700, Tycho Andersen wrote:
> > The const qualifier causes problems for any code that wants to write to the
> > third argument of the seccomp syscall, as we will do in a future patch in
> > this series.
> >
> > The third argument to the seccomp syscall is documented as void *, so
> > rather than just dropping the const, let's switch everything to use void *
> > as well.
> >
> > I believe this is safe because of 1. the documentation above, 2. there's no
> > real type information exported about syscalls anywhere besides the man
> > pages.
> >
> > Signed-off-by: Tycho Andersen <tycho@tycho.ws>
> > CC: Kees Cook <keescook@chromium.org>
> > CC: Andy Lutomirski <luto@amacapital.net>
> > CC: Oleg Nesterov <oleg@redhat.com>
> > CC: Eric W. Biederman <ebiederm@xmission.com>
> > CC: "Serge E. Hallyn" <serge@hallyn.com>
>
> Acked-by: Serge Hallyn <serge@hallyn.com>
>
> Though I'm not entirely convinced there will be no ill effects of changing
> the argument type. I'll feel comfortable when Michael and Paul say it's
> fine :)
Well, looking at the seccomp(2) manpage on my system (dated
2018-02-02) the third argument is already shown as a "void *args":
SYNOPSIS
#include <linux/seccomp.h>
#include <linux/filter.h>
#include <linux/audit.h>
#include <linux/signal.h>
#include <sys/ptrace.h>
int seccomp(unsigned int operation, unsigned int flags, void *args);
... so I think we're safe :)
>From a libseccomp perspective, we always call seccomp(2) via
syscall(2) so it is unlikely we would ever run into problems, not too
mention that we are just talking about the pointer type used in the
kernel; from a syscall ABI perspective it is still a pointer value and
that is the important part.
> > CC: Christian Brauner <christian@brauner.io>
> > CC: Tyler Hicks <tyhicks@canonical.com>
> > CC: Akihiro Suda <suda.akihiro@lab.ntt.co.jp>
> > ---
> > include/linux/seccomp.h | 2 +-
> > kernel/seccomp.c | 8 ++++----
> > 2 files changed, 5 insertions(+), 5 deletions(-)
> >
> > diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h
> > index e5320f6c8654..b5103c019cf4 100644
> > --- a/include/linux/seccomp.h
> > +++ b/include/linux/seccomp.h
> > @@ -43,7 +43,7 @@ extern void secure_computing_strict(int this_syscall);
> > #endif
> >
> > extern long prctl_get_seccomp(void);
> > -extern long prctl_set_seccomp(unsigned long, char __user *);
> > +extern long prctl_set_seccomp(unsigned long, void __user *);
> >
> > static inline int seccomp_mode(struct seccomp *s)
> > {
> > diff --git a/kernel/seccomp.c b/kernel/seccomp.c
> > index 96afc32e041d..393e029f778a 100644
> > --- a/kernel/seccomp.c
> > +++ b/kernel/seccomp.c
> > @@ -924,7 +924,7 @@ static long seccomp_get_action_avail(const char __user *uaction)
> >
> > /* Common entry point for both prctl and syscall. */
> > static long do_seccomp(unsigned int op, unsigned int flags,
> > - const char __user *uargs)
> > + void __user *uargs)
> > {
> > switch (op) {
> > case SECCOMP_SET_MODE_STRICT:
> > @@ -944,7 +944,7 @@ static long do_seccomp(unsigned int op, unsigned int flags,
> > }
> >
> > SYSCALL_DEFINE3(seccomp, unsigned int, op, unsigned int, flags,
> > - const char __user *, uargs)
> > + void __user *, uargs)
> > {
> > return do_seccomp(op, flags, uargs);
> > }
> > @@ -956,10 +956,10 @@ SYSCALL_DEFINE3(seccomp, unsigned int, op, unsigned int, flags,
> > *
> > * Returns 0 on success or -EINVAL on failure.
> > */
> > -long prctl_set_seccomp(unsigned long seccomp_mode, char __user *filter)
> > +long prctl_set_seccomp(unsigned long seccomp_mode, void __user *filter)
> > {
> > unsigned int op;
> > - char __user *uargs;
> > + void __user *uargs;
> >
> > switch (seccomp_mode) {
> > case SECCOMP_MODE_STRICT:
> > --
> > 2.19.1
--
paul moore
www.paul-moore.com
^ 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