public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Add a personality to report 2.6.x version numbers
@ 2011-08-19 23:15 Andi Kleen
  2011-08-21 22:28 ` Arnaud Lacombe
                   ` (4 more replies)
  0 siblings, 5 replies; 35+ messages in thread
From: Andi Kleen @ 2011-08-19 23:15 UTC (permalink / raw)
  To: torvalds; +Cc: akpm, linux-kernel, Andi Kleen

From: Andi Kleen <ak@linux.intel.com>

Reposting due to popular demand. Several other people are running
into the same problem with all kinds of software.

Only change is rebase against current master.

-Andi

--

I ran into a couple of programs which broke with the new Linux 3.0 version.
Some of those were binary only. I tried to use LD_PRELOAD to work
around it, but it was quite difficult and in one case impossible
because of a mix of 32bit and 64bit executables.

This patch adds a UNAME26 personality that makes the kernel
report a 2.6.40+x version number instead. The x is the x in 3.x.

I know this is somewhat ugly, but I didn't find a better workaround,
and compatibility to existing programs is important.

Some programs also read /proc/sys/kernel/osrelease. This can be worked
around in user space with mount --bind (and a mount namespace)

To use:

wget ftp://ftp.kernel.org/pub/linux/kernel/people/ak/uname26/uname26.c
gcc -o uname26 uname26.c
./uname26 program

Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 include/linux/personality.h |    1 +
 kernel/sys.c                |   38 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 39 insertions(+), 0 deletions(-)

