Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security

Pull security subsystem updates for 3.4 from James Morris:
"The main addition here is the new Yama security module from Kees Cook,
which was discussed at the Linux Security Summit last year. Its
purpose is to collect miscellaneous DAC security enhancements in one
place. This also marks a departure in policy for LSM modules, which
were previously limited to being standalone access control systems.
Chromium OS is using Yama, and I believe there are plans for Ubuntu,
at least.

This patchset also includes maintenance updates for AppArmor, TOMOYO
and others."

Fix trivial conflict in <net/sock.h> due to the jumo_label->static_key
rename.

* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: (38 commits)
AppArmor: Fix location of const qualifier on generated string tables
TOMOYO: Return error if fails to delete a domain
AppArmor: add const qualifiers to string arrays
AppArmor: Add ability to load extended policy
TOMOYO: Return appropriate value to poll().
AppArmor: Move path failure information into aa_get_name and rename
AppArmor: Update dfa matching routines.
AppArmor: Minor cleanup of d_namespace_path to consolidate error handling
AppArmor: Retrieve the dentry_path for error reporting when path lookup fails
AppArmor: Add const qualifiers to generated string tables
AppArmor: Fix oops in policy unpack auditing
AppArmor: Fix error returned when a path lookup is disconnected
KEYS: testing wrong bit for KEY_FLAG_REVOKED
TOMOYO: Fix mount flags checking order.
security: fix ima kconfig warning
AppArmor: Fix the error case for chroot relative path name lookup
AppArmor: fix mapping of META_READ to audit and quiet flags
AppArmor: Fix underflow in xindex calculation
AppArmor: Fix dropping of allowed operations that are force audited
AppArmor: Add mising end of structure test to caps unpacking
...

