Bug 15794

Summary: move AT_* constants definition from elf.h into sysdeps (bits) directory
Product: glibc Reporter: Petr.Salinger
Component: libcAssignee: Not yet assigned to anyone <unassigned>
Status: NEW ---    
Severity: normal CC: adconrad, bugdal, drepper.fsp
Priority: P2 Flags: fweimer: security-
Version: unspecified   
Target Milestone: ---   
Host: Target:
Build: Last reconfirmed:
Attachments: proposed patch
v2

Description Petr.Salinger 2013-07-27 08:20:58 UTC
Created attachment 7124 [details]
proposed patch

Currently the installed <elf.h> contains many Linux specific AT_* constants.
Especially with introduction of getauxval() it would be handy to allow overriding them.

Please move this into separate bits header <bits/auxv.h>.

At least the FreeBSD kernel uses a different set.
See http://svnweb.freebsd.org/base/head/sys/x86/include/elf.h

And I doubt hurd also provides all of them.
Comment 1 Ondrej Bilka 2013-07-27 09:35:44 UTC
> 
> Currently the installed <elf.h> contains many Linux specific AT_* constants.
> Especially with introduction of getauxval() it would be handy to allow
> overriding them.
> 
> Please move this into separate bits header <bits/auxv.h>.
> 
> At least the FreeBSD kernel uses a different set.
> See http://svnweb.freebsd.org/base/head/sys/x86/include/elf.h
> 
> And I doubt hurd also provides all of them.
> 
As this is patch please send it to libc-alpha@sourceware.org to get
comments there.
Comment 2 jsm-csl@polyomino.org.uk 2013-07-27 20:22:48 UTC
The installed <elf.h> header is supposed to be system-independent; it 
contains a definition of ELF not just for the system for which glibc is 
built, but for other systems as well.  So it would be appropriate to add 
constants for other OSes, and to rename constants if their names 
misleadingly suggest they are OS-independent, but not to make the set of 
constants or their values depend on the system for which glibc is built.
Comment 3 Petr.Salinger 2013-07-28 06:19:03 UTC
I would rather consider the AT_* constants as constants in errno.h
There is a common base, with the same numbers (0-9).
But there are also some constants with same meaning and different numbers
and constants with same number but completely different meaning.

The original problem is
http://bugs.debian.org//cgi-bin/bugreport.cgi?bug=717912


https://git.kernel.org/cgit/linux/kernel/git/next/linux-next.git/tree/include/uapi/linux/auxvec.h

#define AT_NULL   0	/* end of vector */
#define AT_IGNORE 1	/* entry should be ignored */
#define AT_EXECFD 2	/* file descriptor of program */
#define AT_PHDR   3	/* program headers for program */
#define AT_PHENT  4	/* size of program header entry */
#define AT_PHNUM  5	/* number of program headers */
#define AT_PAGESZ 6	/* system page size */
#define AT_BASE   7	/* base address of interpreter */
#define AT_FLAGS  8	/* flags */
#define AT_ENTRY  9	/* entry point of program */
#define AT_NOTELF 10	/* program is not ELF */
#define AT_UID    11	/* real uid */
#define AT_EUID   12	/* effective uid */
#define AT_GID    13	/* real gid */
#define AT_EGID   14	/* effective gid */
#define AT_PLATFORM 15  /* string identifying CPU for optimizations */
#define AT_HWCAP  16    /* arch dependent hints at CPU capabilities */
#define AT_CLKTCK 17	/* frequency at which times() increments */
/* AT_* values 18 through 22 are reserved */
#define AT_SECURE 23   /* secure mode boolean */
#define AT_BASE_PLATFORM 24	/* string identifying real platform, may
				 * differ from AT_PLATFORM. */
#define AT_RANDOM 25	/* address of 16 random bytes */
#define AT_HWCAP2 26	/* extension of AT_HWCAP */

#define AT_EXECFN  31	/* filename of program */


