Skip to content

Commit 46d51a2

Browse files
torvaldsgregkh
authored andcommitted
Sanitize 'move_pages()' permission checks
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>
1 parent b27e9ff commit 46d51a2

1 file changed

Lines changed: 3 additions & 8 deletions

File tree

mm/migrate.c

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include <linux/balloon_compaction.h>
3939
#include <linux/mmu_notifier.h>
4040
#include <linux/page_idle.h>
41+
#include <linux/ptrace.h>
4142

4243
#include <asm/tlbflush.h>
4344

@@ -1483,7 +1484,6 @@ SYSCALL_DEFINE6(move_pages, pid_t, pid, unsigned long, nr_pages,
14831484
const int __user *, nodes,
14841485
int __user *, status, int, flags)
14851486
{
1486-
const struct cred *cred = current_cred(), *tcred;
14871487
struct task_struct *task;
14881488
struct mm_struct *mm;
14891489
int err;
@@ -1507,14 +1507,9 @@ SYSCALL_DEFINE6(move_pages, pid_t, pid, unsigned long, nr_pages,
15071507

15081508
/*
15091509
* Check if this process has the right to modify the specified
1510-
* process. The right exists if the process has administrative
1511-
* capabilities, superuser privileges or the same
1512-
* userid as the target process.
1510+
* process. Use the regular "ptrace_may_access()" checks.
15131511
*/
1514-
tcred = __task_cred(task);
1515-
if (!uid_eq(cred->euid, tcred->suid) && !uid_eq(cred->euid, tcred->uid) &&
1516-
!uid_eq(cred->uid, tcred->suid) && !uid_eq(cred->uid, tcred->uid) &&
1517-
!capable(CAP_SYS_NICE)) {
1512+
if (!ptrace_may_access(task, PTRACE_MODE_READ_REALCREDS)) {
15181513
rcu_read_unlock();
15191514
err = -EPERM;
15201515
goto out;

0 commit comments

Comments
 (0)