Skip to contentSkip to conversation

uts-semaphore fix for sparc64 solaris emu for kernel-2.6.9-rc1-bk6

PATCH In review Alexander Stohr 2 participants 3 messages Sep 1, 2004

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 uts-semaphore fix for sparc64 solaris emu for kernel-2.6.9-rc1-bk6

Hello,

Maybe i put the below patch
into the wrong mailslot.
I got no reply until now.

Do you have any comments on the subject?

-Alex.

PS: please CC me on replys.

--- Forwarded Message ---
Date: Tue, 31 Aug 2004 12:50:12 +0200 (MEST)
From: "Alexander Stohr" <[email protected]>
To: [email protected]
Subject: [patch] uts-semaphore fix for sparc64 solaris emu for kernel-2.6.9-rc1-bk6

Hello,

when copy-to-user and alikes does fail
for the solaris personality on sparc64
did fail then it is possible that the
current function gets left with an error
without prior releasing the uts-semphore.

the attached diff provides a patch that
is supposed to fixe that behaviour.
i was not able to test test this in the wild
due to lack of the respective hardware, so
any reports from machine owners would be nice.

-Alex.

PS: please CC me on replys, i am not subscribed to this list.

Signature · 6 lines
NEU: Bis zu 10 GB Speicher für e-mails & Dateien!
1 GB bereits bei GMX FreeMail http://www.gmx.net/de/go/mail

-- 
Supergünstige DSL-Tarife + WLAN-Router für 0,- EUR*
Jetzt zu GMX wechseln und sparen http://www.gmx.net/de/go/dsl
arch/sparc64/solaris/misc.c +34 -29
diff -Nur linux-2.6.9-rc1-bk6.orig/arch/sparc64/solaris/misc.c linux-2.6.9-rc1-bk6/arch/sparc64/solaris/misc.c
@@ -137,20 +137,22 @@
 	return sunos_brk(brk);
 }
 
