Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Sanitize 'move_pages()' permission checks

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>
Cc: stable@kernel.org
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

+3 -8
+3 -8
mm/migrate.c
··· 41 41 #include <linux/page_idle.h> 42 42 #include <linux/page_owner.h> 43 43 #include <linux/sched/mm.h> 44 + #include <linux/ptrace.h> 44 45 45 46 #include <asm/tlbflush.h> 46 47 ··· 1653 1652 const int __user *, nodes, 1654 1653 int __user *, status, int, flags) 1655 1654 { 1656 - const struct cred *cred = current_cred(), *tcred; 1657 1655 struct task_struct *task; 1658 1656 struct mm_struct *mm; 1659 1657 int err; ··· 1676 1676 1677 1677 /* 1678 1678 * Check if this process has the right to modify the specified 1679 - * process. The right exists if the process has administrative 1680 - * capabilities, superuser privileges or the same 1681 - * userid as the target process. 1679 + * process. Use the regular "ptrace_may_access()" checks. 1682 1680 */ 1683 - tcred = __task_cred(task); 1684 - if (!uid_eq(cred->euid, tcred->suid) && !uid_eq(cred->euid, tcred->uid) && 1685 - !uid_eq(cred->uid, tcred->suid) && !uid_eq(cred->uid, tcred->uid) && 1686 - !capable(CAP_SYS_NICE)) { 1681 + if (!ptrace_may_access(task, PTRACE_MODE_READ_REALCREDS)) { 1687 1682 rcu_read_unlock(); 1688 1683 err = -EPERM; 1689 1684 goto out;