patch-2.4.0-test8 linux/arch/arm/kernel/ptrace.c

Next file: linux/arch/arm/kernel/signal.c
Previous file: linux/arch/arm/kernel/process.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.0-test7/linux/arch/arm/kernel/ptrace.c linux/arch/arm/kernel/ptrace.c
@@ -61,9 +61,18 @@
 static inline int
 put_stack_long(struct task_struct *task, int offset, long data)
 {
-	get_user_regs(task)->uregs[offset] = data;
+	struct pt_regs newregs, *regs = get_user_regs(task);
+	int ret = -EINVAL;
 
-	return 0;
+	newregs = *regs;
+	newregs.uregs[offset] = data;
+	
+	if (valid_user_regs(&newregs)) {
+		regs->uregs[offset] = data;
+		ret = 0;
+	}
+
+	return ret;
 }
 
 static inline int
@@ -406,7 +415,7 @@
 			if ((addr & 3) || addr < 0 || addr >= sizeof(struct user))
 				break;
 
-			if (addr < sizeof (struct pt_regs))
+			if (addr < sizeof(struct pt_regs))
 				ret = put_stack_long(child, (int)addr >> 2, data);
 			break;
 
@@ -499,12 +508,19 @@
 		 * Set all gp regs in the child.
 		 */
 		case PTRACE_SETREGS: {
-			struct pt_regs *regs = get_user_regs(child);
+			struct pt_regs newregs;
 
-			ret = 0;
-			if (copy_from_user(regs, (void *)data,
-					   sizeof(struct pt_regs)))
-				ret = -EFAULT;
+			ret = -EFAULT;
+			if (copy_from_user(&newregs, (void *)data,
+					   sizeof(struct pt_regs)) == 0) {
+				struct pt_regs *regs = get_user_regs(child);
+
+				ret = -EINVAL;
+				if (valid_user_regs(&newregs)) {
+					*regs = newregs;
+					ret = 0;
+				}
+			}
 			break;
 		}
 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)