-#define set_utsfield(to, from, dotchop, countfrom) {			\
-	char *p; 							\
-	int i, len = (countfrom) ? 					\
-		((sizeof(to) > sizeof(from) ? 				\
-			sizeof(from) : sizeof(to))) : sizeof(to); 	\
-	if (copy_to_user(to, from, len))				\
-		return -EFAULT;						\
-	if (dotchop) 							\
-		for (p=from,i=0; *p && *p != '.' && --len; p++,i++); 	\
-	else 								\
-		i = len - 1; 						\
-	if (__put_user('\0', (char __user *)((to)+i)))			\
-		return -EFAULT;						\
-}
+#define set_utsfield(to, from, dotchop, countfrom, perror) do {			\
+	char *p; 								\
+	int i, len = (countfrom) ? 						\
+		((sizeof(to) > sizeof(from) ? 					\
+			sizeof(from) : sizeof(to))) : sizeof(to); 		\
+	if (copy_to_user(to, from, len))					\
+		*perror = -EFAULT;						\
+	else {									\
+		if (dotchop) 							\
+			for (p=from,i=0; *p && *p != '.' && --len; p++,i++); 	\
+		else 								\
+			i = len - 1; 						\
+		if (__put_user('\0', (char __user *)((to)+i)))			\
+			*perror = -EFAULT;					\
+	}									\
+} while (0)
 
 struct sol_uname {
 	char sysname[9];
@@ -221,15 +223,17 @@
 	struct sol_uname __user *v = A(buf);
 	switch (which) {
 	case 0:	/* old uname */
-		/* Let's cheat */
-		set_utsfield(v->sysname, "SunOS", 1, 0);
-		down_read(&uts_sem);
-		set_utsfield(v->nodename, system_utsname.nodename, 1, 1);
-		up_read(&uts_sem);
-		set_utsfield(v->release, "2.6", 0, 0);
-		set_utsfield(v->version, "Generic", 0, 0);
-		set_utsfield(v->machine, machine(), 0, 0);
-		return 0;
+		{	int error = 0;
+			/* Let's cheat */
+			set_utsfield(v->sysname, "SunOS", 1, 0, &error);
+			down_read(&uts_sem);
+			set_utsfield(v->nodename, system_utsname.nodename, 1, 1, &error);
+			up_read(&uts_sem);
+			set_utsfield(v->release, "2.6", 0, 0, &error);
+			set_utsfield(v->version, "Generic", 0, 0, &error);
+			set_utsfield(v->machine, machine(), 0, 0, &error);
+			return error;
+		}
 	case 2: /* ustat */
 		return -ENOSYS;
 	case 3: /* fusers */
@@ -241,16 +245,17 @@
 
 asmlinkage int solaris_utsname(u32 buf)
 {
+	int error = 0;
 	struct sol_utsname __user *v = A(buf);
 	/* Why should we not lie a bit? */
 	down_read(&uts_sem);
-	set_utsfield(v->sysname, "SunOS", 0, 0);
-	set_utsfield(v->nodename, system_utsname.nodename, 1, 1);
-	set_utsfield(v->release, "5.6", 0, 0);
-	set_utsfield(v->version, "Generic", 0, 0);
-	set_utsfield(v->machine, machine(), 0, 0);
+	set_utsfield(v->sysname, "SunOS", 0, 0, &error);
+	set_utsfield(v->nodename, system_utsname.nodename, 1, 1, &error);
+	set_utsfield(v->release, "5.6", 0, 0, &error);
+	set_utsfield(v->version, "Generic", 0, 0, &error);
+	set_utsfield(v->machine, machine(), 0, 0, &error);
 	up_read(&uts_sem);
-	return 0;
+	return error;
 }
 
 #define SI_SYSNAME		1       /* return name of operating system */
#1 lore raw

Re: Fwd: [patch] uts-semaphore fix for sparc64 solaris emu for

Quoted 5 lines · On Wed, 1 Sep 2004 17:27:09 +0200 (MEST) "Alexander Stohr"…

Maybe i put the below patch
into the wrong mailslot.
I got no reply until now.

Do you have any comments on the subject?

It's a good fix, I'm just too busy to integrate it. I'll get to it, be patient.

#2 lore raw

Re: Fwd: [patch] uts-semaphore fix for sparc64 solaris emu for

In reply to Alexander Stohr

I think this is a better fix.

The based problem is that this thing is a macro at all, that is where the problems come from. It was also implementing strnchr() by hand as well, so I fixed that too.

# This is a BitKeeper generated diff -Nru style patch. #
# ChangeSet
# 2004/09/01 14:40:21-07:00 [email protected]
# [SPARC64]: Fix set_utsname returning with uts semaphore held.
#
# Based upon a patch from Alexander Stohr.
#
# This thing was also reimplementing strnchr() as well.
#
# Signed-off-by: David S. Miller <[email protected]>
#

# arch/sparc64/solaris/misc.c
#   2004/09/01 14:39:26-07:00 [email protected] +44 -25
#   [SPARC64]: Fix set_utsname returning with uts semaphore held.
# 
diff -Nru a/arch/sparc64/solaris/misc.c b/arch/sparc64/solaris/misc.c
--- a/arch/sparc64/solaris/misc.c	2004-09-01 14:40:53 -07:00
+++ b/arch/sparc64/solaris/misc.c	2004-09-01 14:40:53 -07:00
@@ -137,21 +137,34 @@
 	return sunos_brk(brk);
 }

-#define set_utsfield(to, from, dotchop, countfrom) { \
- char *p; \
- int i, len = (countfrom) ? \
- ((sizeof(to) > sizeof(from) ? \
- sizeof(from) : sizeof(to))) : sizeof(to); \
- if (copy_to_user(to, from, len)) \
- return -EFAULT; \
- if (dotchop) \
- for (p=from,i=0; *p && *p != '.' && --len; p++,i++); \
- else \
- i = len - 1; \
- if (__put_user('\0', (char __user *)((to)+i))) \
- return -EFAULT; \
+static int __set_utsfield(char __user *to, int to_size,
+ const char *from, int from_size,
+ int dotchop, int countfrom)
+{
+ int len = countfrom ? (to_size > from_size ?
+ from_size : to_size) : to_size;
+ int off;
+
+ if (copy_to_user(to, from, len))
+ return -EFAULT;
+
+ if (dotchop) {
+ off = (strnchr(from, len, '.') - from);
+ } else{
+ off = len - 1;
+ }
+
+ if (__put_user('\0', to + off))
+ return -EFAULT;
+
+ return 0;
}

+#define set_utsfield(to, from, dotchop, countfrom) \
+ __set_utsfield((to), sizeof(to), \
+ (from), sizeof(from), \
+ (dotchop), (countfrom))
+
struct sol_uname {
char sysname[9];
char nodename[9];
@@ -219,17 +232,20 @@
asmlinkage int solaris_utssys(u32 buf, u32 flags, int which, u32 buf2) {
struct sol_uname __user *v = A(buf);
+ int err;
+
switch (which) {
case 0: /* old uname */
/* Let's cheat */
- set_utsfield(v->sysname, "SunOS", 1, 0);
+ err = set_utsfield(v->sysname, "SunOS", 1, 0);
down_read(&uts_sem);
- set_utsfield(v->nodename, system_utsname.nodename, 1, 1);
+ err |= set_utsfield(v->nodename, system_utsname.nodename,
+ 1, 1);
up_read(&uts_sem);
- set_utsfield(v->release, "2.6", 0, 0);
- set_utsfield(v->version, "Generic", 0, 0);
- set_utsfield(v->machine, machine(), 0, 0);
- return 0;

+		err |= set_utsfield(v->release, "2.6", 0, 0);
+		err |= set_utsfield(v->version, "Generic", 0, 0);
+		err |= set_utsfield(v->machine, machine(), 0, 0);

+ return (err ? -EFAULT : 0);
case 2: /* ustat */
return -ENOSYS;
case 3: /* fusers */
@@ -242,15 +258,18 @@
asmlinkage int solaris_utsname(u32 buf)
{
struct sol_utsname __user *v = A(buf);
+ int err;
+
/* Why should we not lie a bit? */
down_read(&uts_sem);
- set_utsfield(v->sysname, "SunOS", 0, 0);
- set_utsfield(v->nodename, system_utsname.nodename, 1, 1);
- set_utsfield(v->release, "5.6", 0, 0);
- set_utsfield(v->version, "Generic", 0, 0);
- set_utsfield(v->machine, machine(), 0, 0);
+ err = set_utsfield(v->sysname, "SunOS", 0, 0);

+	err |= set_utsfield(v->nodename, system_utsname.nodename, 1, 1);
+	err |= set_utsfield(v->release, "5.6", 0, 0);
+	err |= set_utsfield(v->version, "Generic", 0, 0);
+	err |= set_utsfield(v->machine, machine(), 0, 0);

up_read(&uts_sem);
- return 0;
+
+ return (err ? -EFAULT : 0);
}

#define SI_SYSNAME 1 /* return name of operating system */