Skip to content

Commit e546785

Browse files
author
Al Viro
committed
split ->file_mmap() into ->mmap_addr()/->mmap_file()
... i.e. file-dependent and address-dependent checks. Signed-off-by: Al Viro <[email protected]>
1 parent d007794 commit e546785

File tree

11 files changed

+64
-78
lines changed

11 files changed

+64
-78
lines changed

fs/exec.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -280,10 +280,6 @@ static int __bprm_mm_init(struct linux_binprm *bprm)
280280
vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
281281
INIT_LIST_HEAD(&vma->anon_vma_chain);
282282

283-
err = security_file_mmap(NULL, 0, 0, 0, vma->vm_start, 1);
284-
if (err)
285-
goto err;
286-
287283
err = insert_vm_struct(mm, vma);
288284
if (err)
289285
goto err;

include/linux/security.h

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,8 @@ extern int cap_inode_removexattr(struct dentry *dentry, const char *name);
8787
extern int cap_inode_need_killpriv(struct dentry *dentry);
8888
extern int cap_inode_killpriv(struct dentry *dentry);
8989
extern int cap_mmap_addr(unsigned long addr);
90-
extern int cap_file_mmap(struct file *file, unsigned long reqprot,
91-
unsigned long prot, unsigned long flags,
92-
unsigned long addr, unsigned long addr_only);
90+
extern int cap_mmap_file(struct file *file, unsigned long reqprot,
91+
unsigned long prot, unsigned long flags);
9392
extern int cap_task_fix_setuid(struct cred *new, const struct cred *old, int flags);
9493
extern int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3,
9594
unsigned long arg4, unsigned long arg5);
@@ -587,15 +586,17 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
587586
* simple integer value. When @arg represents a user space pointer, it
588587
* should never be used by the security module.
589588
* Return 0 if permission is granted.
590-
* @file_mmap :
589+
* @mmap_addr :
590+
* Check permissions for a mmap operation at @addr.
591+
* @addr contains virtual address that will be used for the operation.
592+
* Return 0 if permission is granted.
593+
* @mmap_file :
591594
* Check permissions for a mmap operation. The @file may be NULL, e.g.
592595
* if mapping anonymous memory.
593596
* @file contains the file structure for file to map (may be NULL).
594597
* @reqprot contains the protection requested by the application.
595598
* @prot contains the protection that will be applied by the kernel.
596599
* @flags contains the operational flags.
597-
* @addr contains virtual address that will be used for the operation.
598-
* @addr_only contains a boolean: 0 if file-backed VMA, otherwise 1.
599600
* Return 0 if permission is granted.
600601
* @file_mprotect:
601602
* Check permissions before changing memory access permissions.
@@ -1482,10 +1483,10 @@ struct security_operations {
14821483
void (*file_free_security) (struct file *file);
14831484
int (*file_ioctl) (struct file *file, unsigned int cmd,
14841485
unsigned long arg);
1485-
int (*file_mmap) (struct file *file,
1486+
int (*mmap_addr) (unsigned long addr);
1487+
int (*mmap_file) (struct file *file,
14861488
unsigned long reqprot, unsigned long prot,
1487-
unsigned long flags, unsigned long addr,
1488-
unsigned long addr_only);
1489+
unsigned long flags);
14891490
int (*file_mprotect) (struct vm_area_struct *vma,
14901491
unsigned long reqprot,
14911492
unsigned long prot);
@@ -1744,9 +1745,9 @@ int security_file_permission(struct file *file, int mask);
17441745
int security_file_alloc(struct file *file);
17451746
void security_file_free(struct file *file);
17461747
int security_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
1747-
int security_file_mmap(struct file *file, unsigned long reqprot,
1748-
unsigned long prot, unsigned long flags,
1749-
unsigned long addr, unsigned long addr_only);
1748+
int security_mmap_file(struct file *file, unsigned long reqprot,
1749+
unsigned long prot, unsigned long flags);
1750+
int security_mmap_addr(unsigned long addr);
17501751
int security_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot,
17511752
unsigned long prot);
17521753
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,
21822183
return 0;
21832184
}
21842185

