linux(4): Don't relie on process osreldata when testing features

The ELF note identifyies the operating-system ABI that the executable
was created for. The note data of the Glibc executable contains the
earliest release number of the Linux kernel that supports this ABI.
As of a current 2.37 version of Glibc, it is 3.2.0 for x86, 3.7.0
for Aarch64.
Glibc does not use this release number and the current kernel's
LINUX_VERSION_CODE to detect kernel features, using fallbacks to known
previous way in case of ENOSYS or something else instead.

A dynamically linked Glibc reads the current kernel's LINUX_VERSION_CODE
from the ELF note in the vDSO or fallback to uname syscall if the vDSO
can't be located and parse the release field in struct utsname. Glibc
uses the current kernel's LINUX_VERSION_CODE for "kernel too old" check.

While here use inlined LINUX_KERNVER for tests to improve readability,
as suggested by emaste@.

MFC after:		1 month
This commit is contained in:
Dmitry Chagin 2023-04-26 16:56:41 +03:00
parent 727fd8a73d
commit 76f8584e49
2 changed files with 4 additions and 7 deletions

View File

@ -492,6 +492,7 @@ linux_trans_osrel(const Elf_Note *note, int32_t *osrel)
int
__linuxN(copyout_auxargs)(struct image_params *imgp, uintptr_t base)
{
struct thread *td = curthread;
Elf_Auxargs *args;
Elf_Auxinfo *aarray, *pos;
struct proc *p;
@ -526,14 +527,13 @@ __linuxN(copyout_auxargs)(struct image_params *imgp, uintptr_t base)
AUXARGS_ENTRY(pos, AT_GID, imgp->proc->p_ucred->cr_rgid);
AUXARGS_ENTRY(pos, AT_EGID, imgp->proc->p_ucred->cr_svgid);
AUXARGS_ENTRY(pos, LINUX_AT_SECURE, issetugid);
if (p->p_osrel >= LINUX_KERNVER_2006030 || p->p_osrel == 0)
if (linux_kernver(td) >= LINUX_KERNVER(2,6,30))
AUXARGS_ENTRY_PTR(pos, LINUX_AT_RANDOM, imgp->canary);
if ((p->p_osrel >= LINUX_KERNVER_2006026 || p->p_osrel == 0) &&
imgp->execpathp != 0)
if (linux_kernver(td) >= LINUX_KERNVER(2,6,26) && imgp->execpathp != 0)
AUXARGS_ENTRY(pos, LINUX_AT_EXECFN, PTROUT(imgp->execpathp));
if (args->execfd != -1)
AUXARGS_ENTRY(pos, AT_EXECFD, args->execfd);
if (p->p_osrel >= LINUX_KERNVER_5013000 || p->p_osrel == 0)
if (linux_kernver(td) >= LINUX_KERNVER(5,13,0))
AUXARGS_ENTRY(pos, LINUX_AT_MINSIGSTKSZ,
imgp->sysent->sv_minsigstksz);
AUXARGS_ENTRY(pos, AT_NULL, 0);

View File

@ -58,11 +58,8 @@ int linux_kernver(struct thread *td);
#define LINUX_VERSION_STR LINUX_XKERNVERSTR(LINUX_KVERSION.LINUX_KPATCHLEVEL.LINUX_KSUBLEVEL)
#define LINUX_KERNVER_2004000 LINUX_KERNVER(2,4,0)
#define LINUX_KERNVER_2006026 LINUX_KERNVER(2,6,26)
#define LINUX_KERNVER_2006030 LINUX_KERNVER(2,6,30)
#define LINUX_KERNVER_2006039 LINUX_KERNVER(2,6,39)
#define LINUX_KERNVER_5004000 LINUX_KERNVER(5,4,0)
#define LINUX_KERNVER_5013000 LINUX_KERNVER(5,13,0)
#define linux_use54(t) (linux_kernver(t) >= LINUX_KERNVER_5004000)