http://svnweb.freebsd.org/base/head/sys/x86/include/elf.h:
/* Values for a_type. */
#define	AT_NULL		0	/* Terminates the vector. */
#define	AT_IGNORE	1	/* Ignored entry. */
#define	AT_EXECFD	2	/* File descriptor of program to load. */
#define	AT_PHDR		3	/* Program header of program already loaded. */
#define	AT_PHENT	4	/* Size of each program header entry. */
#define	AT_PHNUM	5	/* Number of program header entries. */
#define	AT_PAGESZ	6	/* Page size in bytes. */
#define	AT_BASE		7	/* Interpreter's base address. */
#define	AT_FLAGS	8	/* Flags (unused for i386). */
#define	AT_ENTRY	9	/* Where interpreter should transfer control. */
#define	AT_NOTELF	10	/* Program is not ELF ?? */
#define	AT_UID		11	/* Real uid. */
#define	AT_EUID		12	/* Effective uid. */
#define	AT_GID		13	/* Real gid. */
#define	AT_EGID		14	/* Effective gid. */
#define	AT_EXECPATH	15	/* Path to the executable. */
#define	AT_CANARY	16	/* Canary for SSP. */
#define	AT_CANARYLEN	17	/* Length of the canary. */
#define	AT_OSRELDATE	18	/* OSRELDATE. */
#define	AT_NCPUS	19	/* Number of CPUs. */
#define	AT_PAGESIZES	20	/* Pagesizes. */
#define	AT_PAGESIZESLEN	21	/* Number of pagesizes. */
#define	AT_TIMEKEEP	22	/* Pointer to timehands. */
#define	AT_STACKPROT	23	/* Initial stack protection. */



http://www.openbsd.org/cgi-bin/cvsweb/src/sys/sys/exec_elf.h
enum AuxID {
	AUX_null = 0,
	AUX_ignore = 1,
	AUX_execfd = 2,
	AUX_phdr = 3,			/* &phdr[0] */
	AUX_phent = 4,			/* sizeof(phdr[0]) */
	AUX_phnum = 5,			/* # phdr entries */
	AUX_pagesz = 6,			/* PAGESIZE */
	AUX_base = 7,			/* ld.so base addr */
	AUX_flags = 8,			/* processor flags */
	AUX_entry = 9,			/* a.out entry */
	AUX_sun_uid = 2000,		/* euid */
	AUX_sun_ruid = 2001,		/* ruid */
	AUX_sun_gid = 2002,		/* egid */
	AUX_sun_rgid = 2003		/* rgid */
};

http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/sys/exec_elf.h
/* a_type */
#define AT_NULL		0	/* Marks end of array */
#define AT_IGNORE	1	/* No meaning, a_un is undefined */
#define AT_EXECFD	2	/* Open file descriptor of object file */
#define AT_PHDR		3	/* &phdr[0] */
#define AT_PHENT	4	/* sizeof(phdr[0]) */
#define AT_PHNUM	5	/* # phdr entries */
#define AT_PAGESZ	6	/* PAGESIZE */
#define AT_BASE		7	/* Interpreter base addr */
#define AT_FLAGS	8	/* Processor flags */
#define AT_ENTRY	9	/* Entry address of executable */
#define AT_DCACHEBSIZE	10	/* Data cache block size */
#define AT_ICACHEBSIZE	11	/* Instruction cache block size */
#define AT_UCACHEBSIZE	12	/* Unified cache block size */
#define AT_STACKBASE	13	/* Base address of the main thread */

	/* Vendor specific */
#define AT_MIPS_NOTELF	10	/* XXX a_val != 0 -> MIPS XCOFF executable */

#define AT_EUID		2000	/* euid (solaris compatible numbers) */
#define AT_RUID		2001	/* ruid (solaris compatible numbers) */
#define AT_EGID		2002	/* egid (solaris compatible numbers) */
#define AT_RGID		2003	/* rgid (solaris compatible numbers) */

	/* Solaris kernel specific */
#define AT_SUN_LDELF	2004	/* dynamic linker's ELF header */
#define AT_SUN_LDSHDR	2005	/* dynamic linker's section header */
#define AT_SUN_LDNAME	2006	/* dynamic linker's name */
#define AT_SUN_LPGSIZE	2007	/* large pagesize */

	/* Other information */
#define AT_SUN_PLATFORM 2008	/* sysinfo(SI_PLATFORM) */
#define AT_SUN_HWCAP	2009	/* process hardware capabilities */
#define AT_SUN_IFLUSH	2010	/* do we need to flush the instruction cache? */
#define AT_SUN_CPU	2011	/* CPU name */
	/* ibcs2 emulation band aid */
#define AT_SUN_EMUL_ENTRY 2012	/* coff entry point */
#define AT_SUN_EMUL_EXECFD 2013 /* coff file descriptor */
	/* Executable's fully resolved name */
#define AT_SUN_EXECNAME 2014
Comment 4 jsm-csl@polyomino.org.uk 2013-07-28 17:12:14 UTC
If a value is considered like errno.h, it shouldn't be included in elf.h, 
directly or indirectly, at all, as elf.h should be equally usable for 
cross tools as for native ones.
Comment 5 Petr.Salinger 2013-07-29 07:28:33 UTC
Created attachment 7125 [details]
v2
Comment 6 Petr.Salinger 2013-07-29 07:32:09 UTC
In v2 patch AT_* constants are moved from <elf.h> into <bits/auxv.h>,
this new bits header is included from <sys/auxv.h> for userspace usage
and from ldsodefs.h for ld.so build.
Comment 7 Adam Conrad 2013-11-25 19:44:28 UTC
The problem with this patch is that any code that previously included elf.h to get the AT_ defines is now broken (*cough*GCC*cough*).  Are you expecting that any such code should have an include <sys/auxv.h>, or should elf.h be pulling in bits/auxv.h for backward compat?
Comment 8 Adam Conrad 2013-11-25 20:03:48 UTC
Of note, it seems that on (at least) Solaris, the AT_ defines come from sys/auxv.h, not elf.h, so there's some precedent here for moving them, and perhaps not much code would break.

(The GCC example I gave above is exactly one file in one arch backend, so a trivial patch to fix).
Comment 9 Carlos O'Donell 2013-11-25 20:58:09 UTC
(In reply to Adam Conrad from comment #7)
> The problem with this patch is that any code that previously included elf.h
> to get the AT_ defines is now broken (*cough*GCC*cough*).  Are you expecting
> that any such code should have an include <sys/auxv.h>, or should elf.h be
> pulling in bits/auxv.h for backward compat?

In my opinion the best way forward is:

(a) Move AT_NULL to AT_ENTRY into sysdeps/generic/bits/auvx-base.h, and document that these 10 entries are os-independent.

(b) Move all other AT_* entries into sysdeps/unix/sysv/linux/bits/auxv.h. Have bits/auxv.h include bits/auxv-base.h first. Other OSs can override with their own bits/auxv.h.

(c) Have elf.h include bits/auxv-base.h (not bits/auxv.h) to provide the os-independent auxv constants. This should prevent some source breakage and allow the continued use of AT_NULL to AT_ENTRY Which appear to be the only set of truly os-independent AT_* constants.

(d) Have sys/auxv.h include bits/auxv.h to make all AT_* constants available for use with getauxval().

(e) Post those patches to libc-alpha for review, and make sure that you have gcc, binutils, and gdb patches ready if the changes for (a), (b), and (c) break any of the core toolchain components.

Once you get consensus from glibc it's easier to go to the other projects and post patches. If a project uses a constant outside of the general os-independent range (values 0-10) then you'll need a configure check to determine if you need to include sys/auxv.h or not. It's probably sufficient to detect if auxv.h is present, and if it is include it after including elf.h. So you can crib up a configure check for that and use it for all projects that need a fix (some of which might already have such a check).
Comment 10 Adam Conrad 2013-11-25 21:34:00 UTC
(In reply to Carlos O'Donell from comment #9)
> (c) Have elf.h include bits/auxv-base.h (not bits/auxv.h) to provide the
> os-independent auxv constants. This should prevent some source breakage and
> allow the continued use of AT_NULL to AT_ENTRY Which appear to be the only
> set of truly os-independent AT_* constants.

This would fix the one gcc issue I found with elf.h no longer including these definitions.  I can scrub binutils, but given that it defines a lot of these bits independently anyway, I imagine it'll be in good shape too.

Random userspace packages might explode here and there, but these will all be build failures, not runtime, and we can easily weed them out in an archive rebuild test in Debian or Ubuntu and push patches upstream for the rather tiny set of sources that I expect will be affected by suddenly needing sys/auxv.h.
Comment 11 Adam Conrad 2013-11-26 16:26:27 UTC
Another point to ponder, sys/auxv.h has only existed on glibc systems since 2.16, so we can't go unconditionally patching code to include it (as I'd originally hoped) but, indeed, need configure checks for every project that needs the AT_* defines above the first ten.  Hopefully, this is a short list, but it still feels a bit icky.
Comment 12 Rich Felker 2013-11-27 03:02:51 UTC
I think elf.h should continue to expose these constants, possibly by including sys/auxv.h or similar. There's no sense in causing gratuitous breakage.

If incompatible header changes that break applications that are currently using the headers *correctly* are acceptable in glibc, then certainly changes that only break bogus applications should be acceptable; for starters, the implicit inclusion of sys/sysmacros.h, which defines macros named major() and minor(), from nearly every standard header, should be removed.
Comment 13 Sourceware Commits 2023-05-26 15:03:49 UTC
The master branch has been updated by Joseph Myers <jsm28@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=8754a4133e154ca853e6765a3fe5c7a904c77626

commit 8754a4133e154ca853e6765a3fe5c7a904c77626
Author: Joseph Myers <joseph@codesourcery.com>
Date:   Fri May 26 15:03:31 2023 +0000

    Add AT_RSEQ_* from Linux 6.3 to elf.h
    
    Linux 6.3 adds constants AT_RSEQ_FEATURE_SIZE and AT_RSEQ_ALIGN; add
    them to glibc's elf.h.  (Recall that, although elf.h is a
    system-independent header, so far we've put AT_* constants there even
    if Linux-specific, as discussed in bug 15794.  So rather than making
    any attempt to fix that issue, the new constants are just added there
    alongside the existing ones.)
    
    Tested for x86_64.
