mirror of
https://gitee.com/openharmony/kernel_linux
synced 2025-04-16 06:10:42 +00:00
split ->file_mmap() into ->mmap_addr()/->mmap_file()
... i.e. file-dependent and address-dependent checks. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
d007794a18
commit
e5467859f7
@ -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;
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
12
mm/mmap.c
12
mm/mmap.c
@ -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;
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -490,17 +490,9 @@ static int common_mmap(int op, struct file *file, unsigned long prot,
|
|||||||
return common_file_perm(op, file, mask);
|
return common_file_perm(op, file, mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int apparmor_file_mmap(struct file *file, unsigned long reqprot,
|
static int apparmor_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 rc = 0;
|
|
||||||
|
|
||||||
/* do DAC check */
|
|
||||||
rc = cap_mmap_addr(addr);
|
|
||||||
if (rc || addr_only)
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
return common_mmap(OP_FMMAP, file, prot, flags);
|
return common_mmap(OP_FMMAP, file, prot, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -646,7 +638,8 @@ static struct security_operations apparmor_ops = {
|
|||||||
.file_permission = apparmor_file_permission,
|
.file_permission = apparmor_file_permission,
|
||||||
.file_alloc_security = apparmor_file_alloc_security,
|
.file_alloc_security = apparmor_file_alloc_security,
|
||||||
.file_free_security = apparmor_file_free_security,
|
.file_free_security = apparmor_file_free_security,
|
||||||
.file_mmap = apparmor_file_mmap,
|
.mmap_file = apparmor_mmap_file,
|
||||||
|
.mmap_addr = cap_mmap_addr,
|
||||||
.file_mprotect = apparmor_file_mprotect,
|
.file_mprotect = apparmor_file_mprotect,
|
||||||
.file_lock = apparmor_file_lock,
|
.file_lock = apparmor_file_lock,
|
||||||
|
|
||||||
|
@ -949,7 +949,8 @@ void __init security_fixup_ops(struct security_operations *ops)
|
|||||||
set_to_cap_if_null(ops, file_alloc_security);
|
set_to_cap_if_null(ops, file_alloc_security);
|
||||||
set_to_cap_if_null(ops, file_free_security);
|
set_to_cap_if_null(ops, file_free_security);
|
||||||
set_to_cap_if_null(ops, file_ioctl);
|
set_to_cap_if_null(ops, file_ioctl);
|
||||||
set_to_cap_if_null(ops, file_mmap);
|
set_to_cap_if_null(ops, mmap_addr);
|
||||||
|
set_to_cap_if_null(ops, mmap_file);
|
||||||
set_to_cap_if_null(ops, file_mprotect);
|
set_to_cap_if_null(ops, file_mprotect);
|
||||||
set_to_cap_if_null(ops, file_lock);
|
set_to_cap_if_null(ops, file_lock);
|
||||||
set_to_cap_if_null(ops, file_fcntl);
|
set_to_cap_if_null(ops, file_fcntl);
|
||||||
|
@ -980,23 +980,8 @@ int cap_mmap_addr(unsigned long addr)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
int cap_mmap_file(struct file *file, unsigned long reqprot,
|
||||||
* cap_file_mmap - check if able to map given addr
|
unsigned long prot, unsigned long flags)
|
||||||
* @file: unused
|
|
||||||
* @reqprot: unused
|
|
||||||
* @prot: unused
|
|
||||||
* @flags: unused
|
|
||||||
* @addr: address attempting to be mapped
|
|
||||||
* @addr_only: unused
|
|
||||||
*
|
|
||||||
* If the process is attempting to map memory below dac_mmap_min_addr they need
|
|
||||||
* CAP_SYS_RAWIO. The other parameters to this function are unused by the
|
|
||||||
* capability security module. Returns 0 if this mapping should be allowed
|
|
||||||
* -EPERM if not.
|
|
||||||
*/
|
|
||||||
int cap_file_mmap(struct file *file, unsigned long reqprot,
|
|
||||||
unsigned long prot, unsigned long flags,
|
|
||||||
unsigned long addr, unsigned long addr_only)
|
|
||||||
{
|
{
|
||||||
return cap_mmap_addr(addr);
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -657,18 +657,22 @@ int security_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
|||||||
return security_ops->file_ioctl(file, cmd, arg);
|
return security_ops->file_ioctl(file, cmd, 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 ret;
|
int ret;
|
||||||
|
|
||||||
ret = security_ops->file_mmap(file, reqprot, prot, flags, addr, addr_only);
|
ret = security_ops->mmap_file(file, reqprot, prot, flags);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
return ima_file_mmap(file, prot);
|
return ima_file_mmap(file, prot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int security_mmap_addr(unsigned long addr)
|
||||||
|
{
|
||||||
|
return security_ops->mmap_addr(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)
|
||||||
{
|
{
|
||||||
|
@ -3083,9 +3083,7 @@ error:
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int selinux_file_mmap(struct file *file, unsigned long reqprot,
|
static int selinux_mmap_addr(unsigned long addr)
|
||||||
unsigned long prot, unsigned long flags,
|
|
||||||
unsigned long addr, unsigned long addr_only)
|
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
u32 sid = current_sid();
|
u32 sid = current_sid();
|
||||||
@ -3104,10 +3102,12 @@ static int selinux_file_mmap(struct file *file, unsigned long reqprot,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* do DAC check on address space usage */
|
/* do DAC check on address space usage */
|
||||||
rc = cap_mmap_addr(addr);
|
return cap_mmap_addr(addr);
|
||||||
if (rc || addr_only)
|
}
|
||||||
return rc;
|
|
||||||
|
|
||||||
|
static int selinux_mmap_file(struct file *file, unsigned long reqprot,
|
||||||
|
unsigned long prot, unsigned long flags)
|
||||||
|
{
|
||||||
if (selinux_checkreqprot)
|
if (selinux_checkreqprot)
|
||||||
prot = reqprot;
|
prot = reqprot;
|
||||||
|
|
||||||
@ -5570,7 +5570,8 @@ static struct security_operations selinux_ops = {
|
|||||||
.file_alloc_security = selinux_file_alloc_security,
|
.file_alloc_security = selinux_file_alloc_security,
|
||||||
.file_free_security = selinux_file_free_security,
|
.file_free_security = selinux_file_free_security,
|
||||||
.file_ioctl = selinux_file_ioctl,
|
.file_ioctl = selinux_file_ioctl,
|
||||||
.file_mmap = selinux_file_mmap,
|
.mmap_file = selinux_mmap_file,
|
||||||
|
.mmap_addr = selinux_mmap_addr,
|
||||||
.file_mprotect = selinux_file_mprotect,
|
.file_mprotect = selinux_file_mprotect,
|
||||||
.file_lock = selinux_file_lock,
|
.file_lock = selinux_file_lock,
|
||||||
.file_fcntl = selinux_file_fcntl,
|
.file_fcntl = selinux_file_fcntl,
|
||||||
|
@ -1171,7 +1171,7 @@ static int smack_file_fcntl(struct file *file, unsigned int cmd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* smack_file_mmap :
|
* smack_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).
|
||||||
@ -1180,10 +1180,9 @@ static int smack_file_fcntl(struct file *file, unsigned int cmd,
|
|||||||
* @flags contains the operational flags.
|
* @flags contains the operational flags.
|
||||||
* Return 0 if permission is granted.
|
* Return 0 if permission is granted.
|
||||||
*/
|
*/
|
||||||
static int smack_file_mmap(struct file *file,
|
static int smack_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)
|
|
||||||
{
|
{
|
||||||
struct smack_known *skp;
|
struct smack_known *skp;
|
||||||
struct smack_rule *srp;
|
struct smack_rule *srp;
|
||||||
@ -1198,11 +1197,6 @@ static int smack_file_mmap(struct file *file,
|
|||||||
int tmay;
|
int tmay;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/* do DAC check on address space usage */
|
|
||||||
rc = cap_mmap_addr(addr);
|
|
||||||
if (rc || addr_only)
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
if (file == NULL || file->f_dentry == NULL)
|
if (file == NULL || file->f_dentry == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -3482,7 +3476,8 @@ struct security_operations smack_ops = {
|
|||||||
.file_ioctl = smack_file_ioctl,
|
.file_ioctl = smack_file_ioctl,
|
||||||
.file_lock = smack_file_lock,
|
.file_lock = smack_file_lock,
|
||||||
.file_fcntl = smack_file_fcntl,
|
.file_fcntl = smack_file_fcntl,
|
||||||
.file_mmap = smack_file_mmap,
|
.mmap_file = smack_mmap_file,
|
||||||
|
.mmap_addr = cap_mmap_addr,
|
||||||
.file_set_fowner = smack_file_set_fowner,
|
.file_set_fowner = smack_file_set_fowner,
|
||||||
.file_send_sigiotask = smack_file_send_sigiotask,
|
.file_send_sigiotask = smack_file_send_sigiotask,
|
||||||
.file_receive = smack_file_receive,
|
.file_receive = smack_file_receive,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user