mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	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>
This commit is contained in:
		
							parent
							
								
									7f680d7ec3
								
							
						
					
					
						commit
						197e7e5213
					
				
					 1 changed files with 3 additions and 8 deletions
				
			
		
							
								
								
									
										11
									
								
								mm/migrate.c
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								mm/migrate.c
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -41,6 +41,7 @@
 | 
			
		|||
#include <linux/page_idle.h>
 | 
			
		||||
#include <linux/page_owner.h>
 | 
			
		||||
#include <linux/sched/mm.h>
 | 
			
		||||
#include <linux/ptrace.h>
 | 
			
		||||
 | 
			
		||||
#include <asm/tlbflush.h>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1652,7 +1653,6 @@ SYSCALL_DEFINE6(move_pages, pid_t, pid, unsigned long, nr_pages,
 | 
			
		|||
		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;
 | 
			
		||||
| 
						 | 
				
			
			@ -1676,14 +1676,9 @@ SYSCALL_DEFINE6(move_pages, pid_t, pid, unsigned long, nr_pages,
 | 
			
		|||
 | 
			
		||||
	/*
 | 
			
		||||
	 * 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.
 | 
			
		||||
	 * process. Use the regular "ptrace_may_access()" checks.
 | 
			
		||||
	 */
 | 
			
		||||
	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)) {
 | 
			
		||||
	if (!ptrace_may_access(task, PTRACE_MODE_READ_REALCREDS)) {
 | 
			
		||||
		rcu_read_unlock();
 | 
			
		||||
		err = -EPERM;
 | 
			
		||||
		goto out;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue