summary refs log tree commit diff
path: root/kernel/fork.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2019-11-25 15:43:15 +0100
committerIngo Molnar <mingo@kernel.org>2019-11-25 15:43:15 +0100
commit83bae01182ea755280adc1c3a24032d63a614ede (patch)
treef05249057a392e750c0622bbdd3620e19aafd031 /kernel/fork.c
parentcf25e24db61cc9df42c47485a2ec2bff4e9a3692 (diff)
parent7b8474466ed97be458c825f34a85f2c2b84c3f95 (diff)
downloadlinux-83bae01182ea755280adc1c3a24032d63a614ede.tar.gz
Merge branch 'timers/urgent' into timers/core, to pick up fix
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'kernel/fork.c')
-rw-r--r--kernel/fork.c33
1 files changed, 32 insertions, 1 deletions
diff --git a/kernel/fork.c b/kernel/fork.c
index 1392ee8f4848..7e3a8e1b773a 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -2561,7 +2561,35 @@ noinline static int copy_clone_args_from_user(struct kernel_clone_args *kargs,
 	return 0;
 }
 
-static bool clone3_args_valid(const struct kernel_clone_args *kargs)
+/**
+ * clone3_stack_valid - check and prepare stack
+ * @kargs: kernel clone args
+ *
+ * Verify that the stack arguments userspace gave us are sane.
+ * In addition, set the stack direction for userspace since it's easy for us to
+ * determine.
+ */
+static inline bool clone3_stack_valid(struct kernel_clone_args *kargs)
+{
+	if (kargs->stack == 0) {
+		if (kargs->stack_size > 0)
+			return false;
+	} else {
+		if (kargs->stack_size == 0)
+			return false;
+
+		if (!access_ok((void __user *)kargs->stack, kargs->stack_size))
+			return false;
+
+#if !defined(CONFIG_STACK_GROWSUP) && !defined(CONFIG_IA64)
+		kargs->stack += kargs->stack_size;
+#endif
+	}
+
+	return true;
+}
+
+static bool clone3_args_valid(struct kernel_clone_args *kargs)
 {
 	/*
 	 * All lower bits of the flag word are taken.
@@ -2581,6 +2609,9 @@ static bool clone3_args_valid(const struct kernel_clone_args *kargs)
 	    kargs->exit_signal)
 		return false;
 
+	if (!clone3_stack_valid(kargs))
+		return false;
+
 	return true;
 }