+1035 -251
+4
Documentation/networking/dns_resolver.txt
··· 102 102 If _expiry is non-NULL, the expiry time (TTL) of the result will be 103 103 returned also. 104 104 105 + The kernel maintains an internal keyring in which it caches looked up keys. 106 + This can be cleared by any process that has the CAP_SYS_ADMIN capability by 107 + the use of KEYCTL_KEYRING_CLEAR on the keyring ID. 108 + 105 109 106 110 =============================== 107 111 READING DNS KEYS FROM USERSPACE
+2
Documentation/security/00-INDEX
··· 6 6 - how to get started with the SELinux security enhancement. 7 7 Smack.txt 8 8 - documentation on the Smack Linux Security Module. 9 + Yama.txt 10 + - documentation on the Yama Linux Security Module. 9 11 apparmor.txt 10 12 - documentation on the AppArmor security extension. 11 13 credentials.txt
+65
Documentation/security/Yama.txt
··· 1 + Yama is a Linux Security Module that collects a number of system-wide DAC 2 + security protections that are not handled by the core kernel itself. To 3 + select it at boot time, specify "security=yama" (though this will disable 4 + any other LSM). 5 + 6 + Yama is controlled through sysctl in /proc/sys/kernel/yama: 7 + 8 + - ptrace_scope 9 + 10 + ============================================================== 11 + 12 + ptrace_scope: 13 + 14 + As Linux grows in popularity, it will become a larger target for 15 + malware. One particularly troubling weakness of the Linux process 16 + interfaces is that a single user is able to examine the memory and 17 + running state of any of their processes. For example, if one application 18 + (e.g. Pidgin) was compromised, it would be possible for an attacker to 19 + attach to other running processes (e.g. Firefox, SSH sessions, GPG agent, 20 + etc) to extract additional credentials and continue to expand the scope 21 + of their attack without resorting to user-assisted phishing. 22 + 23 + This is not a theoretical problem. SSH session hijacking 24 + (http://www.storm.net.nz/projects/7) and arbitrary code injection 25 + (http://c-skills.blogspot.com/2007/05/injectso.html) attacks already 26 + exist and remain possible if ptrace is allowed to operate as before. 27 + Since ptrace is not commonly used by non-developers and non-admins, system 28 + builders should be allowed the option to disable this debugging system. 29 + 30 + For a solution, some applications use prctl(PR_SET_DUMPABLE, ...) to 31 + specifically disallow such ptrace attachment (e.g. ssh-agent), but many 32 + do not. A more general solution is to only allow ptrace directly from a 33 + parent to a child process (i.e. direct "gdb EXE" and "strace EXE" still 34 + work), or with CAP_SYS_PTRACE (i.e. "gdb --pid=PID", and "strace -p PID" 35 + still work as root). 36 + 37 + For software that has defined application-specific relationships 38 + between a debugging process and its inferior (crash handlers, etc), 39 + prctl(PR_SET_PTRACER, pid, ...) can be used. An inferior can declare which 40 + other process (and its descendents) are allowed to call PTRACE_ATTACH 41 + against it. Only one such declared debugging process can exists for 42 + each inferior at a time. For example, this is used by KDE, Chromium, and 43 + Firefox's crash handlers, and by Wine for allowing only Wine processes 44 + to ptrace each other. If a process wishes to entirely disable these ptrace 45 + restrictions, it can call prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, ...) 46 + so that any otherwise allowed process (even those in external pid namespaces) 47 + may attach. 48 + 49 + The sysctl settings are: 50 + 51 + 0 - classic ptrace permissions: a process can PTRACE_ATTACH to any other 52 + process running under the same uid, as long as it is dumpable (i.e. 53 + did not transition uids, start privileged, or have called 54 + prctl(PR_SET_DUMPABLE...) already). 55 + 56 + 1 - restricted ptrace: a process must have a predefined relationship 57 + with the inferior it wants to call PTRACE_ATTACH on. By default, 58 + this relationship is that of only its descendants when the above 59 + classic criteria is also met. To change the relationship, an 60 + inferior can call prctl(PR_SET_PTRACER, debugger, ...) to declare 61 + an allowed debugger PID to call PTRACE_ATTACH on the inferior. 62 + 63 + The original children-only logic was based on the restrictions in grsecurity. 64 + 65 + ==============================================================
+4
Documentation/security/keys.txt
··· 554 554 process must have write permission on the keyring, and it must be a 555 555 keyring (or else error ENOTDIR will result). 556 556 557 + This function can also be used to clear special kernel keyrings if they 558 + are appropriately marked if the user has CAP_SYS_ADMIN capability. The 559 + DNS resolver cache keyring is an example of this. 560 + 557 561 558 562 (*) Link a key into a keyring: 559 563
-1
drivers/char/tpm/Kconfig
··· 5 5 menuconfig TCG_TPM 6 6 tristate "TPM Hardware Support" 7 7 depends on HAS_IOMEM 8 - depends on EXPERIMENTAL 9 8 select SECURITYFS 10 9 ---help--- 11 10 If you have a TPM security chip in your system, which
+2 -1
drivers/char/tpm/tpm.c
··· 1221 1221 ret_size = atomic_read(&chip->data_pending); 1222 1222 atomic_set(&chip->data_pending, 0); 1223 1223 if (ret_size > 0) { /* relay data */ 1224 + ssize_t orig_ret_size = ret_size; 1224 1225 if (size < ret_size) 1225 1226 ret_size = size; 1226 1227 1227 1228 mutex_lock(&chip->buffer_mutex); 1228 1229 rc = copy_to_user(buf, chip->data_buffer, ret_size); 1229 - memset(chip->data_buffer, 0, ret_size); 1230 + memset(chip->data_buffer, 0, orig_ret_size); 1230 1231 if (rc) 1231 1232 ret_size = -EFAULT; 1232 1233
+2
drivers/char/tpm/tpm.h
··· 99 99 wait_queue_head_t int_queue; 100 100 }; 101 101 102 + #define TPM_VID_INTEL 0x8086 103 + 102 104 struct tpm_chip { 103 105 struct device *dev; /* Device stuff */ 104 106
+10 -7
drivers/char/tpm/tpm_tis.c
··· 367 367 0x00, 0x00, 0x00, 0xf1 368 368 }; 369 369 size_t len = sizeof(cmd_getticks); 370 - int rem_itpm = itpm; 370 + bool rem_itpm = itpm; 371 + u16 vendor = ioread16(chip->vendor.iobase + TPM_DID_VID(0)); 372 + 373 + /* probe only iTPMS */ 374 + if (vendor != TPM_VID_INTEL) 375 + return 0; 371 376 372 377 itpm = 0; 373 378 ··· 395 390 out: 396 391 itpm = rem_itpm; 397 392 tpm_tis_ready(chip); 398 - /* some TPMs need a break here otherwise they will not work 399 - * correctly on the immediately subsequent command */ 400 - msleep(chip->vendor.timeout_b); 401 393 release_locality(chip, chip->vendor.locality, 0); 402 394 403 395 return rc; ··· 510 508 resource_size_t len, unsigned int irq) 511 509 { 512 510 u32 vendor, intfcaps, intmask; 513 - int rc, i, irq_s, irq_e; 511 + int rc, i, irq_s, irq_e, probe; 514 512 struct tpm_chip *chip; 515 513 516 514 if (!(chip = tpm_register_hardware(dev, &tpm_tis))) ··· 540 538 vendor >> 16, ioread8(chip->vendor.iobase + TPM_RID(0))); 541 539 542 540 if (!itpm) { 543 - itpm = probe_itpm(chip); 544 - if (itpm < 0) { 541 + probe = probe_itpm(chip); 542 + if (probe < 0) { 545 543 rc = -ENODEV; 546 544 goto out_err; 547 545 } 546 + itpm = (probe == 0) ? 0 : 1; 548 547 } 549 548 550 549 if (itpm)
+1
drivers/net/macvtap.c
··· 13 13 #include <linux/init.h> 14 14 #include <linux/wait.h> 15 15 #include <linux/cdev.h> 16 + #include <linux/idr.h> 16 17 #include <linux/fs.h> 17 18 18 19 #include <net/net_namespace.h>
+1
drivers/target/iscsi/iscsi_target.c
··· 23 23 #include <linux/crypto.h> 24 24 #include <linux/completion.h> 25 25 #include <linux/module.h> 26 + #include <linux/idr.h> 26 27 #include <asm/unaligned.h> 27 28 #include <scsi/scsi_device.h> 28 29 #include <scsi/iscsi_proto.h>
+1
drivers/target/iscsi/iscsi_target_login.c
··· 21 21 #include <linux/string.h> 22 22 #include <linux/kthread.h> 23 23 #include <linux/crypto.h> 24 + #include <linux/idr.h> 24 25 #include <scsi/iscsi_proto.h> 25 26 #include <target/target_core_base.h> 26 27 #include <target/target_core_fabric.h>
+1
fs/cifs/cifsacl.c
··· 556 556 557 557 /* instruct request_key() to use this special keyring as a cache for 558 558 * the results it looks up */ 559 + set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags); 559 560 cred->thread_keyring = keyring; 560 561 cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING; 561 562 root_cred = cred;
+1
fs/nfs/client.c
··· 36 36 #include <linux/inet.h> 37 37 #include <linux/in6.h> 38 38 #include <linux/slab.h> 39 + #include <linux/idr.h> 39 40 #include <net/ipv6.h> 40 41 #include <linux/nfs_xdr.h> 41 42 #include <linux/sunrpc/bc_xprt.h>
+1
fs/nfs/idmap.c
··· 198 198 if (ret < 0) 199 199 goto failed_put_key; 200 200 201 + set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags); 201 202 cred->thread_keyring = keyring; 202 203 cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING; 203 204 id_resolver_cache = cred;
+2
fs/proc/proc_sysctl.c
··· 6 6 #include <linux/poll.h> 7 7 #include <linux/proc_fs.h> 8 8 #include <linux/security.h> 9 + #include <linux/sched.h> 9 10 #include <linux/namei.h> 11 + #include <linux/mm.h> 10 12 #include "internal.h" 11 13 12 14 static const struct dentry_operations proc_sys_dentry_operations;
+1
fs/quota/dquot.c
··· 71 71 #include <linux/module.h> 72 72 #include <linux/proc_fs.h> 73 73 #include <linux/security.h> 74 + #include <linux/sched.h> 74 75 #include <linux/kmod.h> 75 76 #include <linux/namei.h> 76 77 #include <linux/capability.h>
+1
fs/super.c
··· 32 32 #include <linux/backing-dev.h> 33 33 #include <linux/rculist_bl.h> 34 34 #include <linux/cleancache.h> 35 + #include <linux/fsnotify.h> 35 36 #include "internal.h" 36 37 37 38
+1
include/linux/key.h
··· 155 155 #define KEY_FLAG_IN_QUOTA 3 /* set if key consumes quota */ 156 156 #define KEY_FLAG_USER_CONSTRUCT 4 /* set if key is being constructed in userspace */ 157 157 #define KEY_FLAG_NEGATIVE 5 /* set if key is negative */ 158 + #define KEY_FLAG_ROOT_CAN_CLEAR 6 /* set if key can be cleared by root without permission */ 158 159 159 160 /* the description string 160 161 * - this is used to match a key against search criteria
+7
include/linux/prctl.h
··· 114 114 # define PR_SET_MM_START_BRK 6 115 115 # define PR_SET_MM_BRK 7 116 116 117 + /* 118 + * Set specific pid that is allowed to ptrace the current task. 119 + * A value of 0 mean "no process". 120 + */ 121 + #define PR_SET_PTRACER 0x59616d61 122 + # define PR_SET_PTRACER_ANY ((unsigned long)-1) 123 + 117 124 #endif /* _LINUX_PRCTL_H */
+38 -42
include/linux/security.h
··· 22 22 #ifndef __LINUX_SECURITY_H 23 23 #define __LINUX_SECURITY_H 24 24 25 - #include <linux/fs.h> 26 - #include <linux/fsnotify.h> 27 - #include <linux/binfmts.h> 28 - #include <linux/dcache.h> 29 - #include <linux/signal.h> 30 - #include <linux/resource.h> 31 - #include <linux/sem.h> 32 - #include <linux/shm.h> 33 - #include <linux/mm.h> /* PAGE_ALIGN */ 34 - #include <linux/msg.h> 35 - #include <linux/sched.h> 36 25 #include <linux/key.h> 37 - #include <linux/xfrm.h> 26 + #include <linux/capability.h> 38 27 #include <linux/slab.h> 39 - #include <linux/xattr.h> 40 - #include <net/flow.h> 28 + #include <linux/err.h> 29 + 30 + struct linux_binprm; 31 + struct cred; 32 + struct rlimit; 33 + struct siginfo; 34 + struct sem_array; 35 + struct sembuf; 36 + struct kern_ipc_perm; 37 + struct audit_context; 38 + struct super_block; 39 + struct inode; 40 + struct dentry; 41 + struct file; 42 + struct vfsmount; 43 + struct path; 44 + struct qstr; 45 + struct nameidata; 46 + struct iattr; 47 + struct fown_struct; 48 + struct file_operations; 49 + struct shmid_kernel; 50 + struct msg_msg; 51 + struct msg_queue; 52 + struct xattr; 53 + struct xfrm_sec_ctx; 54 + struct mm_struct; 41 55 42 56 /* Maximum number of letters for an LSM name string */ 43 57 #define SECURITY_NAME_MAX 10 ··· 63 49 struct ctl_table; 64 50 struct audit_krule; 65 51 struct user_namespace; 52 + struct timezone; 66 53 67 54 /* 68 55 * These functions are in security/capability.c and are used ··· 146 131 #define LSM_UNSAFE_PTRACE_CAP 4 147 132 148 133 #ifdef CONFIG_MMU 149 - /* 150 - * If a hint addr is less than mmap_min_addr change hint to be as 151 - * low as possible but still greater than mmap_min_addr 152 - */ 153 - static inline unsigned long round_hint_to_min(unsigned long hint) 154 - { 155 - hint &= PAGE_MASK; 156 - if (((void *)hint != NULL) && 157 - (hint < mmap_min_addr)) 158 - return PAGE_ALIGN(mmap_min_addr); 159 - return hint; 160 - } 161 134 extern int mmap_min_addr_handler(struct ctl_table *table, int write, 162 135 void __user *buffer, size_t *lenp, loff_t *ppos); 163 136 #endif ··· 654 651 * manual page for definitions of the @clone_flags. 655 652 * @clone_flags contains the flags indicating what should be shared. 656 653 * Return 0 if permission is granted. 654 + * @task_free: 655 + * @task task being freed 656 + * Handle release of task-related resources. (Note that this can be called 657 + * from interrupt context.) 657 658 * @cred_alloc_blank: 658 659 * @cred points to the credentials. 659 660 * @gfp indicates the atomicity of any memory allocations. ··· 1500 1493 int (*dentry_open) (struct file *file, const struct cred *cred); 1501 1494 1502 1495 int (*task_create) (unsigned long clone_flags); 1496 + void (*task_free) (struct task_struct *task); 1503 1497 int (*cred_alloc_blank) (struct cred *cred, gfp_t gfp); 1504 1498 void (*cred_free) (struct cred *cred); 1505 1499 int (*cred_prepare)(struct cred *new, const struct cred *old, ··· 1682 1674 int security_quota_on(struct dentry *dentry); 1683 1675 int security_syslog(int type); 1684 1676 int security_settime(const struct timespec *ts, const struct timezone *tz); 1685 - int security_vm_enough_memory(long pages); 1686 1677 int security_vm_enough_memory_mm(struct mm_struct *mm, long pages); 1687 - int security_vm_enough_memory_kern(long pages); 1688 1678 int security_bprm_set_creds(struct linux_binprm *bprm); 1689 1679 int security_bprm_check(struct linux_binprm *bprm); 1690 1680 void security_bprm_committing_creds(struct linux_binprm *bprm); ··· 1758 1752 int security_file_receive(struct file *file); 1759 1753 int security_dentry_open(struct file *file, const struct cred *cred); 1760 1754 int security_task_create(unsigned long clone_flags); 1755 + void security_task_free(struct task_struct *task); 1761 1756 int security_cred_alloc_blank(struct cred *cred, gfp_t gfp); 1762 1757 void security_cred_free(struct cred *cred); 1763 1758 int security_prepare_creds(struct cred *new, const struct cred *old, gfp_t gfp); ··· 1903 1896 return cap_settime(ts, tz); 1904 1897 } 1905 1898 1906 - static inline int security_vm_enough_memory(long pages) 1907 - { 1908 - WARN_ON(current->mm == NULL); 1909 - return cap_vm_enough_memory(current->mm, pages); 1910 - } 1911 - 1912 1899 static inline int security_vm_enough_memory_mm(struct mm_struct *mm, long pages) 1913 1900 { 1914 - WARN_ON(mm == NULL); 1915 1901 return cap_vm_enough_memory(mm, pages); 1916 - } 1917 - 1918 - static inline int security_vm_enough_memory_kern(long pages) 1919 - { 1920 - /* If current->mm is a kernel thread then we will pass NULL, 1921 - for this specific case that is fine */ 1922 - return cap_vm_enough_memory(current->mm, pages); 1923 1902 } 1924 1903 1925 1904 static inline int security_bprm_set_creds(struct linux_binprm *bprm) ··· 2237 2244 { 2238 2245 return 0; 2239 2246 } 2247 + 2248 + static inline void security_task_free(struct task_struct *task) 2249 + { } 2240 2250 2241 2251 static inline int security_cred_alloc_blank(struct cred *cred, gfp_t gfp) 2242 2252 {
+2
include/net/sock.h
··· 56 56 #include <linux/memcontrol.h> 57 57 #include <linux/res_counter.h> 58 58 #include <linux/static_key.h> 59 + #include <linux/aio.h> 60 + #include <linux/sched.h> 59 61 60 62 #include <linux/filter.h> 61 63 #include <linux/rculist_nulls.h>
+2
ipc/msgutil.c
··· 13 13 #include <linux/security.h> 14 14 #include <linux/slab.h> 15 15 #include <linux/ipc.h> 16 + #include <linux/msg.h> 16 17 #include <linux/ipc_namespace.h> 18 + #include <linux/utsname.h> 17 19 #include <asm/uaccess.h> 18 20 19 21 #include "util.h"
+1
kernel/cred.c
··· 16 16 #include <linux/keyctl.h> 17 17 #include <linux/init_task.h> 18 18 #include <linux/security.h> 19 + #include <linux/binfmts.h> 19 20 #include <linux/cn_proc.h> 20 21 21 22 #if 0
+1
kernel/exit.c
··· 52 52 #include <linux/hw_breakpoint.h> 53 53 #include <linux/oom.h> 54 54 #include <linux/writeback.h> 55 + #include <linux/shm.h> 55 56 56 57 #include <asm/uaccess.h> 57 58 #include <asm/unistd.h>
+2 -1
kernel/fork.c
··· 193 193 WARN_ON(atomic_read(&tsk->usage)); 194 194 WARN_ON(tsk == current); 195 195 196 + security_task_free(tsk); 196 197 exit_creds(tsk); 197 198 delayacct_tsk_free(tsk); 198 199 put_signal_struct(tsk->signal); ··· 356 355 charge = 0; 357 356 if (mpnt->vm_flags & VM_ACCOUNT) { 358 357 unsigned int len = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT; 359 - if (security_vm_enough_memory(len)) 358 + if (security_vm_enough_memory_mm(oldmm, len)) /* sic */ 360 359 goto fail_nomem; 361 360 charge = len; 362 361 }
+1
kernel/sched/core.c
··· 71 71 #include <linux/ftrace.h> 72 72 #include <linux/slab.h> 73 73 #include <linux/init_task.h> 74 + #include <linux/binfmts.h> 74 75 75 76 #include <asm/tlb.h> 76 77 #include <asm/irq_regs.h>
+1
kernel/sysctl.c
··· 58 58 #include <linux/oom.h> 59 59 #include <linux/kmod.h> 60 60 #include <linux/capability.h> 61 + #include <linux/binfmts.h> 61 62 62 63 #include <asm/uaccess.h> 63 64 #include <asm/processor.h>
+15 -2
mm/mmap.c
··· 936 936 #endif /* CONFIG_PROC_FS */ 937 937 938 938 /* 939 + * If a hint addr is less than mmap_min_addr change hint to be as 940 + * low as possible but still greater than mmap_min_addr 941 + */ 942 + static inline unsigned long round_hint_to_min(unsigned long hint) 943 + { 944 + hint &= PAGE_MASK; 945 + if (((void *)hint != NULL) && 946 + (hint < mmap_min_addr)) 947 + return PAGE_ALIGN(mmap_min_addr); 948 + return hint; 949 + } 950 + 951 + /* 939 952 * The caller must hold down_write(&current->mm->mmap_sem). 940 953 */ 941 954 ··· 1248 1235 */ 1249 1236 if (accountable_mapping(file, vm_flags)) { 1250 1237 charged = len >> PAGE_SHIFT; 1251 - if (security_vm_enough_memory(charged)) 1238 + if (security_vm_enough_memory_mm(mm, charged)) 1252 1239 return -ENOMEM; 1253 1240 vm_flags |= VM_ACCOUNT; 1254 1241 } ··· 2193 2180 if (mm->map_count > sysctl_max_map_count) 2194 2181 return -ENOMEM; 2195 2182 2196 - if (security_vm_enough_memory(len >> PAGE_SHIFT)) 2183 + if (security_vm_enough_memory_mm(mm, len >> PAGE_SHIFT)) 2197 2184 return -ENOMEM; 2198 2185 2199 2186 /* Can we just expand an old private anonymous mapping? */
+1 -1
mm/mprotect.c
··· 168 168 if (!(oldflags & (VM_ACCOUNT|VM_WRITE|VM_HUGETLB| 169 169 VM_SHARED|VM_NORESERVE))) { 170 170 charged = nrpages; 171 - if (security_vm_enough_memory(charged)) 171 + if (security_vm_enough_memory_mm(mm, charged)) 172 172 return -ENOMEM; 173 173 newflags |= VM_ACCOUNT; 174 174 }
+1 -1
mm/mremap.c
··· 329 329 330 330 if (vma->vm_flags & VM_ACCOUNT) { 331 331 unsigned long charged = (new_len - old_len) >> PAGE_SHIFT; 332 - if (security_vm_enough_memory(charged)) 332 + if (security_vm_enough_memory_mm(mm, charged)) 333 333 goto Efault; 334 334 *p = charged; 335 335 }
+2 -2
mm/shmem.c
··· 127 127 static inline int shmem_acct_size(unsigned long flags, loff_t size) 128 128 { 129 129 return (flags & VM_NORESERVE) ? 130 - 0 : security_vm_enough_memory_kern(VM_ACCT(size)); 130 + 0 : security_vm_enough_memory_mm(current->mm, VM_ACCT(size)); 131 131 } 132 132 133 133 static inline void shmem_unacct_size(unsigned long flags, loff_t size) ··· 145 145 static inline int shmem_acct_block(unsigned long flags) 146 146 { 147 147 return (flags & VM_NORESERVE) ? 148 - security_vm_enough_memory_kern(VM_ACCT(PAGE_CACHE_SIZE)) : 0; 148 + security_vm_enough_memory_mm(current->mm, VM_ACCT(PAGE_CACHE_SIZE)) : 0; 149 149 } 150 150 151 151 static inline void shmem_unacct_blocks(unsigned long flags, long pages)
+3 -1
mm/swapfile.c
··· 1563 1563 if (!capable(CAP_SYS_ADMIN)) 1564 1564 return -EPERM; 1565 1565 1566 + BUG_ON(!current->mm); 1567 + 1566 1568 pathname = getname(specialfile); 1567 1569 err = PTR_ERR(pathname); 1568 1570 if (IS_ERR(pathname)) ··· 1592 1590 spin_unlock(&swap_lock); 1593 1591 goto out_dput; 1594 1592 } 1595 - if (!security_vm_enough_memory(p->pages)) 1593 + if (!security_vm_enough_memory_mm(current->mm, p->pages)) 1596 1594 vm_unacct_memory(p->pages); 1597 1595 else { 1598 1596 err = -ENOMEM;
+1
net/dns_resolver/dns_key.c
··· 281 281 282 282 /* instruct request_key() to use this special keyring as a cache for 283 283 * the results it looks up */ 284 + set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags); 284 285 cred->thread_keyring = keyring; 285 286 cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING; 286 287 dns_resolver_cache = cred;
+6
security/Kconfig
··· 187 187 source security/smack/Kconfig 188 188 source security/tomoyo/Kconfig 189 189 source security/apparmor/Kconfig 190 + source security/yama/Kconfig 190 191 191 192 source security/integrity/Kconfig 192 193 ··· 197 196 default DEFAULT_SECURITY_SMACK if SECURITY_SMACK 198 197 default DEFAULT_SECURITY_TOMOYO if SECURITY_TOMOYO 199 198 default DEFAULT_SECURITY_APPARMOR if SECURITY_APPARMOR 199 + default DEFAULT_SECURITY_YAMA if SECURITY_YAMA 200 200 default DEFAULT_SECURITY_DAC 201 201 202 202 help ··· 216 214 config DEFAULT_SECURITY_APPARMOR 217 215 bool "AppArmor" if SECURITY_APPARMOR=y 218 216 217 + config DEFAULT_SECURITY_YAMA 218 + bool "Yama" if SECURITY_YAMA=y 219 + 219 220 config DEFAULT_SECURITY_DAC 220 221 bool "Unix Discretionary Access Controls" 221 222 ··· 230 225 default "smack" if DEFAULT_SECURITY_SMACK 231 226 default "tomoyo" if DEFAULT_SECURITY_TOMOYO 232 227 default "apparmor" if DEFAULT_SECURITY_APPARMOR 228 + default "yama" if DEFAULT_SECURITY_YAMA 233 229 default "" if DEFAULT_SECURITY_DAC 234 230 235 231 endmenu
+2
security/Makefile
··· 7 7 subdir-$(CONFIG_SECURITY_SMACK) += smack 8 8 subdir-$(CONFIG_SECURITY_TOMOYO) += tomoyo 9 9 subdir-$(CONFIG_SECURITY_APPARMOR) += apparmor 10 + subdir-$(CONFIG_SECURITY_YAMA) += yama 10 11 11 12 # always enable default capabilities 12 13 obj-y += commoncap.o ··· 22 21 obj-$(CONFIG_AUDIT) += lsm_audit.o 23 22 obj-$(CONFIG_SECURITY_TOMOYO) += tomoyo/built-in.o 24 23 obj-$(CONFIG_SECURITY_APPARMOR) += apparmor/built-in.o 24 + obj-$(CONFIG_SECURITY_YAMA) += yama/built-in.o 25 25 obj-$(CONFIG_CGROUP_DEVICE) += device_cgroup.o 26 26 27 27 # Object integrity file lists
+20 -7
security/apparmor/Makefile
··· 15 15 # to 16 16 # [1] = "dac_override", 17 17 quiet_cmd_make-caps = GEN $@ 18 - cmd_make-caps = echo "static const char *capability_names[] = {" > $@ ;\ 18 + cmd_make-caps = echo "static const char *const capability_names[] = {" > $@ ;\ 19 19 sed $< >>$@ -r -n -e '/CAP_FS_MASK/d' \ 20 20 -e 's/^\#define[ \t]+CAP_([A-Z0-9_]+)[ \t]+([0-9]+)/[\2] = "\L\1",/p';\ 21 21 echo "};" >> $@ ··· 28 28 # [RLIMIT_STACK] = "stack", 29 29 # 30 30 # and build a second integer table (with the second sed cmd), that maps 31 - # RLIMIT defines to the order defined in asm-generic/resource.h Thi is 31 + # RLIMIT defines to the order defined in asm-generic/resource.h This is 32 32 # required by policy load to map policy ordering of RLIMITs to internal 33 33 # ordering for architectures that redefine an RLIMIT. 34 34 # Transforms lines from 35 35 # #define RLIMIT_STACK 3 /* max stack size */ 36 36 # to 37 37 # RLIMIT_STACK, 38 + # 39 + # and build the securityfs entries for the mapping. 40 + # Transforms lines from 41 + # #define RLIMIT_FSIZE 1 /* Maximum filesize */ 42 + # #define RLIMIT_STACK 3 /* max stack size */ 43 + # to 44 + # #define AA_FS_RLIMIT_MASK "fsize stack" 38 45 quiet_cmd_make-rlim = GEN $@ 39 - cmd_make-rlim = echo "static const char *rlim_names[] = {" > $@ ;\ 46 + cmd_make-rlim = echo "static const char *const rlim_names[RLIM_NLIMITS] = {" \ 47 + > $@ ;\ 40 48 sed $< >> $@ -r -n \ 41 49 -e 's/^\# ?define[ \t]+(RLIMIT_([A-Z0-9_]+)).*/[\1] = "\L\2",/p';\ 42 50 echo "};" >> $@ ;\ 43 - echo "static const int rlim_map[] = {" >> $@ ;\ 51 + echo "static const int rlim_map[RLIM_NLIMITS] = {" >> $@ ;\ 44 52 sed -r -n "s/^\# ?define[ \t]+(RLIMIT_[A-Z0-9_]+).*/\1,/p" $< >> $@ ;\ 45 - echo "};" >> $@ 53 + echo "};" >> $@ ; \ 54 + echo -n '\#define AA_FS_RLIMIT_MASK "' >> $@ ;\ 55 + sed -r -n 's/^\# ?define[ \t]+RLIMIT_([A-Z0-9_]+).*/\L\1/p' $< | \ 56 + tr '\n' ' ' | sed -e 's/ $$/"\n/' >> $@ 46 57 47 58 $(obj)/capability.o : $(obj)/capability_names.h 48 59 $(obj)/resource.o : $(obj)/rlim_names.h 49 - $(obj)/capability_names.h : $(srctree)/include/linux/capability.h 60 + $(obj)/capability_names.h : $(srctree)/include/linux/capability.h \ 61 + $(src)/Makefile 50 62 $(call cmd,make-caps) 51 - $(obj)/rlim_names.h : $(srctree)/include/asm-generic/resource.h 63 + $(obj)/rlim_names.h : $(srctree)/include/asm-generic/resource.h \ 64 + $(src)/Makefile 52 65 $(call cmd,make-rlim)
+152 -41
security/apparmor/apparmorfs.c
··· 18 18 #include <linux/seq_file.h> 19 19 #include <linux/uaccess.h> 20 20 #include <linux/namei.h> 21 + #include <linux/capability.h> 21 22 22 23 #include "include/apparmor.h" 23 24 #include "include/apparmorfs.h" 24 25 #include "include/audit.h" 25 26 #include "include/context.h" 26 27 #include "include/policy.h" 28 + #include "include/resource.h" 27 29 28 30 /** 29 31 * aa_simple_write_to_buffer - common routine for getting policy from user ··· 144 142 .llseek = default_llseek, 145 143 }; 146 144 145 + static int aa_fs_seq_show(struct seq_file *seq, void *v) 146 + { 147 + struct aa_fs_entry *fs_file = seq->private; 148 + 149 + if (!fs_file) 150 + return 0; 151 + 152 + switch (fs_file->v_type) { 153 + case AA_FS_TYPE_BOOLEAN: 154 + seq_printf(seq, "%s\n", fs_file->v.boolean ? "yes" : "no"); 155 + break; 156 + case AA_FS_TYPE_STRING: 157 + seq_printf(seq, "%s\n", fs_file->v.string); 158 + break; 159 + case AA_FS_TYPE_U64: 160 + seq_printf(seq, "%#08lx\n", fs_file->v.u64); 161 + break; 162 + default: 163 + /* Ignore unpritable entry types. */ 164 + break; 165 + } 166 + 167 + return 0; 168 + } 169 + 170 + static int aa_fs_seq_open(struct inode *inode, struct file *file) 171 + { 172 + return single_open(file, aa_fs_seq_show, inode->i_private); 173 + } 174 + 175 + const struct file_operations aa_fs_seq_file_ops = { 176 + .owner = THIS_MODULE, 177 + .open = aa_fs_seq_open, 178 + .read = seq_read, 179 + .llseek = seq_lseek, 180 + .release = single_release, 181 + }; 182 + 147 183 /** Base file system setup **/ 148 184 149 - static struct dentry *aa_fs_dentry __initdata; 185 + static struct aa_fs_entry aa_fs_entry_file[] = { 186 + AA_FS_FILE_STRING("mask", "create read write exec append mmap_exec " \ 187 + "link lock"), 188 + { } 189 + }; 150 190 151 - static void __init aafs_remove(const char *name) 191 + static struct aa_fs_entry aa_fs_entry_domain[] = { 192 + AA_FS_FILE_BOOLEAN("change_hat", 1), 193 + AA_FS_FILE_BOOLEAN("change_hatv", 1), 194 + AA_FS_FILE_BOOLEAN("change_onexec", 1), 195 + AA_FS_FILE_BOOLEAN("change_profile", 1), 196 + { } 197 + }; 198 + 199 + static struct aa_fs_entry aa_fs_entry_features[] = { 200 + AA_FS_DIR("domain", aa_fs_entry_domain), 201 + AA_FS_DIR("file", aa_fs_entry_file), 202 + AA_FS_FILE_U64("capability", VFS_CAP_FLAGS_MASK), 203 + AA_FS_DIR("rlimit", aa_fs_entry_rlimit), 204 + { } 205 + }; 206 + 207 + static struct aa_fs_entry aa_fs_entry_apparmor[] = { 208 + AA_FS_FILE_FOPS(".load", 0640, &aa_fs_profile_load), 209 + AA_FS_FILE_FOPS(".replace", 0640, &aa_fs_profile_replace), 210 + AA_FS_FILE_FOPS(".remove", 0640, &aa_fs_profile_remove), 211 + AA_FS_DIR("features", aa_fs_entry_features), 212 + { } 213 + }; 214 + 215 + static struct aa_fs_entry aa_fs_entry = 216 + AA_FS_DIR("apparmor", aa_fs_entry_apparmor); 217 + 218 + /** 219 + * aafs_create_file - create a file entry in the apparmor securityfs 220 + * @fs_file: aa_fs_entry to build an entry for (NOT NULL) 221 + * @parent: the parent dentry in the securityfs 222 + * 223 + * Use aafs_remove_file to remove entries created with this fn. 224 + */ 225 + static int __init aafs_create_file(struct aa_fs_entry *fs_file, 226 + struct dentry *parent) 152 227 { 153 - struct dentry *dentry; 228 + int error = 0; 154 229 155 - dentry = lookup_one_len(name, aa_fs_dentry, strlen(name)); 156 - if (!IS_ERR(dentry)) { 157 - securityfs_remove(dentry); 158 - dput(dentry); 230 + fs_file->dentry = securityfs_create_file(fs_file->name, 231 + S_IFREG | fs_file->mode, 232 + parent, fs_file, 233 + fs_file->file_ops); 234 + if (IS_ERR(fs_file->dentry)) { 235 + error = PTR_ERR(fs_file->dentry); 236 + fs_file->dentry = NULL; 159 237 } 238 + return error; 160 239 } 161 240 162 241 /** 163 - * aafs_create - create an entry in the apparmor filesystem 164 - * @name: name of the entry (NOT NULL) 165 - * @mask: file permission mask of the file 166 - * @fops: file operations for the file (NOT NULL) 242 + * aafs_create_dir - recursively create a directory entry in the securityfs 243 + * @fs_dir: aa_fs_entry (and all child entries) to build (NOT NULL) 244 + * @parent: the parent dentry in the securityfs 167 245 * 168 - * Used aafs_remove to remove entries created with this fn. 246 + * Use aafs_remove_dir to remove entries created with this fn. 169 247 */ 170 - static int __init aafs_create(const char *name, umode_t mask, 171 - const struct file_operations *fops) 248 + static int __init aafs_create_dir(struct aa_fs_entry *fs_dir, 249 + struct dentry *parent) 172 250 { 173 - struct dentry *dentry; 251 + int error; 252 + struct aa_fs_entry *fs_file; 174 253 175 - dentry = securityfs_create_file(name, S_IFREG | mask, aa_fs_dentry, 176 - NULL, fops); 254 + fs_dir->dentry = securityfs_create_dir(fs_dir->name, parent); 255 + if (IS_ERR(fs_dir->dentry)) { 256 + error = PTR_ERR(fs_dir->dentry); 257 + fs_dir->dentry = NULL; 258 + goto failed; 259 + } 177 260 178 - return IS_ERR(dentry) ? PTR_ERR(dentry) : 0; 261 + for (fs_file = fs_dir->v.files; fs_file->name; ++fs_file) { 262 + if (fs_file->v_type == AA_FS_TYPE_DIR) 263 + error = aafs_create_dir(fs_file, fs_dir->dentry); 264 + else 265 + error = aafs_create_file(fs_file, fs_dir->dentry); 266 + if (error) 267 + goto failed; 268 + } 269 + 270 + return 0; 271 + 272 + failed: 273 + return error; 274 + } 275 + 276 + /** 277 + * aafs_remove_file - drop a single file entry in the apparmor securityfs 278 + * @fs_file: aa_fs_entry to detach from the securityfs (NOT NULL) 279 + */ 280 + static void __init aafs_remove_file(struct aa_fs_entry *fs_file) 281 + { 282 + if (!fs_file->dentry) 283 + return; 284 + 285 + securityfs_remove(fs_file->dentry); 286 + fs_file->dentry = NULL; 287 + } 288 + 289 + /** 290 + * aafs_remove_dir - recursively drop a directory entry from the securityfs 291 + * @fs_dir: aa_fs_entry (and all child entries) to detach (NOT NULL) 292 + */ 293 + static void __init aafs_remove_dir(struct aa_fs_entry *fs_dir) 294 + { 295 + struct aa_fs_entry *fs_file; 296 + 297 + for (fs_file = fs_dir->v.files; fs_file->name; ++fs_file) { 298 + if (fs_file->v_type == AA_FS_TYPE_DIR) 299 + aafs_remove_dir(fs_file); 300 + else 301 + aafs_remove_file(fs_file); 302 + } 303 + 304 + aafs_remove_file(fs_dir); 179 305 } 180 306 181 307 /** ··· 313 183 */ 314 184 void __init aa_destroy_aafs(void) 315 185 { 316 - if (aa_fs_dentry) { 317 - aafs_remove(".remove"); 318 - aafs_remove(".replace"); 319 - aafs_remove(".load"); 320 - 321 - securityfs_remove(aa_fs_dentry); 322 - aa_fs_dentry = NULL; 323 - } 186 + aafs_remove_dir(&aa_fs_entry); 324 187 } 325 188 326 189 /** ··· 330 207 if (!apparmor_initialized) 331 208 return 0; 332 209 333 - if (aa_fs_dentry) { 210 + if (aa_fs_entry.dentry) { 334 211 AA_ERROR("%s: AppArmor securityfs already exists\n", __func__); 335 212 return -EEXIST; 336 213 } 337 214 338 - aa_fs_dentry = securityfs_create_dir("apparmor", NULL); 339 - if (IS_ERR(aa_fs_dentry)) { 340 - error = PTR_ERR(aa_fs_dentry); 341 - aa_fs_dentry = NULL; 342 - goto error; 343 - } 344 - 345 - error = aafs_create(".load", 0640, &aa_fs_profile_load); 346 - if (error) 347 - goto error; 348 - error = aafs_create(".replace", 0640, &aa_fs_profile_replace); 349 - if (error) 350 - goto error; 351 - error = aafs_create(".remove", 0640, &aa_fs_profile_remove); 215 + /* Populate fs tree. */ 216 + error = aafs_create_dir(&aa_fs_entry, NULL); 352 217 if (error) 353 218 goto error; 354 219
+4 -3
security/apparmor/audit.c
··· 19 19 #include "include/audit.h" 20 20 #include "include/policy.h" 21 21 22 - const char *op_table[] = { 22 + const char *const op_table[] = { 23 23 "null", 24 24 25 25 "sysctl", ··· 73 73 "profile_remove" 74 74 }; 75 75 76 - const char *audit_mode_names[] = { 76 + const char *const audit_mode_names[] = { 77 77 "normal", 78 78 "quiet_denied", 79 79 "quiet", ··· 81 81 "all" 82 82 }; 83 83 84 - static char *aa_audit_type[] = { 84 + static const char *const aa_audit_type[] = { 85 85 "AUDIT", 86 86 "ALLOWED", 87 87 "DENIED", ··· 89 89 "STATUS", 90 90 "ERROR", 91 91 "KILLED" 92 + "AUTO" 92 93 }; 93 94 94 95 /*
+2 -3
security/apparmor/domain.c
··· 372 372 state = profile->file.start; 373 373 374 374 /* buffer freed below, name is pointer into buffer */ 375 - error = aa_get_name(&bprm->file->f_path, profile->path_flags, &buffer, 376 - &name); 375 + error = aa_path_name(&bprm->file->f_path, profile->path_flags, &buffer, 376 + &name, &info); 377 377 if (error) { 378 378 if (profile->flags & 379 379 (PFLAG_IX_ON_NAME_ERROR | PFLAG_UNCONFINED)) 380 380 error = 0; 381 - info = "Exec failed name resolution"; 382 381 name = bprm->filename; 383 382 goto audit; 384 383 }
+8 -13
security/apparmor/file.c
··· 173 173 if (old & 0x40) /* AA_EXEC_MMAP */ 174 174 new |= AA_EXEC_MMAP; 175 175 176 - new |= AA_MAY_META_READ; 177 - 178 176 return new; 179 177 } 180 178 ··· 210 212 perms.quiet = map_old_perms(dfa_other_quiet(dfa, state)); 211 213 perms.xindex = dfa_other_xindex(dfa, state); 212 214 } 215 + perms.allow |= AA_MAY_META_READ; 213 216 214 217 /* change_profile wasn't determined by ownership in old mapping */ 215 218 if (ACCEPT_TABLE(dfa)[state] & 0x80000000) ··· 278 279 int error; 279 280 280 281 flags |= profile->path_flags | (S_ISDIR(cond->mode) ? PATH_IS_DIR : 0); 281 - error = aa_get_name(path, flags, &buffer, &name); 282 + error = aa_path_name(path, flags, &buffer, &name, &info); 282 283 if (error) { 283 284 if (error == -ENOENT && is_deleted(path->dentry)) { 284 285 /* Access to open files that are deleted are 285 286 * give a pass (implicit delegation) 286 287 */ 287 288 error = 0; 289 + info = NULL; 288 290 perms.allow = request; 289 - } else if (error == -ENOENT) 290 - info = "Failed name lookup - deleted entry"; 291 - else if (error == -ESTALE) 292 - info = "Failed name lookup - disconnected path"; 293 - else if (error == -ENAMETOOLONG) 294 - info = "Failed name lookup - name too long"; 295 - else 296 - info = "Failed name lookup"; 291 + } 297 292 } else { 298 293 aa_str_perms(profile->file.dfa, profile->file.start, name, cond, 299 294 &perms); ··· 358 365 lperms = nullperms; 359 366 360 367 /* buffer freed below, lname is pointer in buffer */ 361 - error = aa_get_name(&link, profile->path_flags, &buffer, &lname); 368 + error = aa_path_name(&link, profile->path_flags, &buffer, &lname, 369 + &info); 362 370 if (error) 363 371 goto audit; 364 372 365 373 /* buffer2 freed below, tname is pointer in buffer2 */ 366 - error = aa_get_name(&target, profile->path_flags, &buffer2, &tname); 374 + error = aa_path_name(&target, profile->path_flags, &buffer2, &tname, 375 + &info); 367 376 if (error) 368 377 goto audit; 369 378
+14 -1
security/apparmor/include/apparmor.h
··· 19 19 20 20 #include "match.h" 21 21 22 + /* 23 + * Class of mediation types in the AppArmor policy db 24 + */ 25 + #define AA_CLASS_ENTRY 0 26 + #define AA_CLASS_UNKNOWN 1 27 + #define AA_CLASS_FILE 2 28 + #define AA_CLASS_CAP 3 29 + #define AA_CLASS_NET 4 30 + #define AA_CLASS_RLIMITS 5 31 + #define AA_CLASS_DOMAIN 6 32 + 33 + #define AA_CLASS_LAST AA_CLASS_DOMAIN 34 + 22 35 /* Control parameters settable through module/boot flags */ 23 36 extern enum audit_mode aa_g_audit; 24 37 extern bool aa_g_audit_header; ··· 94 81 unsigned int start) 95 82 { 96 83 /* the null transition only needs the string's null terminator byte */ 97 - return aa_dfa_match_len(dfa, start, "", 1); 84 + return aa_dfa_next(dfa, start, 0); 98 85 } 99 86 100 87 static inline bool mediated_filesystem(struct inode *inode)
+44
security/apparmor/include/apparmorfs.h
··· 15 15 #ifndef __AA_APPARMORFS_H 16 16 #define __AA_APPARMORFS_H 17 17 18 + enum aa_fs_type { 19 + AA_FS_TYPE_BOOLEAN, 20 + AA_FS_TYPE_STRING, 21 + AA_FS_TYPE_U64, 22 + AA_FS_TYPE_FOPS, 23 + AA_FS_TYPE_DIR, 24 + }; 25 + 26 + struct aa_fs_entry; 27 + 28 + struct aa_fs_entry { 29 + const char *name; 30 + struct dentry *dentry; 31 + umode_t mode; 32 + enum aa_fs_type v_type; 33 + union { 34 + bool boolean; 35 + char *string; 36 + unsigned long u64; 37 + struct aa_fs_entry *files; 38 + } v; 39 + const struct file_operations *file_ops; 40 + }; 41 + 42 + extern const struct file_operations aa_fs_seq_file_ops; 43 + 44 + #define AA_FS_FILE_BOOLEAN(_name, _value) \ 45 + { .name = (_name), .mode = 0444, \ 46 + .v_type = AA_FS_TYPE_BOOLEAN, .v.boolean = (_value), \ 47 + .file_ops = &aa_fs_seq_file_ops } 48 + #define AA_FS_FILE_STRING(_name, _value) \ 49 + { .name = (_name), .mode = 0444, \ 50 + .v_type = AA_FS_TYPE_STRING, .v.string = (_value), \ 51 + .file_ops = &aa_fs_seq_file_ops } 52 + #define AA_FS_FILE_U64(_name, _value) \ 53 + { .name = (_name), .mode = 0444, \ 54 + .v_type = AA_FS_TYPE_U64, .v.u64 = (_value), \ 55 + .file_ops = &aa_fs_seq_file_ops } 56 + #define AA_FS_FILE_FOPS(_name, _mode, _fops) \ 57 + { .name = (_name), .v_type = AA_FS_TYPE_FOPS, \ 58 + .mode = (_mode), .file_ops = (_fops) } 59 + #define AA_FS_DIR(_name, _value) \ 60 + { .name = (_name), .v_type = AA_FS_TYPE_DIR, .v.files = (_value) } 61 + 18 62 extern void __init aa_destroy_aafs(void); 19 63 20 64 #endif /* __AA_APPARMORFS_H */
+4 -5
security/apparmor/include/audit.h
··· 25 25 26 26 struct aa_profile; 27 27 28 - extern const char *audit_mode_names[]; 28 + extern const char *const audit_mode_names[]; 29 29 #define AUDIT_MAX_INDEX 5 30 - 31 - #define AUDIT_APPARMOR_AUTO 0 /* auto choose audit message type */ 32 30 33 31 enum audit_mode { 34 32 AUDIT_NORMAL, /* follow normal auditing of accesses */ ··· 43 45 AUDIT_APPARMOR_HINT, 44 46 AUDIT_APPARMOR_STATUS, 45 47 AUDIT_APPARMOR_ERROR, 46 - AUDIT_APPARMOR_KILL 48 + AUDIT_APPARMOR_KILL, 49 + AUDIT_APPARMOR_AUTO 47 50 }; 48 51 49 - extern const char *op_table[]; 52 + extern const char *const op_table[]; 50 53 enum aa_ops { 51 54 OP_NULL, 52 55
+1 -1
security/apparmor/include/file.h
··· 117 117 index |= AA_X_NAME; 118 118 } else if (old_index == 3) { 119 119 index |= AA_X_NAME | AA_X_CHILD; 120 - } else { 120 + } else if (old_index) { 121 121 index |= AA_X_TABLE; 122 122 index |= old_index - 4; 123 123 }
+3
security/apparmor/include/match.h
··· 116 116 const char *str, int len); 117 117 unsigned int aa_dfa_match(struct aa_dfa *dfa, unsigned int start, 118 118 const char *str); 119 + unsigned int aa_dfa_next(struct aa_dfa *dfa, unsigned int state, 120 + const char c); 121 + 119 122 void aa_dfa_free_kref(struct kref *kref); 120 123 121 124 /**
+2 -1
security/apparmor/include/path.h
··· 26 26 PATH_MEDIATE_DELETED = 0x10000, /* mediate deleted paths */ 27 27 }; 28 28 29 - int aa_get_name(struct path *path, int flags, char **buffer, const char **name); 29 + int aa_path_name(struct path *path, int flags, char **buffer, 30 + const char **name, const char **info); 30 31 31 32 #endif /* __AA_PATH_H */
+14 -1
security/apparmor/include/policy.h
··· 29 29 #include "file.h" 30 30 #include "resource.h" 31 31 32 - extern const char *profile_mode_names[]; 32 + extern const char *const profile_mode_names[]; 33 33 #define APPARMOR_NAMES_MAX_INDEX 3 34 34 35 35 #define COMPLAIN_MODE(_profile) \ ··· 129 129 struct list_head sub_ns; 130 130 }; 131 131 132 + /* struct aa_policydb - match engine for a policy 133 + * dfa: dfa pattern match 134 + * start: set of start states for the different classes of data 135 + */ 136 + struct aa_policydb { 137 + /* Generic policy DFA specific rule types will be subsections of it */ 138 + struct aa_dfa *dfa; 139 + unsigned int start[AA_CLASS_LAST + 1]; 140 + 141 + }; 142 + 132 143 /* struct aa_profile - basic confinement data 133 144 * @base - base components of the profile (name, refcount, lists, lock ...) 134 145 * @parent: parent of profile ··· 154 143 * @flags: flags controlling profile behavior 155 144 * @path_flags: flags controlling path generation behavior 156 145 * @size: the memory consumed by this profiles rules 146 + * @policy: general match rules governing policy 157 147 * @file: The set of rules governing basic file access and domain transitions 158 148 * @caps: capabilities for the profile 159 149 * @rlimits: rlimits for the profile ··· 191 179 u32 path_flags; 192 180 int size; 193 181 182 + struct aa_policydb policy; 194 183 struct aa_file_rules file; 195 184 struct aa_caps caps; 196 185 struct aa_rlimit rlimits;
+4
security/apparmor/include/resource.h
··· 18 18 #include <linux/resource.h> 19 19 #include <linux/sched.h> 20 20 21 + #include "apparmorfs.h" 22 + 21 23 struct aa_profile; 22 24 23 25 /* struct aa_rlimit - rlimit settings for the profile ··· 33 31 unsigned int mask; 34 32 struct rlimit limits[RLIM_NLIMITS]; 35 33 }; 34 + 35 + extern struct aa_fs_entry aa_fs_entry_rlimit[]; 36 36 37 37 int aa_map_resource(int resource); 38 38 int aa_task_setrlimit(struct aa_profile *profile, struct task_struct *,
+77 -3
security/apparmor/match.c
··· 335 335 } 336 336 337 337 /** 338 - * aa_dfa_next_state - traverse @dfa to find state @str stops at 338 + * aa_dfa_match - traverse @dfa to find state @str stops at 339 339 * @dfa: the dfa to match @str against (NOT NULL) 340 340 * @start: the state of the dfa to start matching in 341 341 * @str: the null terminated string of bytes to match against the dfa (NOT NULL) 342 342 * 343 - * aa_dfa_next_state will match @str against the dfa and return the state it 343 + * aa_dfa_match will match @str against the dfa and return the state it 344 344 * finished matching in. The final state can be used to look up the accepting 345 345 * label, or as the start state of a continuing match. 346 346 * ··· 349 349 unsigned int aa_dfa_match(struct aa_dfa *dfa, unsigned int start, 350 350 const char *str) 351 351 { 352 - return aa_dfa_match_len(dfa, start, str, strlen(str)); 352 + u16 *def = DEFAULT_TABLE(dfa); 353 + u32 *base = BASE_TABLE(dfa); 354 + u16 *next = NEXT_TABLE(dfa); 355 + u16 *check = CHECK_TABLE(dfa); 356 + unsigned int state = start, pos; 357 + 358 + if (state == 0) 359 + return 0; 360 + 361 + /* current state is <state>, matching character *str */ 362 + if (dfa->tables[YYTD_ID_EC]) { 363 + /* Equivalence class table defined */ 364 + u8 *equiv = EQUIV_TABLE(dfa); 365 + /* default is direct to next state */ 366 + while (*str) { 367 + pos = base[state] + equiv[(u8) *str++]; 368 + if (check[pos] == state) 369 + state = next[pos]; 370 + else 371 + state = def[state]; 372 + } 373 + } else { 374 + /* default is direct to next state */ 375 + while (*str) { 376 + pos = base[state] + (u8) *str++; 377 + if (check[pos] == state) 378 + state = next[pos]; 379 + else 380 + state = def[state]; 381 + } 382 + } 383 + 384 + return state; 385 + } 386 + 387 + /** 388 + * aa_dfa_next - step one character to the next state in the dfa 389 + * @dfa: the dfa to tranverse (NOT NULL) 390 + * @state: the state to start in 391 + * @c: the input character to transition on 392 + * 393 + * aa_dfa_match will step through the dfa by one input character @c 394 + * 395 + * Returns: state reach after input @c 396 + */ 397 + unsigned int aa_dfa_next(struct aa_dfa *dfa, unsigned int state, 398 + const char c) 399 + { 400 + u16 *def = DEFAULT_TABLE(dfa); 401 + u32 *base = BASE_TABLE(dfa); 402 + u16 *next = NEXT_TABLE(dfa); 403 + u16 *check = CHECK_TABLE(dfa); 404 + unsigned int pos; 405 + 406 + /* current state is <state>, matching character *str */ 407 + if (dfa->tables[YYTD_ID_EC]) { 408 + /* Equivalence class table defined */ 409 + u8 *equiv = EQUIV_TABLE(dfa); 410 + /* default is direct to next state */ 411 + 412 + pos = base[state] + equiv[(u8) c]; 413 + if (check[pos] == state) 414 + state = next[pos]; 415 + else 416 + state = def[state]; 417 + } else { 418 + /* default is direct to next state */ 419 + pos = base[state] + (u8) c; 420 + if (check[pos] == state) 421 + state = next[pos]; 422 + else 423 + state = def[state]; 424 + } 425 + 426 + return state; 353 427 }
+34 -22
security/apparmor/path.c
··· 83 83 struct path root; 84 84 get_fs_root(current->fs, &root); 85 85 res = __d_path(path, &root, buf, buflen); 86 - if (res && !IS_ERR(res)) { 87 - /* everything's fine */ 88 - *name = res; 89 - path_put(&root); 90 - goto ok; 91 - } 92 86 path_put(&root); 93 - connected = 0; 87 + } else { 88 + res = d_absolute_path(path, buf, buflen); 89 + if (!our_mnt(path->mnt)) 90 + connected = 0; 94 91 } 95 92 96 - res = d_absolute_path(path, buf, buflen); 97 - 98 - *name = res; 99 93 /* handle error conditions - and still allow a partial path to 100 94 * be returned. 101 95 */ 102 - if (IS_ERR(res)) { 103 - error = PTR_ERR(res); 104 - *name = buf; 105 - goto out; 106 - } 107 - if (!our_mnt(path->mnt)) 96 + if (!res || IS_ERR(res)) { 97 + connected = 0; 98 + res = dentry_path_raw(path->dentry, buf, buflen); 99 + if (IS_ERR(res)) { 100 + error = PTR_ERR(res); 101 + *name = buf; 102 + goto out; 103 + }; 104 + } else if (!our_mnt(path->mnt)) 108 105 connected = 0; 109 106 110 - ok: 107 + *name = res; 108 + 111 109 /* Handle two cases: 112 110 * 1. A deleted dentry && profile is not allowing mediation of deleted 113 111 * 2. On some filesystems, newly allocated dentries appear to the ··· 136 138 /* disconnected path, don't return pathname starting 137 139 * with '/' 138 140 */ 139 - error = -ESTALE; 141 + error = -EACCES; 140 142 if (*res == '/') 141 143 *name = res + 1; 142 144 } ··· 157 159 * Returns: %0 else error on failure 158 160 */ 159 161 static int get_name_to_buffer(struct path *path, int flags, char *buffer, 160 - int size, char **name) 162 + int size, char **name, const char **info) 161 163 { 162 164 int adjust = (flags & PATH_IS_DIR) ? 1 : 0; 163 165 int error = d_namespace_path(path, buffer, size - adjust, name, flags); ··· 169 171 */ 170 172 strcpy(&buffer[size - 2], "/"); 171 173 174 + if (info && error) { 175 + if (error == -ENOENT) 176 + *info = "Failed name lookup - deleted entry"; 177 + else if (error == -ESTALE) 178 + *info = "Failed name lookup - disconnected path"; 179 + else if (error == -ENAMETOOLONG) 180 + *info = "Failed name lookup - name too long"; 181 + else 182 + *info = "Failed name lookup"; 183 + } 184 + 172 185 return error; 173 186 } 174 187 175 188 /** 176 - * aa_get_name - compute the pathname of a file 189 + * aa_path_name - compute the pathname of a file 177 190 * @path: path the file (NOT NULL) 178 191 * @flags: flags controlling path name generation 179 192 * @buffer: buffer that aa_get_name() allocated (NOT NULL) 180 193 * @name: Returns - the generated path name if !error (NOT NULL) 194 + * @info: Returns - information on why the path lookup failed (MAYBE NULL) 181 195 * 182 196 * @name is a pointer to the beginning of the pathname (which usually differs 183 197 * from the beginning of the buffer), or NULL. If there is an error @name ··· 202 192 * 203 193 * Returns: %0 else error code if could retrieve name 204 194 */ 205 - int aa_get_name(struct path *path, int flags, char **buffer, const char **name) 195 + int aa_path_name(struct path *path, int flags, char **buffer, const char **name, 196 + const char **info) 206 197 { 207 198 char *buf, *str = NULL; 208 199 int size = 256; ··· 217 206 if (!buf) 218 207 return -ENOMEM; 219 208 220 - error = get_name_to_buffer(path, flags, buf, size, &str); 209 + error = get_name_to_buffer(path, flags, buf, size, &str, info); 221 210 if (error != -ENAMETOOLONG) 222 211 break; 223 212 ··· 225 214 size <<= 1; 226 215 if (size > aa_g_path_max) 227 216 return -ENAMETOOLONG; 217 + *info = NULL; 228 218 } 229 219 *buffer = buf; 230 220 *name = str;
+2 -1
security/apparmor/policy.c
··· 93 93 /* root profile namespace */ 94 94 struct aa_namespace *root_ns; 95 95 96 - const char *profile_mode_names[] = { 96 + const char *const profile_mode_names[] = { 97 97 "enforce", 98 98 "complain", 99 99 "kill", ··· 749 749 750 750 aa_free_sid(profile->sid); 751 751 aa_put_dfa(profile->xmatch); 752 + aa_put_dfa(profile->policy.dfa); 752 753 753 754 aa_put_profile(profile->replacedby); 754 755
+28 -3
security/apparmor/policy_unpack.c
··· 84 84 * @new: profile if it has been allocated (MAYBE NULL) 85 85 * @name: name of the profile being manipulated (MAYBE NULL) 86 86 * @info: any extra info about the failure (MAYBE NULL) 87 - * @e: buffer position info (NOT NULL) 87 + * @e: buffer position info 88 88 * @error: error code 89 89 * 90 90 * Returns: %0 or error ··· 95 95 struct aa_profile *profile = __aa_current_profile(); 96 96 struct common_audit_data sa; 97 97 COMMON_AUDIT_DATA_INIT(&sa, NONE); 98 - sa.aad.iface.pos = e->pos - e->start; 98 + if (e) 99 + sa.aad.iface.pos = e->pos - e->start; 99 100 sa.aad.iface.target = new; 100 101 sa.aad.name = name; 101 102 sa.aad.info = info; ··· 469 468 { 470 469 struct aa_profile *profile = NULL; 471 470 const char *name = NULL; 472 - int error = -EPROTO; 471 + int i, error = -EPROTO; 473 472 kernel_cap_t tmpcap; 474 473 u32 tmp; 475 474 ··· 555 554 goto fail; 556 555 if (!unpack_u32(e, &(profile->caps.extended.cap[1]), NULL)) 557 556 goto fail; 557 + if (!unpack_nameX(e, AA_STRUCTEND, NULL)) 558 + goto fail; 558 559 } 559 560 560 561 if (!unpack_rlimits(e, profile)) 561 562 goto fail; 563 + 564 + if (unpack_nameX(e, AA_STRUCT, "policydb")) { 565 + /* generic policy dfa - optional and may be NULL */ 566 + profile->policy.dfa = unpack_dfa(e); 567 + if (IS_ERR(profile->policy.dfa)) { 568 + error = PTR_ERR(profile->policy.dfa); 569 + profile->policy.dfa = NULL; 570 + goto fail; 571 + } 572 + if (!unpack_u32(e, &profile->policy.start[0], "start")) 573 + /* default start state */ 574 + profile->policy.start[0] = DFA_START; 575 + /* setup class index */ 576 + for (i = AA_CLASS_FILE; i <= AA_CLASS_LAST; i++) { 577 + profile->policy.start[i] = 578 + aa_dfa_next(profile->policy.dfa, 579 + profile->policy.start[0], 580 + i); 581 + } 582 + if (!unpack_nameX(e, AA_STRUCTEND, NULL)) 583 + goto fail; 584 + } 562 585 563 586 /* get file rules */ 564 587 profile->file.dfa = unpack_dfa(e);
+5
security/apparmor/resource.c
··· 23 23 */ 24 24 #include "rlim_names.h" 25 25 26 + struct aa_fs_entry aa_fs_entry_rlimit[] = { 27 + AA_FS_FILE_STRING("mask", AA_FS_RLIMIT_MASK), 28 + { } 29 + }; 30 + 26 31 /* audit callback for resource specific fields */ 27 32 static void audit_cb(struct audit_buffer *ab, void *va) 28 33 {
+5
security/capability.c
··· 358 358 return 0; 359 359 } 360 360 361 + static void cap_task_free(struct task_struct *task) 362 + { 363 + } 364 + 361 365 static int cap_cred_alloc_blank(struct cred *cred, gfp_t gfp) 362 366 { 363 367 return 0; ··· 958 954 set_to_cap_if_null(ops, file_receive); 959 955 set_to_cap_if_null(ops, dentry_open); 960 956 set_to_cap_if_null(ops, task_create); 957 + set_to_cap_if_null(ops, task_free); 961 958 set_to_cap_if_null(ops, cred_alloc_blank); 962 959 set_to_cap_if_null(ops, cred_free); 963 960 set_to_cap_if_null(ops, cred_prepare);
+1
security/commoncap.c
··· 28 28 #include <linux/prctl.h> 29 29 #include <linux/securebits.h> 30 30 #include <linux/user_namespace.h> 31 + #include <linux/binfmts.h> 31 32 32 33 /* 33 34 * If a non-root user executes a setuid-root binary in
+2 -2
security/integrity/ima/Kconfig
··· 9 9 select CRYPTO_HMAC 10 10 select CRYPTO_MD5 11 11 select CRYPTO_SHA1 12 - select TCG_TPM if !S390 && !UML 13 - select TCG_TIS if TCG_TPM 12 + select TCG_TPM if HAS_IOMEM && !UML 13 + select TCG_TIS if TCG_TPM && X86 14 14 help 15 15 The Trusted Computing Group(TCG) runtime Integrity 16 16 Measurement Architecture(IMA) maintains a list of hash
+1 -1
security/integrity/ima/ima_audit.c
··· 61 61 audit_log_untrustedstring(ab, inode->i_sb->s_id); 62 62 audit_log_format(ab, " ino=%lu", inode->i_ino); 63 63 } 64 - audit_log_format(ab, " res=%d", !result ? 0 : 1); 64 + audit_log_format(ab, " res=%d", !result); 65 65 audit_log_end(ab); 66 66 }
+2 -1
security/integrity/ima/ima_policy.c
··· 62 62 {.action = DONT_MEASURE,.fsmagic = SYSFS_MAGIC,.flags = IMA_FSMAGIC}, 63 63 {.action = DONT_MEASURE,.fsmagic = DEBUGFS_MAGIC,.flags = IMA_FSMAGIC}, 64 64 {.action = DONT_MEASURE,.fsmagic = TMPFS_MAGIC,.flags = IMA_FSMAGIC}, 65 + {.action = DONT_MEASURE,.fsmagic = RAMFS_MAGIC,.flags = IMA_FSMAGIC}, 65 66 {.action = DONT_MEASURE,.fsmagic = SECURITYFS_MAGIC,.flags = IMA_FSMAGIC}, 66 67 {.action = DONT_MEASURE,.fsmagic = SELINUX_MAGIC,.flags = IMA_FSMAGIC}, 67 68 {.action = MEASURE,.func = FILE_MMAP,.mask = MAY_EXEC, ··· 418 417 if (!result && (entry->action == UNKNOWN)) 419 418 result = -EINVAL; 420 419 421 - audit_log_format(ab, "res=%d", !!result); 420 + audit_log_format(ab, "res=%d", !result); 422 421 audit_log_end(ab); 423 422 return result; 424 423 }
+14 -1
security/keys/keyctl.c
··· 388 388 keyring_ref = lookup_user_key(ringid, KEY_LOOKUP_CREATE, KEY_WRITE); 389 389 if (IS_ERR(keyring_ref)) { 390 390 ret = PTR_ERR(keyring_ref); 391 + 392 + /* Root is permitted to invalidate certain special keyrings */ 393 + if (capable(CAP_SYS_ADMIN)) { 394 + keyring_ref = lookup_user_key(ringid, 0, 0); 395 + if (IS_ERR(keyring_ref)) 396 + goto error; 397 + if (test_bit(KEY_FLAG_ROOT_CAN_CLEAR, 398 + &key_ref_to_ptr(keyring_ref)->flags)) 399 + goto clear; 400 + goto error_put; 401 + } 402 + 391 403 goto error; 392 404 } 393 405 406 + clear: 394 407 ret = keyring_clear(key_ref_to_ptr(keyring_ref)); 395 - 408 + error_put: 396 409 key_ref_put(keyring_ref); 397 410 error: 398 411 return ret;
+2 -1
security/keys/process_keys.c
··· 657 657 goto error; 658 658 659 659 down_read(&cred->request_key_auth->sem); 660 - if (cred->request_key_auth->flags & KEY_FLAG_REVOKED) { 660 + if (test_bit(KEY_FLAG_REVOKED, 661 + &cred->request_key_auth->flags)) { 661 662 key_ref = ERR_PTR(-EKEYREVOKED); 662 663 key = NULL; 663 664 } else {
+7 -14
security/security.c
··· 19 19 #include <linux/integrity.h> 20 20 #include <linux/ima.h> 21 21 #include <linux/evm.h> 22 + #include <linux/fsnotify.h> 23 + #include <net/flow.h> 22 24 23 25 #define MAX_LSM_EVM_XATTR 2 24 26 ··· 189 187 return security_ops->settime(ts, tz); 190 188 } 191 189 192 - int security_vm_enough_memory(long pages) 193 - { 194 - WARN_ON(current->mm == NULL); 195 - return security_ops->vm_enough_memory(current->mm, pages); 196 - } 197 - 198 190 int security_vm_enough_memory_mm(struct mm_struct *mm, long pages) 199 191 { 200 - WARN_ON(mm == NULL); 201 192 return security_ops->vm_enough_memory(mm, pages); 202 - } 203 - 204 - int security_vm_enough_memory_kern(long pages) 205 - { 206 - /* If current->mm is a kernel thread then we will pass NULL, 207 - for this specific case that is fine */ 208 - return security_ops->vm_enough_memory(current->mm, pages); 209 193 } 210 194 211 195 int security_bprm_set_creds(struct linux_binprm *bprm) ··· 715 727 int security_task_create(unsigned long clone_flags) 716 728 { 717 729 return security_ops->task_create(clone_flags); 730 + } 731 + 732 + void security_task_free(struct task_struct *task) 733 + { 734 + security_ops->task_free(task); 718 735 } 719 736 720 737 int security_cred_alloc_blank(struct cred *cred, gfp_t gfp)
+2
security/selinux/hooks.c
··· 81 81 #include <linux/syslog.h> 82 82 #include <linux/user_namespace.h> 83 83 #include <linux/export.h> 84 + #include <linux/msg.h> 85 + #include <linux/shm.h> 84 86 85 87 #include "avc.h" 86 88 #include "objsec.h"
+3
security/smack/smack_lsm.c
··· 36 36 #include <linux/magic.h> 37 37 #include <linux/dcache.h> 38 38 #include <linux/personality.h> 39 + #include <linux/msg.h> 40 + #include <linux/shm.h> 41 + #include <linux/binfmts.h> 39 42 #include "smack.h" 40 43 41 44 #define task_security(task) (task_cred_xxx((task), security))
+2 -2
security/tomoyo/audit.c
··· 446 446 * tomoyo_poll_log - Wait for an audit log. 447 447 * 448 448 * @file: Pointer to "struct file". 449 - * @wait: Pointer to "poll_table". 449 + * @wait: Pointer to "poll_table". Maybe NULL. 450 450 * 451 451 * Returns POLLIN | POLLRDNORM when ready to read an audit log. 452 452 */ 453 - int tomoyo_poll_log(struct file *file, poll_table *wait) 453 + unsigned int tomoyo_poll_log(struct file *file, poll_table *wait) 454 454 { 455 455 if (tomoyo_log_count) 456 456 return POLLIN | POLLRDNORM;
+23 -40
security/tomoyo/common.c
··· 1069 1069 * 1070 1070 * @domainname: The name of domain. 1071 1071 * 1072 - * Returns 0. 1072 + * Returns 0 on success, negative value otherwise. 1073 1073 * 1074 1074 * Caller holds tomoyo_read_lock(). 1075 1075 */ ··· 1081 1081 name.name = domainname; 1082 1082 tomoyo_fill_path_info(&name); 1083 1083 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 1084 - return 0; 1084 + return -EINTR; 1085 1085 /* Is there an active domain? */ 1086 1086 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) { 1087 1087 /* Never delete tomoyo_kernel_domain */ ··· 1164 1164 bool is_select = !is_delete && tomoyo_str_starts(&data, "select "); 1165 1165 unsigned int profile; 1166 1166 if (*data == '<') { 1167 + int ret = 0; 1167 1168 domain = NULL; 1168 1169 if (is_delete) 1169 - tomoyo_delete_domain(data); 1170 + ret = tomoyo_delete_domain(data); 1170 1171 else if (is_select) 1171 1172 domain = tomoyo_find_domain(data); 1172 1173 else 1173 1174 domain = tomoyo_assign_domain(data, false); 1174 1175 head->w.domain = domain; 1175 - return 0; 1176 + return ret; 1176 1177 } 1177 1178 if (!domain) 1178 1179 return -EINVAL; ··· 2112 2111 struct tomoyo_domain_info *domain = NULL; 2113 2112 spin_lock(&tomoyo_query_list_lock); 2114 2113 list_for_each_entry(ptr, &tomoyo_query_list, list) { 2115 - if (ptr->serial != serial || ptr->answer) 2114 + if (ptr->serial != serial) 2116 2115 continue; 2117 2116 domain = ptr->domain; 2118 2117 break; ··· 2131 2130 * 2132 2131 * Waits for access requests which violated policy in enforcing mode. 2133 2132 */ 2134 - static int tomoyo_poll_query(struct file *file, poll_table *wait) 2133 + static unsigned int tomoyo_poll_query(struct file *file, poll_table *wait) 2135 2134 { 2136 - struct list_head *tmp; 2137 - bool found = false; 2138 - u8 i; 2139 - for (i = 0; i < 2; i++) { 2140 - spin_lock(&tomoyo_query_list_lock); 2141 - list_for_each(tmp, &tomoyo_query_list) { 2142 - struct tomoyo_query *ptr = 2143 - list_entry(tmp, typeof(*ptr), list); 2144 - if (ptr->answer) 2145 - continue; 2146 - found = true; 2147 - break; 2148 - } 2149 - spin_unlock(&tomoyo_query_list_lock); 2150 - if (found) 2151 - return POLLIN | POLLRDNORM; 2152 - if (i) 2153 - break; 2154 - poll_wait(file, &tomoyo_query_wait, wait); 2155 - } 2135 + if (!list_empty(&tomoyo_query_list)) 2136 + return POLLIN | POLLRDNORM; 2137 + poll_wait(file, &tomoyo_query_wait, wait); 2138 + if (!list_empty(&tomoyo_query_list)) 2139 + return POLLIN | POLLRDNORM; 2156 2140 return 0; 2157 2141 } 2158 2142 ··· 2161 2175 spin_lock(&tomoyo_query_list_lock); 2162 2176 list_for_each(tmp, &tomoyo_query_list) { 2163 2177 struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list); 2164 - if (ptr->answer) 2165 - continue; 2166 2178 if (pos++ != head->r.query_index) 2167 2179 continue; 2168 2180 len = ptr->query_len; ··· 2178 2194 spin_lock(&tomoyo_query_list_lock); 2179 2195 list_for_each(tmp, &tomoyo_query_list) { 2180 2196 struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list); 2181 - if (ptr->answer) 2182 - continue; 2183 2197 if (pos++ != head->r.query_index) 2184 2198 continue; 2185 2199 /* ··· 2225 2243 struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list); 2226 2244 if (ptr->serial != serial) 2227 2245 continue; 2228 - if (!ptr->answer) 2229 - ptr->answer = answer; 2246 + ptr->answer = answer; 2247 + /* Remove from tomoyo_query_list. */ 2248 + if (ptr->answer) 2249 + list_del_init(&ptr->list); 2230 2250 break; 2231 2251 } 2232 2252 spin_unlock(&tomoyo_query_list_lock); ··· 2461 2477 * tomoyo_poll_control - poll() for /sys/kernel/security/tomoyo/ interface. 2462 2478 * 2463 2479 * @file: Pointer to "struct file". 2464 - * @wait: Pointer to "poll_table". 2480 + * @wait: Pointer to "poll_table". Maybe NULL. 2465 2481 * 2466 - * Waits for read readiness. 2467 - * /sys/kernel/security/tomoyo/query is handled by /usr/sbin/tomoyo-queryd and 2468 - * /sys/kernel/security/tomoyo/audit is handled by /usr/sbin/tomoyo-auditd. 2482 + * Returns POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM if ready to read/write, 2483 + * POLLOUT | POLLWRNORM otherwise. 2469 2484 */ 2470 - int tomoyo_poll_control(struct file *file, poll_table *wait) 2485 + unsigned int tomoyo_poll_control(struct file *file, poll_table *wait) 2471 2486 { 2472 2487 struct tomoyo_io_buffer *head = file->private_data; 2473 - if (!head->poll) 2474 - return -ENOSYS; 2475 - return head->poll(file, wait); 2488 + if (head->poll) 2489 + return head->poll(file, wait) | POLLOUT | POLLWRNORM; 2490 + return POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM; 2476 2491 } 2477 2492 2478 2493 /**
+3 -3
security/tomoyo/common.h
··· 788 788 struct tomoyo_io_buffer { 789 789 void (*read) (struct tomoyo_io_buffer *); 790 790 int (*write) (struct tomoyo_io_buffer *); 791 - int (*poll) (struct file *file, poll_table *wait); 791 + unsigned int (*poll) (struct file *file, poll_table *wait); 792 792 /* Exclusive lock for this structure. */ 793 793 struct mutex io_sem; 794 794 char __user *read_user_buf; ··· 981 981 unsigned long number); 982 982 int tomoyo_path_perm(const u8 operation, struct path *path, 983 983 const char *target); 984 - int tomoyo_poll_control(struct file *file, poll_table *wait); 985 - int tomoyo_poll_log(struct file *file, poll_table *wait); 984 + unsigned int tomoyo_poll_control(struct file *file, poll_table *wait); 985 + unsigned int tomoyo_poll_log(struct file *file, poll_table *wait); 986 986 int tomoyo_socket_bind_permission(struct socket *sock, struct sockaddr *addr, 987 987 int addr_len); 988 988 int tomoyo_socket_connect_permission(struct socket *sock,
+22 -20
security/tomoyo/mount.c
··· 199 199 if (flags & MS_REMOUNT) { 200 200 type = tomoyo_mounts[TOMOYO_MOUNT_REMOUNT]; 201 201 flags &= ~MS_REMOUNT; 202 - } 203 - if (flags & MS_MOVE) { 204 - type = tomoyo_mounts[TOMOYO_MOUNT_MOVE]; 205 - flags &= ~MS_MOVE; 206 - } 207 - if (flags & MS_BIND) { 202 + } else if (flags & MS_BIND) { 208 203 type = tomoyo_mounts[TOMOYO_MOUNT_BIND]; 209 204 flags &= ~MS_BIND; 210 - } 211 - if (flags & MS_UNBINDABLE) { 212 - type = tomoyo_mounts[TOMOYO_MOUNT_MAKE_UNBINDABLE]; 213 - flags &= ~MS_UNBINDABLE; 214 - } 215 - if (flags & MS_PRIVATE) { 216 - type = tomoyo_mounts[TOMOYO_MOUNT_MAKE_PRIVATE]; 217 - flags &= ~MS_PRIVATE; 218 - } 219 - if (flags & MS_SLAVE) { 220 - type = tomoyo_mounts[TOMOYO_MOUNT_MAKE_SLAVE]; 221 - flags &= ~MS_SLAVE; 222 - } 223 - if (flags & MS_SHARED) { 205 + } else if (flags & MS_SHARED) { 206 + if (flags & (MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE)) 207 + return -EINVAL; 224 208 type = tomoyo_mounts[TOMOYO_MOUNT_MAKE_SHARED]; 225 209 flags &= ~MS_SHARED; 210 + } else if (flags & MS_PRIVATE) { 211 + if (flags & (MS_SHARED | MS_SLAVE | MS_UNBINDABLE)) 212 + return -EINVAL; 213 + type = tomoyo_mounts[TOMOYO_MOUNT_MAKE_PRIVATE]; 214 + flags &= ~MS_PRIVATE; 215 + } else if (flags & MS_SLAVE) { 216 + if (flags & (MS_SHARED | MS_PRIVATE | MS_UNBINDABLE)) 217 + return -EINVAL; 218 + type = tomoyo_mounts[TOMOYO_MOUNT_MAKE_SLAVE]; 219 + flags &= ~MS_SLAVE; 220 + } else if (flags & MS_UNBINDABLE) { 221 + if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE)) 222 + return -EINVAL; 223 + type = tomoyo_mounts[TOMOYO_MOUNT_MAKE_UNBINDABLE]; 224 + flags &= ~MS_UNBINDABLE; 225 + } else if (flags & MS_MOVE) { 226 + type = tomoyo_mounts[TOMOYO_MOUNT_MOVE]; 227 + flags &= ~MS_MOVE; 226 228 } 227 229 if (!type) 228 230 type = "<NULL>";
+3 -2
security/tomoyo/securityfs_if.c
··· 157 157 * tomoyo_poll - poll() for /sys/kernel/security/tomoyo/ interface. 158 158 * 159 159 * @file: Pointer to "struct file". 160 - * @wait: Pointer to "poll_table". 160 + * @wait: Pointer to "poll_table". Maybe NULL. 161 161 * 162 - * Returns 0 on success, negative value otherwise. 162 + * Returns POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM if ready to read/write, 163 + * POLLOUT | POLLWRNORM otherwise. 163 164 */ 164 165 static unsigned int tomoyo_poll(struct file *file, poll_table *wait) 165 166 {
+13
security/yama/Kconfig
··· 1 + config SECURITY_YAMA 2 + bool "Yama support" 3 + depends on SECURITY 4 + select SECURITYFS 5 + select SECURITY_PATH 6 + default n 7 + help 8 + This selects Yama, which extends DAC support with additional 9 + system-wide security settings beyond regular Linux discretionary 10 + access controls. Currently available is ptrace scope restriction. 11 + Further information can be found in Documentation/security/Yama.txt. 12 + 13 + If you are unsure how to answer this question, answer N.
+3
security/yama/Makefile
··· 1 + obj-$(CONFIG_SECURITY_YAMA) := yama.o 2 + 3 + yama-y := yama_lsm.o
+323
security/yama/yama_lsm.c
··· 1 + /* 2 + * Yama Linux Security Module 3 + * 4 + * Author: Kees Cook <keescook@chromium.org> 5 + * 6 + * Copyright (C) 2010 Canonical, Ltd. 7 + * Copyright (C) 2011 The Chromium OS Authors. 8 + * 9 + * This program is free software; you can redistribute it and/or modify 10 + * it under the terms of the GNU General Public License version 2, as 11 + * published by the Free Software Foundation. 12 + * 13 + */ 14 + 15 + #include <linux/security.h> 16 + #include <linux/sysctl.h> 17 + #include <linux/ptrace.h> 18 + #include <linux/prctl.h> 19 + #include <linux/ratelimit.h> 20 + 21 + static int ptrace_scope = 1; 22 + 23 + /* describe a ptrace relationship for potential exception */ 24 + struct ptrace_relation { 25 + struct task_struct *tracer; 26 + struct task_struct *tracee; 27 + struct list_head node; 28 + }; 29 + 30 + static LIST_HEAD(ptracer_relations); 31 + static DEFINE_SPINLOCK(ptracer_relations_lock); 32 + 33 + /** 34 + * yama_ptracer_add - add/replace an exception for this tracer/tracee pair 35 + * @tracer: the task_struct of the process doing the ptrace 36 + * @tracee: the task_struct of the process to be ptraced 37 + * 38 + * Each tracee can have, at most, one tracer registered. Each time this 39 + * is called, the prior registered tracer will be replaced for the tracee. 40 + * 41 + * Returns 0 if relationship was added, -ve on error. 42 + */ 43 + static int yama_ptracer_add(struct task_struct *tracer, 44 + struct task_struct *tracee) 45 + { 46 + int rc = 0; 47 + struct ptrace_relation *added; 48 + struct ptrace_relation *entry, *relation = NULL; 49 + 50 + added = kmalloc(sizeof(*added), GFP_KERNEL); 51 + if (!added) 52 + return -ENOMEM; 53 + 54 + spin_lock_bh(&ptracer_relations_lock); 55 + list_for_each_entry(entry, &ptracer_relations, node) 56 + if (entry->tracee == tracee) { 57 + relation = entry; 58 + break; 59 + } 60 + if (!relation) { 61 + relation = added; 62 + relation->tracee = tracee; 63 + list_add(&relation->node, &ptracer_relations); 64 + } 65 + relation->tracer = tracer; 66 + 67 + spin_unlock_bh(&ptracer_relations_lock); 68 + if (added != relation) 69 + kfree(added); 70 + 71 + return rc; 72 + } 73 + 74 + /** 75 + * yama_ptracer_del - remove exceptions related to the given tasks 76 + * @tracer: remove any relation where tracer task matches 77 + * @tracee: remove any relation where tracee task matches 78 + */ 79 + static void yama_ptracer_del(struct task_struct *tracer, 80 + struct task_struct *tracee) 81 + { 82 + struct ptrace_relation *relation, *safe; 83 + 84 + spin_lock_bh(&ptracer_relations_lock); 85 + list_for_each_entry_safe(relation, safe, &ptracer_relations, node) 86 + if (relation->tracee == tracee || 87 + (tracer && relation->tracer == tracer)) { 88 + list_del(&relation->node); 89 + kfree(relation); 90 + } 91 + spin_unlock_bh(&ptracer_relations_lock); 92 + } 93 + 94 + /** 95 + * yama_task_free - check for task_pid to remove from exception list 96 + * @task: task being removed 97 + */ 98 + static void yama_task_free(struct task_struct *task) 99 + { 100 + yama_ptracer_del(task, task); 101 + } 102 + 103 + /** 104 + * yama_task_prctl - check for Yama-specific prctl operations 105 + * @option: operation 106 + * @arg2: argument 107 + * @arg3: argument 108 + * @arg4: argument 109 + * @arg5: argument 110 + * 111 + * Return 0 on success, -ve on error. -ENOSYS is returned when Yama 112 + * does not handle the given option. 113 + */ 114 + static int yama_task_prctl(int option, unsigned long arg2, unsigned long arg3, 115 + unsigned long arg4, unsigned long arg5) 116 + { 117 + int rc; 118 + struct task_struct *myself = current; 119 + 120 + rc = cap_task_prctl(option, arg2, arg3, arg4, arg5); 121 + if (rc != -ENOSYS) 122 + return rc; 123 + 124 + switch (option) { 125 + case PR_SET_PTRACER: 126 + /* Since a thread can call prctl(), find the group leader 127 + * before calling _add() or _del() on it, since we want 128 + * process-level granularity of control. The tracer group 129 + * leader checking is handled later when walking the ancestry 130 + * at the time of PTRACE_ATTACH check. 131 + */ 132 + rcu_read_lock(); 133 + if (!thread_group_leader(myself)) 134 + myself = rcu_dereference(myself->group_leader); 135 + get_task_struct(myself); 136 + rcu_read_unlock(); 137 + 138 + if (arg2 == 0) { 139 + yama_ptracer_del(NULL, myself); 140 + rc = 0; 141 + } else if (arg2 == PR_SET_PTRACER_ANY) { 142 + rc = yama_ptracer_add(NULL, myself); 143 + } else { 144 + struct task_struct *tracer; 145 + 146 + rcu_read_lock(); 147 + tracer = find_task_by_vpid(arg2); 148 + if (tracer) 149 + get_task_struct(tracer); 150 + else 151 + rc = -EINVAL; 152 + rcu_read_unlock(); 153 + 154 + if (tracer) { 155 + rc = yama_ptracer_add(tracer, myself); 156 + put_task_struct(tracer); 157 + } 158 + } 159 + 160 + put_task_struct(myself); 161 + break; 162 + } 163 + 164 + return rc; 165 + } 166 + 167 + /** 168 + * task_is_descendant - walk up a process family tree looking for a match 169 + * @parent: the process to compare against while walking up from child 170 + * @child: the process to start from while looking upwards for parent 171 + * 172 + * Returns 1 if child is a descendant of parent, 0 if not. 173 + */ 174 + static int task_is_descendant(struct task_struct *parent, 175 + struct task_struct *child) 176 + { 177 + int rc = 0; 178 + struct task_struct *walker = child; 179 + 180 + if (!parent || !child) 181 + return 0; 182 + 183 + rcu_read_lock(); 184 + if (!thread_group_leader(parent)) 185 + parent = rcu_dereference(parent->group_leader); 186 + while (walker->pid > 0) { 187 + if (!thread_group_leader(walker)) 188 + walker = rcu_dereference(walker->group_leader); 189 + if (walker == parent) { 190 + rc = 1; 191 + break; 192 + } 193 + walker = rcu_dereference(walker->real_parent); 194 + } 195 + rcu_read_unlock(); 196 + 197 + return rc; 198 + } 199 + 200 + /** 201 + * ptracer_exception_found - tracer registered as exception for this tracee 202 + * @tracer: the task_struct of the process attempting ptrace 203 + * @tracee: the task_struct of the process to be ptraced 204 + * 205 + * Returns 1 if tracer has is ptracer exception ancestor for tracee. 206 + */ 207 + static int ptracer_exception_found(struct task_struct *tracer, 208 + struct task_struct *tracee) 209 + { 210 + int rc = 0; 211 + struct ptrace_relation *relation; 212 + struct task_struct *parent = NULL; 213 + bool found = false; 214 + 215 + spin_lock_bh(&ptracer_relations_lock); 216 + rcu_read_lock(); 217 + if (!thread_group_leader(tracee)) 218 + tracee = rcu_dereference(tracee->group_leader); 219 + list_for_each_entry(relation, &ptracer_relations, node) 220 + if (relation->tracee == tracee) { 221 + parent = relation->tracer; 222 + found = true; 223 + break; 224 + } 225 + 226 + if (found && (parent == NULL || task_is_descendant(parent, tracer))) 227 + rc = 1; 228 + rcu_read_unlock(); 229 + spin_unlock_bh(&ptracer_relations_lock); 230 + 231 + return rc; 232 + } 233 + 234 + /** 235 + * yama_ptrace_access_check - validate PTRACE_ATTACH calls 236 + * @child: task that current task is attempting to ptrace 237 + * @mode: ptrace attach mode 238 + * 239 + * Returns 0 if following the ptrace is allowed, -ve on error. 240 + */ 241 + static int yama_ptrace_access_check(struct task_struct *child, 242 + unsigned int mode) 243 + { 244 + int rc; 245 + 246 + /* If standard caps disallows it, so does Yama. We should 247 + * only tighten restrictions further. 248 + */ 249 + rc = cap_ptrace_access_check(child, mode); 250 + if (rc) 251 + return rc; 252 + 253 + /* require ptrace target be a child of ptracer on attach */ 254 + if (mode == PTRACE_MODE_ATTACH && 255 + ptrace_scope && 256 + !task_is_descendant(current, child) && 257 + !ptracer_exception_found(current, child) && 258 + !capable(CAP_SYS_PTRACE)) 259 + rc = -EPERM; 260 + 261 + if (rc) { 262 + char name[sizeof(current->comm)]; 263 + printk_ratelimited(KERN_NOTICE "ptrace of non-child" 264 + " pid %d was attempted by: %s (pid %d)\n", 265 + child->pid, 266 + get_task_comm(name, current), 267 + current->pid); 268 + } 269 + 270 + return rc; 271 + } 272 + 273 + static struct security_operations yama_ops = { 274 + .name = "yama", 275 + 276 + .ptrace_access_check = yama_ptrace_access_check, 277 + .task_prctl = yama_task_prctl, 278 + .task_free = yama_task_free, 279 + }; 280 + 281 + #ifdef CONFIG_SYSCTL 282 + static int zero; 283 + static int one = 1; 284 + 285 + struct ctl_path yama_sysctl_path[] = { 286 + { .procname = "kernel", }, 287 + { .procname = "yama", }, 288 + { } 289 + }; 290 + 291 + static struct ctl_table yama_sysctl_table[] = { 292 + { 293 + .procname = "ptrace_scope", 294 + .data = &ptrace_scope, 295 + .maxlen = sizeof(int), 296 + .mode = 0644, 297 + .proc_handler = proc_dointvec_minmax, 298 + .extra1 = &zero, 299 + .extra2 = &one, 300 + }, 301 + { } 302 + }; 303 + #endif /* CONFIG_SYSCTL */ 304 + 305 + static __init int yama_init(void) 306 + { 307 + if (!security_module_enable(&yama_ops)) 308 + return 0; 309 + 310 + printk(KERN_INFO "Yama: becoming mindful.\n"); 311 + 312 + if (register_security(&yama_ops)) 313 + panic("Yama: kernel registration failed.\n"); 314 + 315 + #ifdef CONFIG_SYSCTL 316 + if (!register_sysctl_paths(yama_sysctl_path, yama_sysctl_table)) 317 + panic("Yama: sysctl registration failed.\n"); 318 + #endif 319 + 320 + return 0; 321 + } 322 + 323 + security_initcall(yama_init);