2185-
static inline int security_file_mmap(struct file *file, unsigned long reqprot,
2186+
static inline int security_mmap_file(struct file *file, unsigned long reqprot,
21862187
unsigned long prot,
2187-
unsigned long flags,
2188-
unsigned long addr,
2189-
unsigned long addr_only)
2188+
unsigned long flags)
2189+
{
2190+
return 0;
2191+
}
2192+
2193+
static inline int security_mmap_addr(unsigned long addr)
21902194
{
21912195
return cap_mmap_addr(addr);
21922196
}

mm/mmap.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1101,7 +1101,11 @@ static unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
11011101
}
11021102
}
11031103

1104-
error = security_file_mmap(file, reqprot, prot, flags, addr, 0);
1104+
error = security_mmap_addr(addr);
1105+
if (error)
1106+
return error;
1107+
1108+
error = security_mmap_file(file, reqprot, prot, flags);
11051109
if (error)
11061110
return error;
11071111

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

18191823
address &= PAGE_MASK;
1820-
error = security_file_mmap(NULL, 0, 0, 0, address, 1);
1824+
error = security_mmap_addr(address);
18211825
if (error)
18221826
return error;
18231827

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

2208-
error = security_file_mmap(NULL, 0, 0, 0, addr, 1);
2212+
error = security_mmap_addr(addr);
22092213
if (error)
22102214
return error;
22112215

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

2564-
ret = security_file_mmap(NULL, 0, 0, 0, vma->vm_start, 1);
2568+
ret = security_mmap_addr(vma->vm_start);
25652569
if (ret)
25662570
goto out;
25672571

mm/mremap.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ static unsigned long mremap_to(unsigned long addr,
371371
if ((addr <= new_addr) && (addr+old_len) > new_addr)
372372
goto out;
373373

374-
ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1);
374+
ret = security_mmap_addr(new_addr);
375375
if (ret)
376376
goto out;
377377

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

535-
ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1);
535+
ret = security_mmap_addr(new_addr);
536536
if (ret)
537537
goto out;
538538
ret = move_vma(vma, addr, old_len, new_len, new_addr);

mm/nommu.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1047,7 +1047,10 @@ static int validate_mmap_request(struct file *file,
10471047
}
10481048

10491049
/* allow the security API to have its say */
1050-
ret = security_file_mmap(file, reqprot, prot, flags, addr, 0);
1050+
ret = security_mmap_addr(addr);
1051+
if (ret < 0)
1052+
return ret;
1053+
ret = security_mmap_file(file, reqprot, prot, flags);
10511054
if (ret < 0)
10521055
return ret;
10531056

security/apparmor/lsm.c

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -490,17 +490,9 @@ static int common_mmap(int op, struct file *file, unsigned long prot,
490490
return common_file_perm(op, file, mask);
491491
}
492492

493-
static int apparmor_file_mmap(struct file *file, unsigned long reqprot,
494-
unsigned long prot, unsigned long flags,
495-
unsigned long addr, unsigned long addr_only)
493+
static int apparmor_mmap_file(struct file *file, unsigned long reqprot,
494+
unsigned long prot, unsigned long flags)
496495
{
497-
int rc = 0;
498-
499-
/* do DAC check */
500-
rc = cap_mmap_addr(addr);
501-
if (rc || addr_only)
502-
return rc;
503-
504496
return common_mmap(OP_FMMAP, file, prot, flags);
505497
}
506498

@@ -646,7 +638,8 @@ static struct security_operations apparmor_ops = {
646638
.file_permission = apparmor_file_permission,
647639
.file_alloc_security = apparmor_file_alloc_security,
648640
.file_free_security = apparmor_file_free_security,
649-
.file_mmap = apparmor_file_mmap,
641+
.mmap_file = apparmor_mmap_file,
642+
.mmap_addr = cap_mmap_addr,
650643
.file_mprotect = apparmor_file_mprotect,
651644
.file_lock = apparmor_file_lock,
652645

security/capability.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -949,7 +949,8 @@ void __init security_fixup_ops(struct security_operations *ops)
949949
set_to_cap_if_null(ops, file_alloc_security);
950950
set_to_cap_if_null(ops, file_free_security);
951951
set_to_cap_if_null(ops, file_ioctl);
952-
set_to_cap_if_null(ops, file_mmap);
952+
set_to_cap_if_null(ops, mmap_addr);
953+
set_to_cap_if_null(ops, mmap_file);
953954
set_to_cap_if_null(ops, file_mprotect);
954955
set_to_cap_if_null(ops, file_lock);
955956
set_to_cap_if_null(ops, file_fcntl);

security/commoncap.c

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -980,23 +980,8 @@ int cap_mmap_addr(unsigned long addr)
980980
return ret;
981981
}
982982

