patch-2.1.106 linux/arch/alpha/kernel/osf_sys.c

Next file: linux/arch/alpha/kernel/process.c
Previous file: linux/arch/alpha/kernel/entry.S
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.105/linux/arch/alpha/kernel/osf_sys.c linux/arch/alpha/kernel/osf_sys.c
@@ -537,11 +537,15 @@
 	error = verify_area(VERIFY_WRITE, name, 5 * 32);
 	if (error)
 		goto out;
+		
+	down(&uts_sem);
 	copy_to_user(name + 0, system_utsname.sysname, 32);
 	copy_to_user(name + 32, system_utsname.nodename, 32);
 	copy_to_user(name + 64, system_utsname.release, 32);
 	copy_to_user(name + 96, system_utsname.version, 32);
 	copy_to_user(name + 128, system_utsname.machine, 32);
+	up(&uts_sem);
+	
 out:
 	unlock_kernel();
 	return error;
@@ -602,11 +606,13 @@
 	if (namelen > 32)
 		len = 32;
 
+	down(&uts_sem);
 	for (i = 0; i < len; ++i) {
-		put_user(system_utsname.domainname[i], name + i);
+		__put_user(system_utsname.domainname[i], name + i);
 		if (system_utsname.domainname[i] == '\0')
 			break;
 	}
+	up(&uts_sem);
 out:
 	unlock_kernel();
 	return error;
@@ -743,6 +749,50 @@
 	return error;
 }
 
+asmlinkage int osf_sigstack(struct sigstack *uss, struct sigstack *uoss)
+{
+	unsigned long usp = rdusp();
+	unsigned long oss_sp, oss_os;
+	int error;
+
+	if (uoss) {
+		oss_sp = current->sas_ss_sp + current->sas_ss_size;
+		oss_os = on_sig_stack(usp);
+	}
+
+	if (uss) {
+		unsigned long ss_sp;
+
+		error = -EFAULT;
+		if (get_user(ss_sp, &uss->ss_sp))
+			goto out;
+
+		/* If the current stack was set with sigaltstack, don't
+		   swap stacks while we are on it.  */
+		error = -EPERM;
+		if (current->sas_ss_sp && on_sig_stack(usp))
+			goto out;
+
+		/* Since we don't know the extent of the stack, and we don't
+		   track onstack-ness, but rather calculate it, we must 
+		   presume a size.  Ho hum this interface is lossy.  */
+		current->sas_ss_sp = ss_sp - SIGSTKSZ;
+		current->sas_ss_size = SIGSTKSZ;
+	}
+
+	if (uoss) {
+		error = -EFAULT;
+		if (! access_ok(VERIFY_WRITE, uoss, sizeof(*uoss))
+		    || __put_user(oss_sp, &uoss->ss_sp)
+		    || __put_user(oss_os, &uoss->ss_onstack))
+			goto out;
+	}
+
+	error = 0;
+out:
+	return error;
+}
+
 /*
  * The Linux kernel isn't good at returning values that look
  * like negative longs (they are mistaken as error values).
@@ -799,6 +849,8 @@
 		printk("sysinfo(%d)", command);
 		goto out;
 	}
+	
+	down(&uts_sem);
 	res = sysinfo_table[offset];
 	len = strlen(res)+1;
 	if (len > count)
@@ -807,6 +859,7 @@
 		err = -EFAULT;
 	else
 		err = 0;
+	up(&uts_sem);
 out:
 	unlock_kernel();
 	return err;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov