Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e5467859 authored by Al Viro's avatar Al Viro
Browse files

split ->file_mmap() into ->mmap_addr()/->mmap_file()



... i.e. file-dependent and address-dependent checks.

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent d007794a
Loading
Loading
Loading
Loading
+0 −4
Original line number Original line Diff line number Diff line
@@ -280,10 +280,6 @@ static int __bprm_mm_init(struct linux_binprm *bprm)
	vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
	vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
	INIT_LIST_HEAD(&vma->anon_vma_chain);
	INIT_LIST_HEAD(&vma->anon_vma_chain);


	err = security_file_mmap(NULL, 0, 0, 0, vma->vm_start, 1);
	if (err)
		goto err;

	err = insert_vm_struct(mm, vma);
	err = insert_vm_struct(mm, vma);
	if (err)
	if (err)
		goto err;
		goto err;
+20 −16
Original line number Original line Diff line number Diff line
@@ -87,9 +87,8 @@ extern int cap_inode_removexattr(struct dentry *dentry, const char *name);
extern int cap_inode_need_killpriv(struct dentry *dentry);
extern int cap_inode_need_killpriv(struct dentry *dentry);
extern int cap_inode_killpriv(struct dentry *dentry);
extern int cap_inode_killpriv(struct dentry *dentry);
extern int cap_mmap_addr(unsigned long addr);
extern int cap_mmap_addr(unsigned long addr);
extern int cap_file_mmap(struct file *file, unsigned long reqprot,
extern int cap_mmap_file(struct file *file, unsigned long reqprot,
			 unsigned long prot, unsigned long flags,
			 unsigned long prot, unsigned long flags);
			 unsigned long addr, unsigned long addr_only);
extern int cap_task_fix_setuid(struct cred *new, const struct cred *old, int flags);
extern int cap_task_fix_setuid(struct cred *new, const struct cred *old, int flags);
extern int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3,
extern int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3,
			  unsigned long arg4, unsigned long arg5);
			  unsigned long arg4, unsigned long arg5);
@@ -587,15 +586,17 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
 *	simple integer value.  When @arg represents a user space pointer, it
 *	simple integer value.  When @arg represents a user space pointer, it
 *	should never be used by the security module.
 *	should never be used by the security module.
 *	Return 0 if permission is granted.
 *	Return 0 if permission is granted.
 * @file_mmap :
 * @mmap_addr :
 *	Check permissions for a mmap operation at @addr.
 *	@addr contains virtual address that will be used for the operation.
 *	Return 0 if permission is granted.
 * @mmap_file :
 *	Check permissions for a mmap operation.  The @file may be NULL, e.g.
 *	Check permissions for a mmap operation.  The @file may be NULL, e.g.
 *	if mapping anonymous memory.
 *	if mapping anonymous memory.
 *	@file contains the file structure for file to map (may be NULL).
 *	@file contains the file structure for file to map (may be NULL).
 *	@reqprot contains the protection requested by the application.
 *	@reqprot contains the protection requested by the application.
 *	@prot contains the protection that will be applied by the kernel.
 *	@prot contains the protection that will be applied by the kernel.
 *	@flags contains the operational flags.
 *	@flags contains the operational flags.
 *	@addr contains virtual address that will be used for the operation.
 *	@addr_only contains a boolean: 0 if file-backed VMA, otherwise 1.
 *	Return 0 if permission is granted.
 *	Return 0 if permission is granted.
 * @file_mprotect:
 * @file_mprotect:
 *	Check permissions before changing memory access permissions.
 *	Check permissions before changing memory access permissions.
@@ -1482,10 +1483,10 @@ struct security_operations {
	void (*file_free_security) (struct file *file);
	void (*file_free_security) (struct file *file);
	int (*file_ioctl) (struct file *file, unsigned int cmd,
	int (*file_ioctl) (struct file *file, unsigned int cmd,
			   unsigned long arg);
			   unsigned long arg);
	int (*file_mmap) (struct file *file,
	int (*mmap_addr) (unsigned long addr);
	int (*mmap_file) (struct file *file,
			  unsigned long reqprot, unsigned long prot,
			  unsigned long reqprot, unsigned long prot,
			  unsigned long flags, unsigned long addr,
			  unsigned long flags);
			  unsigned long addr_only);
	int (*file_mprotect) (struct vm_area_struct *vma,
	int (*file_mprotect) (struct vm_area_struct *vma,
			      unsigned long reqprot,
			      unsigned long reqprot,
			      unsigned long prot);
			      unsigned long prot);
@@ -1744,9 +1745,9 @@ int security_file_permission(struct file *file, int mask);
int security_file_alloc(struct file *file);
int security_file_alloc(struct file *file);
void security_file_free(struct file *file);
void security_file_free(struct file *file);
int security_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
int security_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
int security_file_mmap(struct file *file, unsigned long reqprot,
int security_mmap_file(struct file *file, unsigned long reqprot,
			unsigned long prot, unsigned long flags,
			unsigned long prot, unsigned long flags);
			unsigned long addr, unsigned long addr_only);
int security_mmap_addr(unsigned long addr);
int security_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot,
int security_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot,
			   unsigned long prot);
			   unsigned long prot);
