From raybry@sgi.com Fri Jul 1 15:41:45 2005 Date: Fri, 1 Jul 2005 15:41:42 -0700 (PDT) From: Ray Bryant To: Hirokazu Takahashi , Marcelo Tosatti , Andi Kleen , Dave Hansen Cc: Christoph Hellwig , linux-mm , Nathan Scott , Ray Bryant , lhms-devel@lists.sourceforge.net, Ray Bryant , Paul Jackson , clameter@sgi.com Subject: [PATCH 2.6.13-rc1 10/11] mm: manual page migration-rc4 -- sys_migrate_pages-permissions-check-rc4.patch Add permissions checking to migrate_pages() system call. The basic idea is that if you could send an arbitary signal to a process then you are allowed to migrate that process, or if the calling process has capability CAP_SYS_ADMIN. The permissions check is based on that in check_kill_permission() in kernel/signal.c. Signed-off-by: Ray Bryant include/linux/capability.h | 2 ++ mm/mmigrate.c | 12 ++++++++++++ 2 files changed, 14 insertions(+) Index: linux-2.6.13/include/linux/capability.h =================================================================== --- linux-2.6.13.orig/include/linux/capability.h 2005-08-28 16:41:01.000000000 -0700 +++ linux-2.6.13/include/linux/capability.h 2005-08-30 13:20:49.000000000 -0700 @@ -233,6 +233,8 @@ typedef __u32 kernel_cap_t; /* Allow enabling/disabling tagged queuing on SCSI controllers and sending arbitrary SCSI commands */ /* Allow setting encryption key on loopback filesystem */ +/* Allow using the migrate_pages() system call to migrate a process's pages + from one set of NUMA nodes to another */ #define CAP_SYS_ADMIN 21 Index: linux-2.6.13/mm/mmigrate.c =================================================================== --- linux-2.6.13.orig/mm/mmigrate.c 2005-08-30 13:20:47.000000000 -0700 +++ linux-2.6.13/mm/mmigrate.c 2005-08-30 13:20:49.000000000 -0700 @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include #include #include @@ -733,6 +735,16 @@ sys_migrate_pages(pid_t pid, __u32 count task = find_task_by_pid(pid); if (task) { task_lock(task); + /* does this task have permission to migrate that task? + * (ala check_kill_permission() ) */ + if ((current->euid ^ task->suid) && (current->euid ^ task->uid) + && (current->uid ^ task->suid) && (current->uid ^ task->uid) + && !capable(CAP_SYS_ADMIN)) { + ret = -EPERM; + task_unlock(task); + read_unlock(&tasklist_lock); + goto out; + } mm = task->mm; if (mm) atomic_inc(&mm->mm_users);