This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] linux: add support for uname26 personality


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]