diff options
-rw-r--r-- | include/linux/security.h | 7 | ||||
-rw-r--r-- | security/capability.c | 9 | ||||
-rw-r--r-- | security/commoncap.c | 30 |
3 files changed, 34 insertions, 12 deletions
diff --git a/include/linux/security.h b/include/linux/security.h index 5eff459b3833..ac4bc3760b46 100644 --- a/include/linux/security.h +++ b/include/linux/security.h | |||
@@ -66,6 +66,9 @@ extern int cap_inode_setxattr(struct dentry *dentry, const char *name, | |||
66 | extern int cap_inode_removexattr(struct dentry *dentry, const char *name); | 66 | extern int cap_inode_removexattr(struct dentry *dentry, const char *name); |
67 | extern int cap_inode_need_killpriv(struct dentry *dentry); | 67 | extern int cap_inode_need_killpriv(struct dentry *dentry); |
68 | extern int cap_inode_killpriv(struct dentry *dentry); | 68 | extern int cap_inode_killpriv(struct dentry *dentry); |
69 | extern int cap_file_mmap(struct file *file, unsigned long reqprot, | ||
70 | unsigned long prot, unsigned long flags, | ||
71 | unsigned long addr, unsigned long addr_only); | ||
69 | extern int cap_task_fix_setuid(struct cred *new, const struct cred *old, int flags); | 72 | extern int cap_task_fix_setuid(struct cred *new, const struct cred *old, int flags); |
70 | extern int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3, | 73 | extern int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3, |
71 | unsigned long arg4, unsigned long arg5); | 74 | unsigned long arg4, unsigned long arg5); |
@@ -2197,9 +2200,7 @@ static inline int security_file_mmap(struct file *file, unsigned long reqprot, | |||
2197 | unsigned long addr, | 2200 | unsigned long addr, |
2198 | unsigned long addr_only) | 2201 | unsigned long addr_only) |
2199 | { | 2202 | { |
2200 | if ((addr < mmap_min_addr) && !capable(CAP_SYS_RAWIO)) | 2203 | return cap_file_mmap(file, reqprot, prot, flags, addr, addr_only); |
2201 | return -EACCES; | ||
2202 | return 0; | ||
2203 | } | 2204 | } |
2204 | 2205 | ||
2205 | static inline int security_file_mprotect(struct vm_area_struct *vma, | 2206 | static inline int security_file_mprotect(struct vm_area_struct *vma, |
diff --git a/security/capability.c b/security/capability.c index 21b6cead6a8e..88f752e8152c 100644 --- a/security/capability.c +++ b/security/capability.c | |||
@@ -330,15 +330,6 @@ static int cap_file_ioctl(struct file *file, unsigned int command, | |||
330 | return 0; | 330 | return 0; |
331 | } | 331 | } |
332 | 332 | ||
333 | static int cap_file_mmap(struct file *file, unsigned long reqprot, | ||
334 | unsigned long prot, unsigned long flags, | ||
335 | unsigned long addr, unsigned long addr_only) | ||
336 | { | ||
337 | if ((addr < mmap_min_addr) && !capable(CAP_SYS_RAWIO)) | ||
338 | return -EACCES; | ||
339 | return 0; | ||
340 | } | ||
341 | |||
342 | static int cap_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot, | 333 | static int cap_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot, |
343 | unsigned long prot) | 334 | unsigned long prot) |
344 | { | 335 | { |
diff --git a/security/commoncap.c b/security/commoncap.c index 48b7e0228fa3..6bcf6e81e547 100644 --- a/security/commoncap.c +++ b/security/commoncap.c | |||
@@ -984,3 +984,33 @@ int cap_vm_enough_memory(struct mm_struct *mm, long pages) | |||
984 | cap_sys_admin = 1; | 984 | cap_sys_admin = 1; |
985 | return __vm_enough_memory(mm, pages, cap_sys_admin); | 985 | return __vm_enough_memory(mm, pages, cap_sys_admin); |
986 | } | 986 | } |
987 | |||
988 | /* | ||
989 | * cap_file_mmap - check if able to map given addr | ||
990 | * @file: unused | ||
991 | * @reqprot: unused | ||
992 | * @prot: unused | ||
993 | * @flags: unused | ||
994 | * @addr: address attempting to be mapped | ||
995 | * @addr_only: unused | ||
996 | * | ||
997 | * If the process is attempting to map memory below mmap_min_addr they need | ||
998 | * CAP_SYS_RAWIO. The other parameters to this function are unused by the | ||
999 | * capability security module. Returns 0 if this mapping should be allowed | ||
1000 | * -EPERM if not. | ||
1001 | */ | ||
1002 | int cap_file_mmap(struct file *file, unsigned long reqprot, | ||
1003 | unsigned long prot, unsigned long flags, | ||
1004 | unsigned long addr, unsigned long addr_only) | ||
1005 | { | ||
1006 | int ret = 0; | ||
1007 | |||
1008 | if (addr < mmap_min_addr) { | ||
1009 | ret = cap_capable(current, current_cred(), CAP_SYS_RAWIO, | ||
1010 | SECURITY_CAP_AUDIT); | ||
1011 | /* set PF_SUPERPRIV if it turns out we allow the low mmap */ | ||
1012 | if (ret == 0) | ||
1013 | current->flags |= PF_SUPERPRIV; | ||
1014 | } | ||
1015 | return ret; | ||
1016 | } | ||