Message ID | 87wmlx9sjh.fsf@oldenburg.str.redhat.com |
---|---|
State | New |
Headers | show |
Series | Linux: Change meaning of __rseq_size slightly | expand |
On 2024-07-07 10:37, Florian Weimer wrote: > It is now the active area of struct rseq (so 20 initially), not > the full struct size including padding at the end (32 initially). > Introduce a new symbol version for __rseq_area, so that I guess you mean __rseq_size rather than __rseq_area here ? > applications can rely on the new semantics. > > Update misc/tst-rseq to print some additional diagnostics. > > This replaces Michael's __rseq_feature_size patch. I prefer this > approach because it avoids confusion with having three different sizes > (__rseq_size, __rseq_feature_size, getauxval (AT_RSEQ_FEATURE_SIZE)). > I looked at the __rseq_size usage in CRIU, and it seems to be compatible > as long as the system has full ptrace support. I do not think we > need a compat symbol that is artificially increased to 32. We > can do this retroactively if necessary because there is a new symbol > version (so that newly linked applications can depend on the new > semantics). I agree, your approach keeps the ABI simple, I like it. > > I hope we can still put this into 2.40. It would be great if it can make it. :) If this patch is acceptable for 2.40, should we keep targetting 2.40 for the extensible rseq getauxval() integration or postpone that part to 2.41 ? AFAIU, once this patch is integrated, the getauxval() integration will not require any ABI change anymore. > > Tested on aarch64-linux-gnu, i386-linux-gnu, x86_64-linux-gnu. > Built with build-many-glibcs.py. Reviewed-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> Thanks, Mathieu
* Mathieu Desnoyers: > On 2024-07-07 10:37, Florian Weimer wrote: >> It is now the active area of struct rseq (so 20 initially), not >> the full struct size including padding at the end (32 initially). >> Introduce a new symbol version for __rseq_area, so that > > I guess you mean __rseq_size rather than __rseq_area here ? Right, fixed locally. > If this patch is acceptable for 2.40, should we keep targetting > 2.40 for the extensible rseq getauxval() integration or postpone > that part to 2.41 ? AFAIU, once this patch is integrated, the > getauxval() integration will not require any ABI change anymore. I think we don't want to take further changes for 2.40 at this point. > Reviewed-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> Thanks! Andreas, is this okay from a release manager perspective, too? Florian
On 2024-07-07 10 h 37, Florian Weimer wrote: > It is now the active area of struct rseq (so 20 initially), not > the full struct size including padding at the end (32 initially). > Introduce a new symbol version for __rseq_area, so that > applications can rely on the new semantics. > > Update misc/tst-rseq to print some additional diagnostics. > > This replaces Michael's __rseq_feature_size patch. I prefer this > approach because it avoids confusion with having three different sizes > (__rseq_size, __rseq_feature_size, getauxval (AT_RSEQ_FEATURE_SIZE)). > I looked at the __rseq_size usage in CRIU, and it seems to be compatible > as long as the system has full ptrace support. I do not think we > need a compat symbol that is artificially increased to 32. We > can do this retroactively if necessary because there is a new symbol > version (so that newly linked applications can depend on the new > semantics). One thing I'm not sure I understand, how would I write an application that can be built against any glibc with the '__rseq_symbol' that can distinguish between the old semantic of '__rseq_size == 32' and an hypothetical new kernel with 32 bytes of rseq features available? > > I hope we can still put this into 2.40. > > Tested on aarch64-linux-gnu, i386-linux-gnu, x86_64-linux-gnu. > Built with build-many-glibcs.py. > > Thanks, > Florian
* Michael Jeanson: > On 2024-07-07 10 h 37, Florian Weimer wrote: >> It is now the active area of struct rseq (so 20 initially), not >> the full struct size including padding at the end (32 initially). >> Introduce a new symbol version for __rseq_area, so that >> applications can rely on the new semantics. >> Update misc/tst-rseq to print some additional diagnostics. >> This replaces Michael's __rseq_feature_size patch. I prefer this >> approach because it avoids confusion with having three different sizes >> (__rseq_size, __rseq_feature_size, getauxval (AT_RSEQ_FEATURE_SIZE)). >> I looked at the __rseq_size usage in CRIU, and it seems to be compatible >> as long as the system has full ptrace support. I do not think we >> need a compat symbol that is artificially increased to 32. We >> can do this retroactively if necessary because there is a new symbol >> version (so that newly linked applications can depend on the new >> semantics). > > One thing I'm not sure I understand, how would I write an application > that can be built against any glibc with the '__rseq_symbol' that can > distinguish between the old semantic of '__rseq_size == 32' and an > hypothetical new kernel with 32 bytes of rseq features available? We don't know for sure because I do not think we have reached a getauxval (AT_RSEQ_FEATURE_SIZE) value that is larger than 28. For now, it is reasonable to assume that if __rseq_size is 32, and getauxval (AT_RSEQ_FEATURE_SIZE) is 28, then the usable part is 28. But if e.g. getauxval (AT_RSEQ_FEATURE_SIZE) is 40 and __rseq_size is still 32, we don't know if bytes up to 32 are usable. It could be that the kernel supports 20 bytes only. If __rseq_size is 32 and getauxval (AT_RSEQ_FEATURE_SIZE) is zero, the usable part is 20 bytes long. If __rseq_size is 0, rseq is not supported. Otherwise, __rseq_size is usable size. We discussed this a bit during today's call, and we concluded that this patch here may not the best possible solution. 1) [your patch] New __rseq_feature_size symbol: Applications using the new logic will fail to compile on older glibc. Compiled on new glibc, applications will fail to launch with a GLIBC_2.40 version error. 2) [this patch] New symbol version for __rseq_size (same variable as before): Compiled on new glibc, applications will fail to launch with a GLIBC_2.40 version error. This is done because they might use the new size semantics. But the application code specific to glibc 2.40 will compile successfully on glibc 2.39 and earlier, and run, given the weird results. This is not ideal. 3) [no patch, but similar to this patch] Treat this as a bug fix for __rseq_size: it should have been 20 initially. No new symbol version, but backport it 2.35 and later. Given so many distributions use stable release branches nowadays, it is likely the fix is available to users before they encounter rseq-using applications. The rules above apply to both 2) & 3). I'm leaning towards approach 3) and would do the backports to 2.35 and later. Thanks, Florian
On 2024-07-08 13 h 06, Florian Weimer wrote: > * Michael Jeanson: > >> On 2024-07-07 10 h 37, Florian Weimer wrote: >>> It is now the active area of struct rseq (so 20 initially), not >>> the full struct size including padding at the end (32 initially). >>> Introduce a new symbol version for __rseq_area, so that >>> applications can rely on the new semantics. >>> Update misc/tst-rseq to print some additional diagnostics. >>> This replaces Michael's __rseq_feature_size patch. I prefer this >>> approach because it avoids confusion with having three different sizes >>> (__rseq_size, __rseq_feature_size, getauxval (AT_RSEQ_FEATURE_SIZE)). >>> I looked at the __rseq_size usage in CRIU, and it seems to be compatible >>> as long as the system has full ptrace support. I do not think we >>> need a compat symbol that is artificially increased to 32. We >>> can do this retroactively if necessary because there is a new symbol >>> version (so that newly linked applications can depend on the new >>> semantics). >> >> One thing I'm not sure I understand, how would I write an application >> that can be built against any glibc with the '__rseq_symbol' that can >> distinguish between the old semantic of '__rseq_size == 32' and an >> hypothetical new kernel with 32 bytes of rseq features available? > > We don't know for sure because I do not think we have reached a > getauxval (AT_RSEQ_FEATURE_SIZE) value that is larger than 28. For now, > it is reasonable to assume that if __rseq_size is 32, and getauxval > (AT_RSEQ_FEATURE_SIZE) is 28, then the usable part is 28. But if > e.g. getauxval (AT_RSEQ_FEATURE_SIZE) is 40 and __rseq_size is still 32, > we don't know if bytes up to 32 are usable. It could be that the kernel > supports 20 bytes only. > > If __rseq_size is 32 and getauxval (AT_RSEQ_FEATURE_SIZE) is zero, the > usable part is 20 bytes long. > > If __rseq_size is 0, rseq is not supported. > > Otherwise, __rseq_size is usable size. > > We discussed this a bit during today's call, and we concluded that this > patch here may not the best possible solution. > > 1) [your patch] New __rseq_feature_size symbol: Applications using the > new logic will fail to compile on older glibc. Compiled on new > glibc, applications will fail to launch with a GLIBC_2.40 version > error. > > 2) [this patch] New symbol version for __rseq_size (same variable as > before): Compiled on new glibc, applications will fail to launch with > a GLIBC_2.40 version error. This is done because they might use the > new size semantics. But the application code specific to glibc 2.40 > will compile successfully on glibc 2.39 and earlier, and run, given > the weird results. This is not ideal. > > 3) [no patch, but similar to this patch] Treat this as a bug fix for > __rseq_size: it should have been 20 initially. No new symbol > version, but backport it 2.35 and later. Given so many distributions > use stable release branches nowadays, it is likely the fix is > available to users before they encounter rseq-using applications. > > The rules above apply to both 2) & 3). I'm leaning towards approach 3) > and would do the backports to 2.35 and later. I also prefer 3) over 2), it could still break early adopters that expect "__rseq_size >= 32" but it would most likely disable rseq usage instead of potentially using unimplemented features.
On 2024-07-08 13:06, Florian Weimer wrote: > * Michael Jeanson: > >> On 2024-07-07 10 h 37, Florian Weimer wrote: >>> It is now the active area of struct rseq (so 20 initially), not >>> the full struct size including padding at the end (32 initially). >>> Introduce a new symbol version for __rseq_area, so that >>> applications can rely on the new semantics. >>> Update misc/tst-rseq to print some additional diagnostics. >>> This replaces Michael's __rseq_feature_size patch. I prefer this >>> approach because it avoids confusion with having three different sizes >>> (__rseq_size, __rseq_feature_size, getauxval (AT_RSEQ_FEATURE_SIZE)). >>> I looked at the __rseq_size usage in CRIU, and it seems to be compatible >>> as long as the system has full ptrace support. I do not think we >>> need a compat symbol that is artificially increased to 32. We >>> can do this retroactively if necessary because there is a new symbol >>> version (so that newly linked applications can depend on the new >>> semantics). >> >> One thing I'm not sure I understand, how would I write an application >> that can be built against any glibc with the '__rseq_symbol' that can >> distinguish between the old semantic of '__rseq_size == 32' and an >> hypothetical new kernel with 32 bytes of rseq features available? > > We don't know for sure because I do not think we have reached a > getauxval (AT_RSEQ_FEATURE_SIZE) value that is larger than 28. For now, > it is reasonable to assume that if __rseq_size is 32, and getauxval > (AT_RSEQ_FEATURE_SIZE) is 28, then the usable part is 28. Correct. > But if > e.g. getauxval (AT_RSEQ_FEATURE_SIZE) is 40 and __rseq_size is still 32, > we don't know if bytes up to 32 are usable. It could be that the kernel > supports 20 bytes only. Based on the rseq system call implementation: [...] * In order to be valid, rseq_len is either the original rseq size, or * large enough to contain all supported fields, as communicated to * user-space through the ELF auxiliary vector AT_RSEQ_FEATURE_SIZE. */ if (rseq_len < ORIG_RSEQ_SIZE || (rseq_len == ORIG_RSEQ_SIZE && !IS_ALIGNED((unsigned long)rseq, ORIG_RSEQ_SIZE)) || (rseq_len != ORIG_RSEQ_SIZE && (!IS_ALIGNED((unsigned long)rseq, __alignof__(*rseq)) || rseq_len < offsetof(struct rseq, end)))) return -EINVAL; [...] current->rseq_len = rseq_len; When rseq_len=32 (ORIG_RSEQ_SIZE), it will be used as-is as current->rseq_len which is used by rseq_update_cpu_node_id() to "gate" which features are populated. I have placed a comment in this function to make sure only the fields _after_ 32 bytes will be conditionally populated: if (!user_write_access_begin(rseq, t->rseq_len)) goto efault; unsafe_put_user(cpu_id, &rseq->cpu_id_start, efault_end); unsafe_put_user(cpu_id, &rseq->cpu_id, efault_end); unsafe_put_user(node_id, &rseq->node_id, efault_end); unsafe_put_user(mm_cid, &rseq->mm_cid, efault_end); /* * Additional feature fields added after ORIG_RSEQ_SIZE * need to be conditionally updated only if * t->rseq_len != ORIG_RSEQ_SIZE. */ user_write_access_end(); This effectively ensures that the fields with offsetof(field) >= 20 && offsetofend(field) <= 32 are populated when "legacy" registration provides a rseq_len of 32. Based on the rseq(2) man page found in librseq: Structure size This structure size needs to be at least 32 bytes. It can be either 32 bytes, or it needs to be large enough to hold the re‐ sult of getauxval() invoked with AT_RSEQ_FEATURE_SIZE. Its size is passed as parameter to the rseq() system call. Arguably, I do not state clearly what happens when the rseq registration has size=32 and getauxval(AT_RSEQ_FEATURE_SIZE) returns a value larger than 32. If the kernel getauxval(AT_RSEQ_FEATURE_SIZE) returns 40, it means the kernel supports 40 bytes of feature. An application observing __rseq_size == 32 && getauxval(AT_RSEQ_FEATURE_SIZE) == 40 should be able to use the intersection of the rseq area size supported by libc and the feature fields supported by the kernel. I fully agree that I should improve the rseq documentation and man page to clarify this. > > If __rseq_size is 32 and getauxval (AT_RSEQ_FEATURE_SIZE) is zero, the > usable part is 20 bytes long. Yes. > > If __rseq_size is 0, rseq is not supported. Yes. > > Otherwise, __rseq_size is usable size. Yes. > > We discussed this a bit during today's call, and we concluded that this > patch here may not the best possible solution. > > 1) [your patch] New __rseq_feature_size symbol: Applications using the > new logic will fail to compile on older glibc. Compiled on new > glibc, applications will fail to launch with a GLIBC_2.40 version > error. > > 2) [this patch] New symbol version for __rseq_size (same variable as > before): Compiled on new glibc, applications will fail to launch with > a GLIBC_2.40 version error. This is done because they might use the > new size semantics. But the application code specific to glibc 2.40 > will compile successfully on glibc 2.39 and earlier, and run, given > the weird results. This is not ideal. Agreed. > > 3) [no patch, but similar to this patch] Treat this as a bug fix for > __rseq_size: it should have been 20 initially. No new symbol > version, but backport it 2.35 and later. Given so many distributions > use stable release branches nowadays, it is likely the fix is > available to users before they encounter rseq-using applications. > > The rules above apply to both 2) & 3). I'm leaning towards approach 3) > and would do the backports to 2.35 and later. I would also prefer approach 3. Thanks, Mathieu > > Thanks, > Florian >
> > > > > 3) [no patch, but similar to this patch] Treat this as a bug fix for > > __rseq_size: it should have been 20 initially. No new symbol > > version, but backport it 2.35 and later. Given so many distributions > > use stable release branches nowadays, it is likely the fix is > > available to users before they encounter rseq-using applications. > > > > The rules above apply to both 2) & 3). I'm leaning towards approach 3) > > and would do the backports to 2.35 and later. > > I would also prefer approach 3. > Approach 3 is technically not an ABI change, so OK at this stage. After the discussion in the meeting, the explanations in the thread here and some further reading it makes most sense to me too.
* Andreas K. Huettel: >> >> > >> > 3) [no patch, but similar to this patch] Treat this as a bug fix for >> > __rseq_size: it should have been 20 initially. No new symbol >> > version, but backport it 2.35 and later. Given so many distributions >> > use stable release branches nowadays, it is likely the fix is >> > available to users before they encounter rseq-using applications. >> > >> > The rules above apply to both 2) & 3). I'm leaning towards approach 3) >> > and would do the backports to 2.35 and later. >> >> I would also prefer approach 3. >> > > Approach 3 is technically not an ABI change, so OK at this stage. > > After the discussion in the meeting, the explanations in the thread here and > some further reading it makes most sense to me too. Great. I've posted a v2: [PATCH v2] Linux: Make __rseq_size useful for feature detection (bug 31965) <https://inbox.sourceware.org/libc-alpha/87ikxfd7d3.fsf@oldenburg.str.redhat.com/> Thanks, Florian
diff --git a/NEWS b/NEWS index f626896aa0..3824815917 100644 --- a/NEWS +++ b/NEWS @@ -49,6 +49,9 @@ Deprecated and removed features, and other changes affecting compatibility: <utmpx.h> (except for login_tty) due to locking and session management problems. +* __rseq_size now denotes the size of the active rseq area (20 bytes + initially), not the size of struct rseq (32 bytes initially). + Changes to build and runtime requirements: [Add changes to build and runtime requirements here] diff --git a/manual/threads.texi b/manual/threads.texi index e5544ff3da..25e99c9606 100644 --- a/manual/threads.texi +++ b/manual/threads.texi @@ -1007,8 +1007,12 @@ This variable is either zero (if restartable sequence registration failed or has been disabled) or the size of the restartable sequence registration. This can be different from the size of @code{struct rseq} if the kernel has extended the size of the registration. If -registration is successful, @code{__rseq_size} is at least 32 (the -initial size of @code{struct rseq}). +registration is successful, @code{__rseq_size} is at least 20 (the +initially active size of @code{struct rseq}). + +Previous versions of @theglibc{} set this to 32 even if the kernel only +supported the initial area of 20 bytes because the value included unused +padding at the end of the restartable sequence area. @end deftypevar @deftypevar {unsigned int} __rseq_flags diff --git a/sysdeps/nptl/dl-tls_init_tp.c b/sysdeps/nptl/dl-tls_init_tp.c index 7eb35fb133..7803e19fd1 100644 --- a/sysdeps/nptl/dl-tls_init_tp.c +++ b/sysdeps/nptl/dl-tls_init_tp.c @@ -46,10 +46,6 @@ rtld_mutex_dummy (pthread_mutex_t *lock) const unsigned int __rseq_flags; -/* The variables are in .data.relro but are not yet write-protected. */ -extern unsigned int _rseq_size attribute_hidden; -extern ptrdiff_t _rseq_offset attribute_hidden; - void __tls_pre_init_tp (void) { @@ -106,9 +102,7 @@ __tls_init_tp (void) bool do_rseq = true; do_rseq = TUNABLE_GET (rseq, int, NULL); if (rseq_register_current_thread (pd, do_rseq)) - { - _rseq_size = sizeof (pd->rseq_area); - } + _rseq_size = RSEQ_AREA_SIZE_INITIAL_USED; #ifdef RSEQ_SIG /* This should be a compile-time constant, but the current diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions index 268ba1b6ac..e3b232db92 100644 --- a/sysdeps/unix/sysv/linux/Versions +++ b/sysdeps/unix/sysv/linux/Versions @@ -356,6 +356,9 @@ ld { __rseq_offset; __rseq_size; } + GLIBC_2.40 { + __rseq_size; + } GLIBC_PRIVATE { __nptl_change_stack_perm; } diff --git a/sysdeps/unix/sysv/linux/aarch64/ld.abilist b/sysdeps/unix/sysv/linux/aarch64/ld.abilist index 5151c0781d..04efaa1e4f 100644 --- a/sysdeps/unix/sysv/linux/aarch64/ld.abilist +++ b/sysdeps/unix/sysv/linux/aarch64/ld.abilist @@ -7,3 +7,4 @@ GLIBC_2.34 __rtld_version_placeholder F GLIBC_2.35 __rseq_flags D 0x4 GLIBC_2.35 __rseq_offset D 0x8 GLIBC_2.35 __rseq_size D 0x4 +GLIBC_2.40 __rseq_size D 0x4 diff --git a/sysdeps/unix/sysv/linux/alpha/ld.abilist b/sysdeps/unix/sysv/linux/alpha/ld.abilist index 3e296c5473..9103538e04 100644 --- a/sysdeps/unix/sysv/linux/alpha/ld.abilist +++ b/sysdeps/unix/sysv/linux/alpha/ld.abilist @@ -7,3 +7,4 @@ GLIBC_2.35 __rseq_flags D 0x4 GLIBC_2.35 __rseq_offset D 0x8 GLIBC_2.35 __rseq_size D 0x4 GLIBC_2.4 __stack_chk_guard D 0x8 +GLIBC_2.40 __rseq_size D 0x4 diff --git a/sysdeps/unix/sysv/linux/arc/ld.abilist b/sysdeps/unix/sysv/linux/arc/ld.abilist index 55f0c2ab9c..031a0b5e33 100644 --- a/sysdeps/unix/sysv/linux/arc/ld.abilist +++ b/sysdeps/unix/sysv/linux/arc/ld.abilist @@ -7,3 +7,4 @@ GLIBC_2.34 __rtld_version_placeholder F GLIBC_2.35 __rseq_flags D 0x4 GLIBC_2.35 __rseq_offset D 0x4 GLIBC_2.35 __rseq_size D 0x4 +GLIBC_2.40 __rseq_size D 0x4 diff --git a/sysdeps/unix/sysv/linux/arm/be/ld.abilist b/sysdeps/unix/sysv/linux/arm/be/ld.abilist index f1da2c636d..4ee96084c1 100644 --- a/sysdeps/unix/sysv/linux/arm/be/ld.abilist +++ b/sysdeps/unix/sysv/linux/arm/be/ld.abilist @@ -7,3 +7,4 @@ GLIBC_2.4 __stack_chk_guard D 0x4 GLIBC_2.4 __tls_get_addr F GLIBC_2.4 _dl_mcount F GLIBC_2.4 _r_debug D 0x14 +GLIBC_2.40 __rseq_size D 0x4 diff --git a/sysdeps/unix/sysv/linux/arm/le/ld.abilist b/sysdeps/unix/sysv/linux/arm/le/ld.abilist index f1da2c636d..4ee96084c1 100644 --- a/sysdeps/unix/sysv/linux/arm/le/ld.abilist +++ b/sysdeps/unix/sysv/linux/arm/le/ld.abilist @@ -7,3 +7,4 @@ GLIBC_2.4 __stack_chk_guard D 0x4 GLIBC_2.4 __tls_get_addr F GLIBC_2.4 _dl_mcount F GLIBC_2.4 _r_debug D 0x14 +GLIBC_2.40 __rseq_size D 0x4 diff --git a/sysdeps/unix/sysv/linux/csky/ld.abilist b/sysdeps/unix/sysv/linux/csky/ld.abilist index 7f482276ed..ac51f7ca61 100644 --- a/sysdeps/unix/sysv/linux/csky/ld.abilist +++ b/sysdeps/unix/sysv/linux/csky/ld.abilist @@ -7,3 +7,4 @@ GLIBC_2.34 __rtld_version_placeholder F GLIBC_2.35 __rseq_flags D 0x4 GLIBC_2.35 __rseq_offset D 0x4 GLIBC_2.35 __rseq_size D 0x4 +GLIBC_2.40 __rseq_size D 0x4 diff --git a/sysdeps/unix/sysv/linux/dl-rseq-symbols.S b/sysdeps/unix/sysv/linux/dl-rseq-symbols.S index b4bba06a99..2155a79e02 100644 --- a/sysdeps/unix/sysv/linux/dl-rseq-symbols.S +++ b/sysdeps/unix/sysv/linux/dl-rseq-symbols.S @@ -17,6 +17,7 @@ <https://www.gnu.org/licenses/>. */ #include <sysdep.h> +#include <shlib-compat.h> #if __WORDSIZE == 64 #define RSEQ_OFFSET_SIZE 8 @@ -32,18 +33,34 @@ dynamic linker which will initialize the value both symbols point to before copy relocations take place. */ - .globl __rseq_size - .type __rseq_size, %object - .size __rseq_size, 4 .hidden _rseq_size .globl _rseq_size .type _rseq_size, %object .size _rseq_size, 4 +#ifdef SHARED + .globl __rseq_size_original + .type __rseq_size_original, %object + .size __rseq_size_original, 4 + .globl __rseq_size_current + .type __rseq_size_current, %object + .size __rseq_size_current, 4 +#else + .globl __rseq_size + .type __rseq_size, %object + .size __rseq_size, 4 +#endif .section .data.rel.ro .balign 4 __rseq_size: +__rseq_size_original: +__rseq_size_current: _rseq_size: .zero 4 +#ifdef SHARED +/* Ensure that new binaries get the new __rseq_size semantics. */ +compat_symbol (ld, __rseq_size_original, __rseq_size, GLIBC_2_35) +versioned_symbol (ld, __rseq_size_current, __rseq_size, GLIBC_2_40) +#endif /* Define 2 symbols: '__rseq_offset' is public const and '_rseq_offset' (an alias of '__rseq_offset') is hidden and writable for internal use by the diff --git a/sysdeps/unix/sysv/linux/hppa/ld.abilist b/sysdeps/unix/sysv/linux/hppa/ld.abilist index 7f5527fb30..a23ea40dff 100644 --- a/sysdeps/unix/sysv/linux/hppa/ld.abilist +++ b/sysdeps/unix/sysv/linux/hppa/ld.abilist @@ -7,3 +7,4 @@ GLIBC_2.35 __rseq_flags D 0x4 GLIBC_2.35 __rseq_offset D 0x4 GLIBC_2.35 __rseq_size D 0x4 GLIBC_2.4 __stack_chk_guard D 0x4 +GLIBC_2.40 __rseq_size D 0x4 diff --git a/sysdeps/unix/sysv/linux/i386/ld.abilist b/sysdeps/unix/sysv/linux/i386/ld.abilist index 9c4a45d8dc..6041d6473c 100644 --- a/sysdeps/unix/sysv/linux/i386/ld.abilist +++ b/sysdeps/unix/sysv/linux/i386/ld.abilist @@ -7,3 +7,4 @@ GLIBC_2.34 __rtld_version_placeholder F GLIBC_2.35 __rseq_flags D 0x4 GLIBC_2.35 __rseq_offset D 0x4 GLIBC_2.35 __rseq_size D 0x4 +GLIBC_2.40 __rseq_size D 0x4 diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/ld.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/ld.abilist index 93fcd64eee..bf7fb6b1fd 100644 --- a/sysdeps/unix/sysv/linux/loongarch/lp64/ld.abilist +++ b/sysdeps/unix/sysv/linux/loongarch/lp64/ld.abilist @@ -6,3 +6,4 @@ GLIBC_2.36 __stack_chk_guard D 0x8 GLIBC_2.36 __tls_get_addr F GLIBC_2.36 _dl_mcount F GLIBC_2.36 _r_debug D 0x28 +GLIBC_2.40 __rseq_size D 0x4 diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/ld.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/ld.abilist index f1da2c636d..4ee96084c1 100644 --- a/sysdeps/unix/sysv/linux/m68k/coldfire/ld.abilist +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/ld.abilist @@ -7,3 +7,4 @@ GLIBC_2.4 __stack_chk_guard D 0x4 GLIBC_2.4 __tls_get_addr F GLIBC_2.4 _dl_mcount F GLIBC_2.4 _r_debug D 0x14 +GLIBC_2.40 __rseq_size D 0x4 diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/ld.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/ld.abilist index dadbf852d0..526c0d5fba 100644 --- a/sysdeps/unix/sysv/linux/m68k/m680x0/ld.abilist +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/ld.abilist @@ -7,3 +7,4 @@ GLIBC_2.35 __rseq_flags D 0x4 GLIBC_2.35 __rseq_offset D 0x4 GLIBC_2.35 __rseq_size D 0x4 GLIBC_2.4 __stack_chk_guard D 0x4 +GLIBC_2.40 __rseq_size D 0x4 diff --git a/sysdeps/unix/sysv/linux/microblaze/ld.abilist b/sysdeps/unix/sysv/linux/microblaze/ld.abilist index 89a0b7e4fd..e57cec648d 100644 --- a/sysdeps/unix/sysv/linux/microblaze/ld.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/ld.abilist @@ -7,3 +7,4 @@ GLIBC_2.34 __rtld_version_placeholder F GLIBC_2.35 __rseq_flags D 0x4 GLIBC_2.35 __rseq_offset D 0x4 GLIBC_2.35 __rseq_size D 0x4 +GLIBC_2.40 __rseq_size D 0x4 diff --git a/sysdeps/unix/sysv/linux/mips/mips32/ld.abilist b/sysdeps/unix/sysv/linux/mips/mips32/ld.abilist index e304d1bb46..9033f384d5 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/ld.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/ld.abilist @@ -7,3 +7,4 @@ GLIBC_2.35 __rseq_flags D 0x4 GLIBC_2.35 __rseq_offset D 0x4 GLIBC_2.35 __rseq_size D 0x4 GLIBC_2.4 __stack_chk_guard D 0x4 +GLIBC_2.40 __rseq_size D 0x4 diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/ld.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/ld.abilist index e304d1bb46..9033f384d5 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/ld.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/ld.abilist @@ -7,3 +7,4 @@ GLIBC_2.35 __rseq_flags D 0x4 GLIBC_2.35 __rseq_offset D 0x4 GLIBC_2.35 __rseq_size D 0x4 GLIBC_2.4 __stack_chk_guard D 0x4 +GLIBC_2.40 __rseq_size D 0x4 diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/ld.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/ld.abilist index f26e594a13..bf037e137a 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/ld.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/ld.abilist @@ -7,3 +7,4 @@ GLIBC_2.35 __rseq_flags D 0x4 GLIBC_2.35 __rseq_offset D 0x8 GLIBC_2.35 __rseq_size D 0x4 GLIBC_2.4 __stack_chk_guard D 0x8 +GLIBC_2.40 __rseq_size D 0x4 diff --git a/sysdeps/unix/sysv/linux/nios2/ld.abilist b/sysdeps/unix/sysv/linux/nios2/ld.abilist index 811ae9da2f..127829e91c 100644 --- a/sysdeps/unix/sysv/linux/nios2/ld.abilist +++ b/sysdeps/unix/sysv/linux/nios2/ld.abilist @@ -7,3 +7,4 @@ GLIBC_2.34 __rtld_version_placeholder F GLIBC_2.35 __rseq_flags D 0x4 GLIBC_2.35 __rseq_offset D 0x4 GLIBC_2.35 __rseq_size D 0x4 +GLIBC_2.40 __rseq_size D 0x4 diff --git a/sysdeps/unix/sysv/linux/or1k/ld.abilist b/sysdeps/unix/sysv/linux/or1k/ld.abilist index cff2ffd23b..55baff19f3 100644 --- a/sysdeps/unix/sysv/linux/or1k/ld.abilist +++ b/sysdeps/unix/sysv/linux/or1k/ld.abilist @@ -6,3 +6,4 @@ GLIBC_2.35 __stack_chk_guard D 0x4 GLIBC_2.35 __tls_get_addr F GLIBC_2.35 _dl_mcount F GLIBC_2.35 _r_debug D 0x14 +GLIBC_2.40 __rseq_size D 0x4 diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/ld.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/ld.abilist index b1073f0942..46b193e2ef 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/ld.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/ld.abilist @@ -9,3 +9,4 @@ GLIBC_2.35 __rseq_flags D 0x4 GLIBC_2.35 __rseq_offset D 0x4 GLIBC_2.35 __rseq_size D 0x4 GLIBC_2.39 __parse_hwcap_3_4_and_convert_at_platform F +GLIBC_2.40 __rseq_size D 0x4 diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/ld.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/ld.abilist index 40942a2cc6..e8a9859d9a 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/ld.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/ld.abilist @@ -9,3 +9,4 @@ GLIBC_2.35 __rseq_flags D 0x4 GLIBC_2.35 __rseq_offset D 0x8 GLIBC_2.35 __rseq_size D 0x4 GLIBC_2.39 __parse_hwcap_3_4_and_convert_at_platform F +GLIBC_2.40 __rseq_size D 0x4 diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/ld.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/ld.abilist index 01f2694a4d..e57d8e3331 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/ld.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/ld.abilist @@ -9,3 +9,4 @@ GLIBC_2.35 __rseq_flags D 0x4 GLIBC_2.35 __rseq_offset D 0x8 GLIBC_2.35 __rseq_size D 0x4 GLIBC_2.39 __parse_hwcap_3_4_and_convert_at_platform F +GLIBC_2.40 __rseq_size D 0x4 diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/ld.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/ld.abilist index 068368878e..d9e51f124c 100644 --- a/sysdeps/unix/sysv/linux/riscv/rv32/ld.abilist +++ b/sysdeps/unix/sysv/linux/riscv/rv32/ld.abilist @@ -7,3 +7,4 @@ GLIBC_2.34 __rtld_version_placeholder F GLIBC_2.35 __rseq_flags D 0x4 GLIBC_2.35 __rseq_offset D 0x4 GLIBC_2.35 __rseq_size D 0x4 +GLIBC_2.40 __rseq_size D 0x4 diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/ld.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/ld.abilist index a7758a0e52..ff2294932c 100644 --- a/sysdeps/unix/sysv/linux/riscv/rv64/ld.abilist +++ b/sysdeps/unix/sysv/linux/riscv/rv64/ld.abilist @@ -7,3 +7,4 @@ GLIBC_2.34 __rtld_version_placeholder F GLIBC_2.35 __rseq_flags D 0x4 GLIBC_2.35 __rseq_offset D 0x8 GLIBC_2.35 __rseq_size D 0x4 +GLIBC_2.40 __rseq_size D 0x4 diff --git a/sysdeps/unix/sysv/linux/rseq-internal.h b/sysdeps/unix/sysv/linux/rseq-internal.h index 48eebc1e16..7ea935b4ad 100644 --- a/sysdeps/unix/sysv/linux/rseq-internal.h +++ b/sysdeps/unix/sysv/linux/rseq-internal.h @@ -25,15 +25,34 @@ #include <stdio.h> #include <sys/rseq.h> +/* 32 is the initially required value for the area size. The + actually used rseq size may be less (20 bytes initially). */ +#define RSEQ_AREA_SIZE_INITIAL 32 +#define RSEQ_AREA_SIZE_INITIAL_USED 20 + +/* The variables are in .data.relro but are not yet write-protected. */ +extern unsigned int _rseq_size attribute_hidden; +extern ptrdiff_t _rseq_offset attribute_hidden; + #ifdef RSEQ_SIG static inline bool rseq_register_current_thread (struct pthread *self, bool do_rseq) { if (do_rseq) { + unsigned int size; +#if IS_IN (rtld) + /* Use the hidden symbol in ld.so. */ + size = _rseq_size; +#else + size = __rseq_size; +#endif + if (size < RSEQ_AREA_SIZE_INITIAL) + /* The initial implementation used only 20 bytes out of 32, + but still expected size 32. */ + size = RSEQ_AREA_SIZE_INITIAL; int ret = INTERNAL_SYSCALL_CALL (rseq, &self->rseq_area, - sizeof (self->rseq_area), - 0, RSEQ_SIG); + size, 0, RSEQ_SIG); if (!INTERNAL_SYSCALL_ERROR_P (ret)) return true; } diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/ld.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/ld.abilist index c15288394a..b8b8e0dd30 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/ld.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-32/ld.abilist @@ -6,3 +6,4 @@ GLIBC_2.34 __rtld_version_placeholder F GLIBC_2.35 __rseq_flags D 0x4 GLIBC_2.35 __rseq_offset D 0x4 GLIBC_2.35 __rseq_size D 0x4 +GLIBC_2.40 __rseq_size D 0x4 diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/ld.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/ld.abilist index 78d071600b..b436ecbdf5 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/ld.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-64/ld.abilist @@ -6,3 +6,4 @@ GLIBC_2.34 __rtld_version_placeholder F GLIBC_2.35 __rseq_flags D 0x4 GLIBC_2.35 __rseq_offset D 0x8 GLIBC_2.35 __rseq_size D 0x4 +GLIBC_2.40 __rseq_size D 0x4 diff --git a/sysdeps/unix/sysv/linux/sh/be/ld.abilist b/sysdeps/unix/sysv/linux/sh/be/ld.abilist index 7f5527fb30..a23ea40dff 100644 --- a/sysdeps/unix/sysv/linux/sh/be/ld.abilist +++ b/sysdeps/unix/sysv/linux/sh/be/ld.abilist @@ -7,3 +7,4 @@ GLIBC_2.35 __rseq_flags D 0x4 GLIBC_2.35 __rseq_offset D 0x4 GLIBC_2.35 __rseq_size D 0x4 GLIBC_2.4 __stack_chk_guard D 0x4 +GLIBC_2.40 __rseq_size D 0x4 diff --git a/sysdeps/unix/sysv/linux/sh/le/ld.abilist b/sysdeps/unix/sysv/linux/sh/le/ld.abilist index 7f5527fb30..a23ea40dff 100644 --- a/sysdeps/unix/sysv/linux/sh/le/ld.abilist +++ b/sysdeps/unix/sysv/linux/sh/le/ld.abilist @@ -7,3 +7,4 @@ GLIBC_2.35 __rseq_flags D 0x4 GLIBC_2.35 __rseq_offset D 0x4 GLIBC_2.35 __rseq_size D 0x4 GLIBC_2.4 __stack_chk_guard D 0x4 +GLIBC_2.40 __rseq_size D 0x4 diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/ld.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/ld.abilist index 3aac73f3df..1ea464b376 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/ld.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/ld.abilist @@ -6,3 +6,4 @@ GLIBC_2.34 __rtld_version_placeholder F GLIBC_2.35 __rseq_flags D 0x4 GLIBC_2.35 __rseq_offset D 0x4 GLIBC_2.35 __rseq_size D 0x4 +GLIBC_2.40 __rseq_size D 0x4 diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/ld.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/ld.abilist index 5471b24d59..94ff921440 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/ld.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/ld.abilist @@ -6,3 +6,4 @@ GLIBC_2.34 __rtld_version_placeholder F GLIBC_2.35 __rseq_flags D 0x4 GLIBC_2.35 __rseq_offset D 0x8 GLIBC_2.35 __rseq_size D 0x4 +GLIBC_2.40 __rseq_size D 0x4 diff --git a/sysdeps/unix/sysv/linux/tst-rseq.c b/sysdeps/unix/sysv/linux/tst-rseq.c index 2c90409ba0..08a9533130 100644 --- a/sysdeps/unix/sysv/linux/tst-rseq.c +++ b/sysdeps/unix/sysv/linux/tst-rseq.c @@ -29,6 +29,7 @@ # include <stdlib.h> # include <string.h> # include <syscall.h> +# include <sys/auxv.h> # include <thread_pointer.h> # include <tls.h> # include "tst-rseq.h" @@ -42,7 +43,8 @@ do_rseq_main_test (void) TEST_COMPARE (__rseq_flags, 0); TEST_VERIFY ((char *) __thread_pointer () + __rseq_offset == (char *) &pd->rseq_area); - TEST_COMPARE (__rseq_size, sizeof (pd->rseq_area)); + /* The current implementation only supports the initial size. */ + TEST_COMPARE (__rseq_size, 20); } static void @@ -52,6 +54,12 @@ do_rseq_test (void) { FAIL_UNSUPPORTED ("kernel does not support rseq, skipping test"); } + printf ("info: __rseq_size: %u\n", __rseq_size); + printf ("info: __rseq_offset: %td\n", __rseq_offset); + printf ("info: __rseq_flags: %u\n", __rseq_flags); + printf ("info: getauxval (AT_RSEQ_FEATURE_SIZE): %ld\n", + getauxval (AT_RSEQ_FEATURE_SIZE)); + printf ("info: getauxval (AT_RSEQ_ALIGN): %ld\n", getauxval (AT_RSEQ_ALIGN)); do_rseq_main_test (); } #else /* RSEQ_SIG */ diff --git a/sysdeps/unix/sysv/linux/x86_64/64/ld.abilist b/sysdeps/unix/sysv/linux/x86_64/64/ld.abilist index 5a8bd322cd..171b38a2b9 100644 --- a/sysdeps/unix/sysv/linux/x86_64/64/ld.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/64/ld.abilist @@ -6,3 +6,4 @@ GLIBC_2.34 __rtld_version_placeholder F GLIBC_2.35 __rseq_flags D 0x4 GLIBC_2.35 __rseq_offset D 0x8 GLIBC_2.35 __rseq_size D 0x4 +GLIBC_2.40 __rseq_size D 0x4 diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/ld.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/ld.abilist index e17496d124..0a18a6c2d6 100644 --- a/sysdeps/unix/sysv/linux/x86_64/x32/ld.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/x32/ld.abilist @@ -6,3 +6,4 @@ GLIBC_2.34 __rtld_version_placeholder F GLIBC_2.35 __rseq_flags D 0x4 GLIBC_2.35 __rseq_offset D 0x4 GLIBC_2.35 __rseq_size D 0x4 +GLIBC_2.40 __rseq_size D 0x4