diff --git a/include/linux/personality.h b/include/linux/personality.h
index eec3bae..8fc7dd1a 100644
--- a/include/linux/personality.h
+++ b/include/linux/personality.h
@@ -22,6 +22,7 @@ extern int		__set_personality(unsigned int);
  * These occupy the top three bytes.
  */
 enum {
+	UNAME26	=               0x0020000,
 	ADDR_NO_RANDOMIZE = 	0x0040000,	/* disable randomization of VA space */
 	FDPIC_FUNCPTRS =	0x0080000,	/* userspace function ptrs point to descriptors
 						 * (signal handling)
diff --git a/kernel/sys.c b/kernel/sys.c
index a101ba3..bd6d142 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -37,6 +37,8 @@
 #include <linux/fs_struct.h>
 #include <linux/gfp.h>
 #include <linux/syscore_ops.h>
+#include <linux/version.h>
+#include <linux/ctype.h>
 
 #include <linux/compat.h>
 #include <linux/syscalls.h>
@@ -44,6 +46,8 @@
 #include <linux/user_namespace.h>
 
 #include <linux/kmsg_dump.h>
+/* Move somewhere else to avoid recompiling? */
+#include <generated/utsrelease.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -1154,6 +1158,34 @@ DECLARE_RWSEM(uts_sem);
 #define override_architecture(name)	0
 #endif
 
+/* 
+ * Work around broken programs that cannot handle "Linux 3.0".
+ * Instead we map 3.x to 2.6.40+x, so e.g. 3.0 would be 2.6.40
+ */
+static int override_release(char __user *release, int len)
+{	
+	int ret = 0;
+	char buf[len];
+
+	if (current->personality & UNAME26) {
+		char *rest = UTS_RELEASE;
+		int ndots = 0;
+		unsigned v;
+
+		while (*rest) {
+			if (*rest == '.' && ++ndots >= 3)
+				break;
+			if (!isdigit(*rest) && *rest != '.')
+				break;
+			rest++;
+		}
+		v = ((LINUX_VERSION_CODE >> 8) & 0xff) + 40;
+		snprintf(buf, len, "2.6.%u%s", v, rest);
+		ret = copy_to_user(release, buf, len);
+	}
+	return ret;
+}
+
 SYSCALL_DEFINE1(newuname, struct new_utsname __user *, name)
 {
 	int errno = 0;
@@ -1163,6 +1195,8 @@ SYSCALL_DEFINE1(newuname, struct new_utsname __user *, name)
 		errno = -EFAULT;
 	up_read(&uts_sem);
 
+	if (!errno && override_release(name->release, sizeof(name->release)))
+		errno = -EFAULT;
 	if (!errno && override_architecture(name))
 		errno = -EFAULT;
 	return errno;
@@ -1184,6 +1218,8 @@ SYSCALL_DEFINE1(uname, struct old_utsname __user *, name)
 		error = -EFAULT;
 	up_read(&uts_sem);
 
+	if (!error && override_release(name->release, sizeof(name->release)))
+		error = -EFAULT;
 	if (!error && override_architecture(name))
 		error = -EFAULT;
 	return error;
@@ -1218,6 +1254,8 @@ SYSCALL_DEFINE1(olduname, struct oldold_utsname __user *, name)
 
 	if (!error && override_architecture(name))
 		error = -EFAULT;
+	if (!error && override_release(name->release, sizeof(name->release)))
+		error = -EFAULT;
 	return error ? -EFAULT : 0;
 }
 #endif
-- 
1.7.4.4


^ permalink raw reply related	[flat|nested] 35+ messages in thread
* [PATCH] Add a personality to report 2.6.x version numbers
@ 2011-07-07 23:42 Andi Kleen
  0 siblings, 0 replies; 35+ messages in thread
From: Andi Kleen @ 2011-07-07 23:42 UTC (permalink / raw)
  To: torvalds; +Cc: linux-kernel, Andi Kleen

From: Andi Kleen <ak@linux.intel.com>

I ran into a couple of programs which broke with the new Linux 3.0 version.
Some of those were binary only. I tried to use LD_PRELOAD to work
around it, but it was quite difficult and in one case impossible
because of a mix of 32bit and 64bit executables.

This patch adds a UNAME26 personality that makes the kernel
report a 2.6.40+x version number instead. The x is the x in 3.x.

I know this is somewhat ugly, but I didn't find a better workaround,
and compatibility to existing programs is important.

To use:

wget ftp://ftp.kernel.org/pub/linux/kernel/people/ak/uname26/uname26.c
gcc -o uname26 uname26.c
./uname26 program

Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 include/linux/personality.h |    1 +
 kernel/sys.c                |   38 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 39 insertions(+), 0 deletions(-)

diff --git a/include/linux/personality.h b/include/linux/personality.h
index eec3bae..8fc7dd1a 100644
--- a/include/linux/personality.h
+++ b/include/linux/personality.h
@@ -22,6 +22,7 @@ extern int		__set_personality(unsigned int);
  * These occupy the top three bytes.
  */
 enum {
+	UNAME26	=               0x0020000,
 	ADDR_NO_RANDOMIZE = 	0x0040000,	/* disable randomization of VA space */
 	FDPIC_FUNCPTRS =	0x0080000,	/* userspace function ptrs point to descriptors
 						 * (signal handling)
diff --git a/kernel/sys.c b/kernel/sys.c
index e4128b2..a828be0 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -38,6 +38,8 @@
 #include <linux/fs_struct.h>
 #include <linux/gfp.h>
 #include <linux/syscore_ops.h>
+#include <linux/version.h>
+#include <linux/ctype.h>
 
 #include <linux/compat.h>
 #include <linux/syscalls.h>
@@ -45,6 +47,8 @@
 #include <linux/user_namespace.h>
 
 #include <linux/kmsg_dump.h>
+/* Move somewhere else to avoid recompiling? */
+#include <generated/utsrelease.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -1124,6 +1128,34 @@ DECLARE_RWSEM(uts_sem);
 #define override_architecture(name)	0
 #endif
 
+/* 
+ * Work around broken programs that cannot handle "Linux 3.0".
+ * Instead we map 3.x to 2.6.40+x, so e.g. 3.0 would be 2.6.40
+ */
+static int override_release(char __user *release, int len)
+{	
+	int ret = 0;
+	char buf[len];
+
+	if (current->personality & UNAME26) {
+		char *rest = UTS_RELEASE;
+		int ndots = 0;
+		unsigned v;
+
+		while (*rest) {
+			if (*rest == '.' && ++ndots >= 3)
+				break;
+			if (!isdigit(*rest) && *rest != '.')
+				break;
+			rest++;
+		}
+		v = ((LINUX_VERSION_CODE >> 8) & 0xff) + 40;
+		snprintf(buf, len, "2.6.%u%s", v, rest);
+		ret = copy_to_user(release, buf, len);
+	}
+	return ret;
+}
+
 SYSCALL_DEFINE1(newuname, struct new_utsname __user *, name)
 {
 	int errno = 0;
@@ -1133,6 +1165,8 @@ SYSCALL_DEFINE1(newuname, struct new_utsname __user *, name)
 		errno = -EFAULT;
 	up_read(&uts_sem);
 
+	if (!errno && override_release(name->release, sizeof(name->release)))
+		errno = -EFAULT;
 	if (!errno && override_architecture(name))
 		errno = -EFAULT;
 	return errno;
@@ -1154,6 +1188,8 @@ SYSCALL_DEFINE1(uname, struct old_utsname __user *, name)
 		error = -EFAULT;
 	up_read(&uts_sem);
 
+	if (!error && override_release(name->release, sizeof(name->release)))
+		error = -EFAULT;
 	if (!error && override_architecture(name))
 		error = -EFAULT;
 	return error;
@@ -1188,6 +1224,8 @@ SYSCALL_DEFINE1(olduname, struct oldold_utsname __user *, name)
 
 	if (!error && override_architecture(name))
 		error = -EFAULT;
+	if (!error && override_release(name->release, sizeof(name->release)))
+		error = -EFAULT;
 	return error ? -EFAULT : 0;
 }
 #endif
-- 
1.7.4.4


^ permalink raw reply related	[flat|nested] 35+ messages in thread

end of thread, other threads:[~2011-09-13 23:06 UTC | newest]

Thread overview: 35+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-08-19 23:15 [PATCH] Add a personality to report 2.6.x version numbers Andi Kleen
2011-08-21 22:28 ` Arnaud Lacombe
2011-08-21 22:37   ` Jesper Juhl
2011-08-21 23:15     ` Andi Kleen
2011-08-21 23:13   ` Andi Kleen
2011-08-21 23:32     ` Arnaud Lacombe
2011-08-22  0:11       ` Andi Kleen
2011-08-22  1:04         ` Arnaud Lacombe
2011-08-22  1:46           ` Andi Kleen
2011-08-22  9:54   ` Américo Wang
2011-08-22 18:30 ` Linus Torvalds
2011-08-22 18:45   ` Eric Dumazet
2011-08-22 19:03     ` David Daney
2011-08-22 19:34   ` Andi Kleen
2011-08-23 13:15   ` Colin Walters
2011-08-23 16:11     ` Andi Kleen
2011-08-23 16:20       ` Colin Walters
2011-08-23 17:35         ` Arnaud Lacombe
2011-08-24 14:19     ` Alexey Dobriyan
2011-08-24 17:02       ` Arnd Bergmann
2011-09-13 14:12   ` Pavel Machek
2011-09-13 14:36     ` Stratos Psomadakis
2011-09-13 15:50       ` Andi Kleen
2011-09-13 23:06         ` Stratos Psomadakis
2011-08-23  6:00 ` [PATCH] setarch: Add --uname-2.6 option for personality flag UNAME26 Ben Hutchings
2011-08-23 10:16   ` Karel Zak
2011-08-23 12:15     ` Ben Hutchings
2011-08-26 21:43     ` Greg KH
2011-08-29  9:17   ` Karel Zak
2011-08-23 12:44 ` [PATCH] Add a personality to report 2.6.x version numbers Arnd Bergmann
2011-08-26 21:43 ` Greg KH
2011-08-26 22:25   ` Andi Kleen
2011-08-26 22:35     ` Greg KH
2011-08-27 16:36     ` Jesper Juhl
  -- strict thread matches above, loose matches on Subject: below --
2011-07-07 23:42 Andi Kleen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox