--- /dev/null
+From 197e7e521384a23b9e585178f3f11c9fa08274b9 Mon Sep 17 00:00:00 2001
+From: Linus Torvalds <torvalds@linux-foundation.org>
+Date: Sun, 20 Aug 2017 13:26:27 -0700
+Subject: Sanitize 'move_pages()' permission checks
+
+From: Linus Torvalds <torvalds@linux-foundation.org>
+
+commit 197e7e521384a23b9e585178f3f11c9fa08274b9 upstream.
+
+The 'move_paghes()' system call was introduced long long ago with the
+same permission checks as for sending a signal (except using
+CAP_SYS_NICE instead of CAP_SYS_KILL for the overriding capability).
+
+That turns out to not be a great choice - while the system call really
+only moves physical page allocations around (and you need other
+capabilities to do a lot of it), you can check the return value to map
+out some the virtual address choices and defeat ASLR of a binary that
+still shares your uid.
+
+So change the access checks to the more common 'ptrace_may_access()'
+model instead.
+
+This tightens the access checks for the uid, and also effectively
+changes the CAP_SYS_NICE check to CAP_SYS_PTRACE, but it's unlikely that
+anybody really _uses_ this legacy system call any more (we hav ebetter
+NUMA placement models these days), so I expect nobody to notice.
+
+Famous last words.
+
+Reported-by: Otto Ebeling <otto.ebeling@iki.fi>
+Acked-by: Eric W. Biederman <ebiederm@xmission.com>
+Cc: Willy Tarreau <w@1wt.eu>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ mm/migrate.c | 13 ++++---------
+ 1 file changed, 4 insertions(+), 9 deletions(-)
+
+--- a/mm/migrate.c
++++ b/mm/migrate.c
+@@ -37,6 +37,7 @@
+ #include <linux/gfp.h>
+ #include <linux/balloon_compaction.h>
+ #include <linux/mmu_notifier.h>
++#include <linux/ptrace.h>
+
+ #include <asm/tlbflush.h>
+
+@@ -1468,7 +1469,6 @@ SYSCALL_DEFINE6(move_pages, pid_t, pid,
+ const int __user *, nodes,
+ int __user *, status, int, flags)
+ {
+- const struct cred *cred = current_cred(), *tcred;
+ struct task_struct *task;
+ struct mm_struct *mm;
+ int err;
+@@ -1492,14 +1492,9 @@ SYSCALL_DEFINE6(move_pages, pid_t, pid,
+
+ /*
+ * Check if this process has the right to modify the specified
+- * process. The right exists if the process has administrative
+- * capabilities, superuser privileges or the same
+- * userid as the target process.
+- */
+- tcred = __task_cred(task);
+- if (!uid_eq(cred->euid, tcred->suid) && !uid_eq(cred->euid, tcred->uid) &&
+- !uid_eq(cred->uid, tcred->suid) && !uid_eq(cred->uid, tcred->uid) &&
+- !capable(CAP_SYS_NICE)) {
++ * process. Use the regular "ptrace_may_access()" checks.
++ */
++ if (!ptrace_may_access(task, PTRACE_MODE_READ_REALCREDS)) {
+ rcu_read_unlock();
+ err = -EPERM;
+ goto out;