int security_file_lock(struct file *file, unsigned int cmd);
int security_file_lock(struct file *file, unsigned int cmd);
@@ -2182,11 +2183,14 @@ static inline int security_file_ioctl(struct file *file, unsigned int cmd,
	return 0;
	return 0;
}
}


static inline int security_file_mmap(struct file *file, unsigned long reqprot,
static inline int security_mmap_file(struct file *file, unsigned long reqprot,
				     unsigned long prot,
				     unsigned long prot,
				     unsigned long flags,
				     unsigned long flags)
				     unsigned long addr,
{
				     unsigned long addr_only)
	return 0;
}

static inline int security_mmap_addr(unsigned long addr)
{
{
	return cap_mmap_addr(addr);
	return cap_mmap_addr(addr);
}
}
+8 −4
Original line number Original line Diff line number Diff line
@@ -1101,7 +1101,11 @@ static unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
		}
		}
	}
	}


	error = security_file_mmap(file, reqprot, prot, flags, addr, 0);
	error = security_mmap_addr(addr);
	if (error)
		return error;

	error = security_mmap_file(file, reqprot, prot, flags);
	if (error)
	if (error)
		return error;
		return error;


@@ -1817,7 +1821,7 @@ int expand_downwards(struct vm_area_struct *vma,
		return -ENOMEM;
		return -ENOMEM;


	address &= PAGE_MASK;
	address &= PAGE_MASK;
	error = security_file_mmap(NULL, 0, 0, 0, address, 1);
	error = security_mmap_addr(address);
	if (error)
	if (error)
		return error;
		return error;


@@ -2205,7 +2209,7 @@ static unsigned long do_brk(unsigned long addr, unsigned long len)
	if (!len)
	if (!len)
		return addr;
		return addr;


	error = security_file_mmap(NULL, 0, 0, 0, addr, 1);
	error = security_mmap_addr(addr);
	if (error)
	if (error)
		return error;
		return error;


@@ -2561,7 +2565,7 @@ int install_special_mapping(struct mm_struct *mm,
	vma->vm_ops = &special_mapping_vmops;
	vma->vm_ops = &special_mapping_vmops;
	vma->vm_private_data = pages;
	vma->vm_private_data = pages;


	ret = security_file_mmap(NULL, 0, 0, 0, vma->vm_start, 1);
	ret = security_mmap_addr(vma->vm_start);
	if (ret)
	if (ret)
		goto out;
		goto out;


+2 −2
Original line number Original line Diff line number Diff line
@@ -371,7 +371,7 @@ static unsigned long mremap_to(unsigned long addr,
	if ((addr <= new_addr) && (addr+old_len) > new_addr)
	if ((addr <= new_addr) && (addr+old_len) > new_addr)
		goto out;
		goto out;


	ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1);
	ret = security_mmap_addr(new_addr);
	if (ret)
	if (ret)
		goto out;
		goto out;


@@ -532,7 +532,7 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len,
			goto out;
			goto out;
		}
		}


		ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1);
		ret = security_mmap_addr(new_addr);
		if (ret)
		if (ret)
			goto out;
			goto out;
		ret = move_vma(vma, addr, old_len, new_len, new_addr);
		ret = move_vma(vma, addr, old_len, new_len, new_addr);
+4 −1
Original line number Original line Diff line number Diff line
@@ -1047,7 +1047,10 @@ static int validate_mmap_request(struct file *file,
	}
	}


	/* allow the security API to have its say */
	/* allow the security API to have its say */
	ret = security_file_mmap(file, reqprot, prot, flags, addr, 0);
	ret = security_mmap_addr(addr);
	if (ret < 0)
		return ret;
	ret = security_mmap_file(file, reqprot, prot, flags);
	if (ret < 0)
	if (ret < 0)
		return ret;
		return ret;


Loading