Comment 14 Sourceware Commits 2024-07-16 17:33:04 UTC
The release/2.37/master branch has been updated by Florian Weimer <fw@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=182f4a8c7570008bcf68b10b809d39e89951c124

commit 182f4a8c7570008bcf68b10b809d39e89951c124
Author: Joseph Myers <joseph@codesourcery.com>
Date:   Fri May 26 15:03:31 2023 +0000

    Add AT_RSEQ_* from Linux 6.3 to elf.h
    
    Linux 6.3 adds constants AT_RSEQ_FEATURE_SIZE and AT_RSEQ_ALIGN; add
    them to glibc's elf.h.  (Recall that, although elf.h is a
    system-independent header, so far we've put AT_* constants there even
    if Linux-specific, as discussed in bug 15794.  So rather than making
    any attempt to fix that issue, the new constants are just added there
    alongside the existing ones.)
    
    Tested for x86_64.
    
    (cherry picked from commit 8754a4133e154ca853e6765a3fe5c7a904c77626)
Comment 15 Sourceware Commits 2024-07-16 17:33:20 UTC
The release/2.36/master branch has been updated by Florian Weimer <fw@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=61da55a07f7609ca7b6e9ef42113a53593286eda

commit 61da55a07f7609ca7b6e9ef42113a53593286eda
Author: Joseph Myers <joseph@codesourcery.com>
Date:   Fri May 26 15:03:31 2023 +0000

    Add AT_RSEQ_* from Linux 6.3 to elf.h
    
    Linux 6.3 adds constants AT_RSEQ_FEATURE_SIZE and AT_RSEQ_ALIGN; add
    them to glibc's elf.h.  (Recall that, although elf.h is a
    system-independent header, so far we've put AT_* constants there even
    if Linux-specific, as discussed in bug 15794.  So rather than making
    any attempt to fix that issue, the new constants are just added there
    alongside the existing ones.)
    
    Tested for x86_64.
    
    (cherry picked from commit 8754a4133e154ca853e6765a3fe5c7a904c77626)
Comment 16 Sourceware Commits 2024-07-16 17:46:53 UTC
The release/2.35/master branch has been updated by Florian Weimer <fw@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=602fff4efac381c263bef1f036990d5a6d51b61f

commit 602fff4efac381c263bef1f036990d5a6d51b61f
Author: Joseph Myers <joseph@codesourcery.com>
Date:   Fri May 26 15:03:31 2023 +0000

    Add AT_RSEQ_* from Linux 6.3 to elf.h
    
    Linux 6.3 adds constants AT_RSEQ_FEATURE_SIZE and AT_RSEQ_ALIGN; add
    them to glibc's elf.h.  (Recall that, although elf.h is a
    system-independent header, so far we've put AT_* constants there even
    if Linux-specific, as discussed in bug 15794.  So rather than making
    any attempt to fix that issue, the new constants are just added there
    alongside the existing ones.)
    
    Tested for x86_64.
    
    (cherry picked from commit 8754a4133e154ca853e6765a3fe5c7a904c77626)