[PATCH v2 4/4] x86: Use typeof_member style in RSEQ area access expressions

Uros Bizjak ubizjak@gmail.com
Tue Sep 30 13:11:00 GMT 2025


On Tue, Sep 30, 2025 at 2:16 PM Florian Weimer <fweimer@redhat.com> wrote:
>
> * Uros Bizjak:
>
> > Update RSEQ access macros to use `((struct rseq_area *)0)->member`
> > in _Static_assert and __typeof expressions, instead of
> > RSEQ_SELF()->member.  This adopts the typeof_member style, avoiding
> > reliance on RSEQ_SELF for compile-time expressions.
> >
> > Signed-off-by: Uros Bizjak <ubizjak@gmail.com>
> > ---
> >  sysdeps/i386/nptl/rseq-access.h       | 20 ++++++++++----------
> >  sysdeps/x86_64/64/nptl/rseq-access.h  | 24 ++++++++++++------------
> >  sysdeps/x86_64/x32/nptl/rseq-access.h | 12 ++++++------
> >  3 files changed, 28 insertions(+), 28 deletions(-)
> >
> > diff --git a/sysdeps/i386/nptl/rseq-access.h b/sysdeps/i386/nptl/rseq-access.h
> > index 753152cb58..0dd0cbb180 100644
> > --- a/sysdeps/i386/nptl/rseq-access.h
> > +++ b/sysdeps/i386/nptl/rseq-access.h
> > @@ -19,9 +19,9 @@
> >  /* Read member of the RSEQ area directly.  */
> >  #define RSEQ_GETMEM(member) \
> >    ({                                                                       \
> > -     _Static_assert (sizeof (RSEQ_SELF()->member) == 1                             \
> > -                  || sizeof (RSEQ_SELF()->member) == 4                     \
> > -                  || sizeof (RSEQ_SELF()->member) == 8,                    \
> > +     _Static_assert (sizeof (((struct rseq_area *)0)->member) == 1         \
> > +                  || sizeof (((struct rseq_area *)0)->member) == 4         \
> > +                  || sizeof (((struct rseq_area *)0)->member) == 8,        \
> >                    "size of rseq data");                                    \
> >       ((struct rseq_area __seg_gs *)__rseq_offset)->member;                 \
> >    })
>
> I think we use (struct rseq_area) {}.member in other contexts.  It
> avoids the compile-time null pointer dereference.

Actually, there are:

elf/dl-find_object.c:      element_size = sizeof ((struct
dlfo_mappings_segment) {}.objects[0])
elf/dl-find_object.c:      element_size = sizeof ((struct
dlfo_mappings_segment) {}.objects[0])

and:

argp/argp-parse.c:#define USER_BITS ((sizeof ((struct option *)0)->val
* CHAR_BIT) - GROUP_BITS)
elf/dynamic-link.h:          __typeof (((ElfW(Dyn) *) 0)->d_un.d_val)
nrelative; int lazy; }  \
elf/do-rel.h:               __typeof (((ElfW(Dyn) *) 0)->d_un.d_val) nrelative,
include/list.h:  ((type *) ((char *) (ptr) - (unsigned long) (&((type
*) 0)->member)))
intl/bindtextdom.c:# define offsetof(type,ident) ((size_t)&(((type*)0)->ident))
intl/dcigettext.c:    ((int) &((struct { char dummy1; TYPE dummy2; }
*) 0)->dummy2)
intl/dcigettext.c:# define offsetof(type,ident) ((size_t)&(((type*)0)->ident))
nptl_db/db_info.c:      offsetof (type, field), ((type *) 0)->field)
nptl_db/db_info.c:            offsetof (type, field), ((type *) 0)->field)
nptl_db/db_info.c:                     offsetof (type, field), ((type
*) 0)->field)
posix/glob.c:/* The type of ((struct dirent *) 0)->d_type is 'unsigned
char' on most
sunrpc/tst-bug22542.c:  char name [sizeof ((struct
sockaddr_un*)0)->sun_path * 2];
sysdeps/x86_64/locale-defines.sym:SIZEOF_VALUES                 sizeof
(((struct __locale_data *) 0)->values[0])
sysdeps/i386/i686/multiarch/locale-defines.sym:SIZEOF_VALUES
         sizeof (((struct __locale_data *) 0)->values[0])
sysdeps/aarch64/dl-irel.h:#define sizeof_field(TYPE, MEMBER) sizeof
((((TYPE *)0)->MEMBER))
sysdeps/powerpc/locale-defines.sym:SIZEOF_VALUES                sizeof
(((struct __locale_data *) 0)->values[0])
sysdeps/unix/sysv/linux/clone-internal.c:#define sizeof_field(TYPE,
MEMBER) sizeof ((((TYPE *)0)->MEMBER))
sysdeps/unix/sysv/linux/x86/longjmp.c:                    + sizeof
(((struct pthread_unwind_buf *) 0)->priv))
sysdeps/unix/sysv/linux/x86_64/allocate-shadow-stack.h:typedef
__typeof (((ucontext_t *) 0)->__ssp[0]) shadow_stack_size_t;

However, the latter is never actually evaluated at runtime (otherwise
it would deref NULL and crash). It is even used in the definition of
offsetof ().

That said, using sizeof_member() utility function would indeed look
less scary ;)

Thanks,
Uros.


More information about the Libc-alpha mailing list