983-
/*
984-
* cap_file_mmap - check if able to map given addr
985-
* @file: unused
986-
* @reqprot: unused
987-
* @prot: unused
988-
* @flags: unused
989-
* @addr: address attempting to be mapped
990-
* @addr_only: unused
991-
*
992-
* If the process is attempting to map memory below dac_mmap_min_addr they need
993-
* CAP_SYS_RAWIO. The other parameters to this function are unused by the
994-
* capability security module. Returns 0 if this mapping should be allowed
995-
* -EPERM if not.
996-
*/
997-
int cap_file_mmap(struct file *file, unsigned long reqprot,
998-
unsigned long prot, unsigned long flags,
999-
unsigned long addr, unsigned long addr_only)
983+
int cap_mmap_file(struct file *file, unsigned long reqprot,
984+
unsigned long prot, unsigned long flags)
1000985
{
1001-
return cap_mmap_addr(addr);
986+
return 0;
1002987
}

security/security.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -657,18 +657,22 @@ int security_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
657657
return security_ops->file_ioctl(file, cmd, arg);
658658
}
659659

660-
int security_file_mmap(struct file *file, unsigned long reqprot,
661-
unsigned long prot, unsigned long flags,
662-
unsigned long addr, unsigned long addr_only)
660+
int security_mmap_file(struct file *file, unsigned long reqprot,
661+
unsigned long prot, unsigned long flags)
663662
{
664663
int ret;
665664

666-
ret = security_ops->file_mmap(file, reqprot, prot, flags, addr, addr_only);
665+
ret = security_ops->mmap_file(file, reqprot, prot, flags);
667666
if (ret)
668667
return ret;
669668
return ima_file_mmap(file, prot);
670669
}
671670

671+
int security_mmap_addr(unsigned long addr)
672+
{
673+
return security_ops->mmap_addr(addr);
674+
}
675+
672676
int security_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot,
673677
unsigned long prot)
674678
{

security/selinux/hooks.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3083,9 +3083,7 @@ static int file_map_prot_check(struct file *file, unsigned long prot, int shared
30833083
return rc;
30843084
}
30853085

3086-
static int selinux_file_mmap(struct file *file, unsigned long reqprot,
3087-
unsigned long prot, unsigned long flags,
3088-
unsigned long addr, unsigned long addr_only)
3086+
static int selinux_mmap_addr(unsigned long addr)
30893087
{
30903088
int rc = 0;
30913089
u32 sid = current_sid();
@@ -3104,10 +3102,12 @@ static int selinux_file_mmap(struct file *file, unsigned long reqprot,
31043102
}
31053103

31063104
/* do DAC check on address space usage */
3107-
rc = cap_mmap_addr(addr);
3108-
if (rc || addr_only)
3109-
return rc;
3105+
return cap_mmap_addr(addr);
3106+
}
31103107

3108+
static int selinux_mmap_file(struct file *file, unsigned long reqprot,
3109+
unsigned long prot, unsigned long flags)
3110+
{
31113111
if (selinux_checkreqprot)
31123112
prot = reqprot;
31133113

@@ -5570,7 +5570,8 @@ static struct security_operations selinux_ops = {
55705570
.file_alloc_security = selinux_file_alloc_security,
55715571
.file_free_security = selinux_file_free_security,
55725572
.file_ioctl = selinux_file_ioctl,
5573-
.file_mmap = selinux_file_mmap,
5573+
.mmap_file = selinux_mmap_file,
5574+
.mmap_addr = selinux_mmap_addr,
55745575
.file_mprotect = selinux_file_mprotect,
55755576
.file_lock = selinux_file_lock,
55765577
.file_fcntl = selinux_file_fcntl,

0 commit comments

Comments
 (0)