This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH] linux: add support for uname26 personality
- From: Aurelien Jarno <aurelien at aurel32 dot net>
- To: libc-alpha at sourceware dot org
- Cc: Aurelien Jarno <aurelien at aurel32 dot net>
- Date: Thu, 3 Dec 2015 00:22:42 +0100
- Subject: [PATCH] linux: add support for uname26 personality
- Authentication-results: sourceware.org; auth=none
When the kernel is running under the uname26 personality (for programs
that cannot handle "Linux 3.0"), it maps version 3.x to 2.6.40+x and
4.x to 2.6.60+x. When the GNU libc is configured with --enable-kernel=3.x
or 4.x and uname26 personality is enabled, binaries get abort with a
"FATAL: kernel too old message", even if the kernel actually supports
such a binary.
This patch fixes the issue by converting the value in 2.6.x format back
to the 3.x or 4.X format.
---
ChangeLog | 6 ++++++
sysdeps/unix/sysv/linux/dl-sysdep.c | 26 +++++++++++++++++++++++---
2 files changed, 29 insertions(+), 3 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index c7c4c25..593cfad 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2015-12-03 Aurelien Jarno <aurel32@debian.org>
+
+ * sysdeps/unix/sysv/linux/dl-sysdep.c (convert_from_uname26): New.
+ (_dl_discover_osversion): Call convert_from_uname26 before returning
+ the version.
+
2015-12-01 H.J. Lu <hongjiu.lu@intel.com>
[BZ #19313]
diff --git a/sysdeps/unix/sysv/linux/dl-sysdep.c b/sysdeps/unix/sysv/linux/dl-sysdep.c
index a4c32f6..4fca8d1 100644
--- a/sysdeps/unix/sysv/linux/dl-sysdep.c
+++ b/sysdeps/unix/sysv/linux/dl-sysdep.c
@@ -38,6 +38,25 @@ frob_brk (void)
# include <elf/dl-sysdep.c>
#endif
+/* When the kernel is running under the uname26 personality (for programs
+ that cannot handle "Linux 3.0"), it maps version 3.x to 2.6.40+x and
+ 4.x to 2.6.60+x. We need to convert that back to the standard version
+ numbering to be able to compare versions. */
+static int
+convert_from_uname26 (int version)
+{
+ if ((version & 0xffff00) == 0x020600)
+ {
+ /* 2.6.40+x to 3.x */
+ if ((version & 0xff) >= 60)
+ version += 0x020000 - 60;
+ /* 2.6.60+x to 4.x */
+ else if ((version & 0xff) >= 40)
+ version += 0x010000 - 40;
+ }
+
+ return version;
+}
int
attribute_hidden
@@ -65,8 +84,9 @@ _dl_discover_osversion (void)
while ((ElfW(Addr)) (note + 1) - start < phdr[i].p_memsz)
{
if (!memcmp (note, &expected_note, sizeof expected_note))
- return *(const ElfW(Word) *) ((const void *) note
- + sizeof expected_note);
+ return convert_from_uname26(
+ *(const ElfW(Word) *) ((const void *) note
+ + sizeof expected_note));
#define ROUND(len) (((len) + sizeof note->n_type - 1) & -sizeof note->n_type)
note = ((const void *) (note + 1)
+ ROUND (note->n_namesz) + ROUND (note->n_descsz));
@@ -128,5 +148,5 @@ _dl_discover_osversion (void)
if (parts < 3)
version <<= 8 * (3 - parts);
- return version;
+ return convert_from_uname26(version);
}
--
2.6.2