aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/Smack.txt20
-rw-r--r--Documentation/kernel-parameters.txt6
-rw-r--r--Documentation/sysctl/kernel.txt11
-rw-r--r--fs/compat.c6
-rw-r--r--fs/exec.c10
-rw-r--r--fs/hugetlbfs/inode.c2
-rw-r--r--fs/namei.c6
-rw-r--r--fs/nfsd/vfs.c14
-rw-r--r--fs/proc/base.c6
-rw-r--r--include/linux/ima.h11
-rw-r--r--include/linux/init_task.h4
-rw-r--r--include/linux/lsm_audit.h111
-rw-r--r--include/linux/magic.h1
-rw-r--r--include/linux/mm.h2
-rw-r--r--include/linux/sched.h5
-rw-r--r--include/linux/security.h2
-rw-r--r--ipc/shm.c3
-rw-r--r--kernel/cred.c4
-rw-r--r--kernel/exit.c1
-rw-r--r--kernel/module.c7
-rw-r--r--kernel/ptrace.c9
-rw-r--r--kernel/signal.c11
-rw-r--r--kernel/sysctl.c14
-rw-r--r--mm/Kconfig19
-rw-r--r--mm/mmap.c3
-rw-r--r--mm/nommu.c3
-rw-r--r--mm/shmem.c2
-rw-r--r--security/Kconfig22
-rw-r--r--security/Makefile3
-rw-r--r--security/commoncap.c32
-rw-r--r--security/inode.c2
-rw-r--r--security/integrity/ima/ima_audit.c32
-rw-r--r--security/integrity/ima/ima_crypto.c4
-rw-r--r--security/integrity/ima/ima_fs.c8
-rw-r--r--security/integrity/ima/ima_iint.c2
-rw-r--r--security/integrity/ima/ima_init.c4
-rw-r--r--security/integrity/ima/ima_main.c86
-rw-r--r--security/integrity/ima/ima_policy.c48
-rw-r--r--security/lsm_audit.c386
-rw-r--r--security/root_plug.c12
-rw-r--r--security/security.c3
-rw-r--r--security/selinux/avc.c2
-rw-r--r--security/selinux/hooks.c24
-rw-r--r--security/selinux/include/security.h7
-rw-r--r--security/selinux/nlmsgtab.c2
-rw-r--r--security/selinux/selinuxfs.c8
-rw-r--r--security/selinux/ss/services.c30
-rw-r--r--security/smack/smack.h108
-rw-r--r--security/smack/smack_access.c143
-rw-r--r--security/smack/smack_lsm.c405
-rw-r--r--security/smack/smackfs.c68
-rw-r--r--security/tomoyo/common.c119
-rw-r--r--security/tomoyo/common.h134
-rw-r--r--security/tomoyo/domain.c240
-rw-r--r--security/tomoyo/file.c156
-rw-r--r--security/tomoyo/realpath.c23
-rw-r--r--security/tomoyo/tomoyo.c4
-rw-r--r--security/tomoyo/tomoyo.h13
58 files changed, 1946 insertions, 477 deletions
diff --git a/Documentation/Smack.txt b/Documentation/Smack.txt
index 629c92e99783..34614b4c708e 100644
--- a/Documentation/Smack.txt
+++ b/Documentation/Smack.txt
@@ -184,8 +184,9 @@ length. Single character labels using special characters, that being anything
184other than a letter or digit, are reserved for use by the Smack development 184other than a letter or digit, are reserved for use by the Smack development
185team. Smack labels are unstructured, case sensitive, and the only operation 185team. Smack labels are unstructured, case sensitive, and the only operation
186ever performed on them is comparison for equality. Smack labels cannot 186ever performed on them is comparison for equality. Smack labels cannot
187contain unprintable characters or the "/" (slash) character. Smack labels 187contain unprintable characters, the "/" (slash), the "\" (backslash), the "'"
188cannot begin with a '-', which is reserved for special options. 188(quote) and '"' (double-quote) characters.
189Smack labels cannot begin with a '-', which is reserved for special options.
189 190
190There are some predefined labels: 191There are some predefined labels:
191 192
@@ -523,3 +524,18 @@ Smack supports some mount options:
523 524
524These mount options apply to all file system types. 525These mount options apply to all file system types.
525 526
527Smack auditing
528
529If you want Smack auditing of security events, you need to set CONFIG_AUDIT
530in your kernel configuration.
531By default, all denied events will be audited. You can change this behavior by
532writing a single character to the /smack/logging file :
5330 : no logging
5341 : log denied (default)
5352 : log accepted
5363 : log denied & accepted
537
538Events are logged as 'key=value' pairs, for each event you at least will get
539the subjet, the object, the rights requested, the action, the kernel function
540that triggered the event, plus other pairs depending on the type of event
541audited.
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index af43f45e8358..a5253f6d01af 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -916,6 +916,12 @@ and is between 256 and 4096 characters. It is defined in the file
916 Formt: { "sha1" | "md5" } 916 Formt: { "sha1" | "md5" }
917 default: "sha1" 917 default: "sha1"
918 918
919 ima_tcb [IMA]
920 Load a policy which meets the needs of the Trusted
921 Computing Base. This means IMA will measure all
922 programs exec'd, files mmap'd for exec, and all files
923 opened for read by uid=0.
924
919 in2000= [HW,SCSI] 925 in2000= [HW,SCSI]
920 See header of drivers/scsi/in2000.c. 926 See header of drivers/scsi/in2000.c.
921 927
diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt
index f11ca7979fa6..322a00bb99d9 100644
--- a/Documentation/sysctl/kernel.txt
+++ b/Documentation/sysctl/kernel.txt
@@ -32,6 +32,7 @@ show up in /proc/sys/kernel:
32- kstack_depth_to_print [ X86 only ] 32- kstack_depth_to_print [ X86 only ]
33- l2cr [ PPC only ] 33- l2cr [ PPC only ]
34- modprobe ==> Documentation/debugging-modules.txt 34- modprobe ==> Documentation/debugging-modules.txt
35- modules_disabled
35- msgmax 36- msgmax
36- msgmnb 37- msgmnb
37- msgmni 38- msgmni
@@ -184,6 +185,16 @@ kernel stack.
184 185
185============================================================== 186==============================================================
186 187
188modules_disabled:
189
190A toggle value indicating if modules are allowed to be loaded
191in an otherwise modular kernel. This toggle defaults to off
192(0), but can be set true (1). Once true, modules can be
193neither loaded nor unloaded, and the toggle cannot be set back
194to false.
195
196==============================================================
197
187osrelease, ostype & version: 198osrelease, ostype & version:
188 199
189# cat osrelease 200# cat osrelease
diff --git a/fs/compat.c b/fs/compat.c
index 681ed81e6be0..bb2a9b2e8173 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -1488,7 +1488,7 @@ int compat_do_execve(char * filename,
1488 if (!bprm) 1488 if (!bprm)
1489 goto out_files; 1489 goto out_files;
1490 1490
1491 retval = mutex_lock_interruptible(&current->cred_exec_mutex); 1491 retval = mutex_lock_interruptible(&current->cred_guard_mutex);
1492 if (retval < 0) 1492 if (retval < 0)
1493 goto out_free; 1493 goto out_free;
1494 current->in_execve = 1; 1494 current->in_execve = 1;
@@ -1550,7 +1550,7 @@ int compat_do_execve(char * filename,
1550 /* execve succeeded */ 1550 /* execve succeeded */
1551 current->fs->in_exec = 0; 1551 current->fs->in_exec = 0;
1552 current->in_execve = 0; 1552 current->in_execve = 0;
1553 mutex_unlock(&current->cred_exec_mutex); 1553 mutex_unlock(&current->cred_guard_mutex);
1554 acct_update_integrals(current); 1554 acct_update_integrals(current);
1555 free_bprm(bprm); 1555 free_bprm(bprm);
1556 if (displaced) 1556 if (displaced)
@@ -1573,7 +1573,7 @@ out_unmark:
1573 1573
1574out_unlock: 1574out_unlock:
1575 current->in_execve = 0; 1575 current->in_execve = 0;
1576 mutex_unlock(&current->cred_exec_mutex); 1576 mutex_unlock(&current->cred_guard_mutex);
1577 1577
1578out_free: 1578out_free:
1579 free_bprm(bprm); 1579 free_bprm(bprm);
diff --git a/fs/exec.c b/fs/exec.c
index 895823d0149d..a7fcd975c6b2 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1016,7 +1016,7 @@ void install_exec_creds(struct linux_binprm *bprm)
1016 commit_creds(bprm->cred); 1016 commit_creds(bprm->cred);
1017 bprm->cred = NULL; 1017 bprm->cred = NULL;
1018 1018
1019 /* cred_exec_mutex must be held at least to this point to prevent 1019 /* cred_guard_mutex must be held at least to this point to prevent
1020 * ptrace_attach() from altering our determination of the task's 1020 * ptrace_attach() from altering our determination of the task's
1021 * credentials; any time after this it may be unlocked */ 1021 * credentials; any time after this it may be unlocked */
1022 1022
@@ -1026,7 +1026,7 @@ EXPORT_SYMBOL(install_exec_creds);
1026 1026
1027/* 1027/*
1028 * determine how safe it is to execute the proposed program 1028 * determine how safe it is to execute the proposed program
1029 * - the caller must hold current->cred_exec_mutex to protect against 1029 * - the caller must hold current->cred_guard_mutex to protect against
1030 * PTRACE_ATTACH 1030 * PTRACE_ATTACH
1031 */ 1031 */
1032int check_unsafe_exec(struct linux_binprm *bprm) 1032int check_unsafe_exec(struct linux_binprm *bprm)
@@ -1268,7 +1268,7 @@ int do_execve(char * filename,
1268 if (!bprm) 1268 if (!bprm)
1269 goto out_files; 1269 goto out_files;
1270 1270
1271 retval = mutex_lock_interruptible(&current->cred_exec_mutex); 1271 retval = mutex_lock_interruptible(&current->cred_guard_mutex);
1272 if (retval < 0) 1272 if (retval < 0)
1273 goto out_free; 1273 goto out_free;
1274 current->in_execve = 1; 1274 current->in_execve = 1;
@@ -1331,7 +1331,7 @@ int do_execve(char * filename,
1331 /* execve succeeded */ 1331 /* execve succeeded */
1332 current->fs->in_exec = 0; 1332 current->fs->in_exec = 0;
1333 current->in_execve = 0; 1333 current->in_execve = 0;
1334 mutex_unlock(&current->cred_exec_mutex); 1334 mutex_unlock(&current->cred_guard_mutex);
1335 acct_update_integrals(current); 1335 acct_update_integrals(current);
1336 free_bprm(bprm); 1336 free_bprm(bprm);
1337 if (displaced) 1337 if (displaced)
@@ -1354,7 +1354,7 @@ out_unmark:
1354 1354
1355out_unlock: 1355out_unlock:
1356 current->in_execve = 0; 1356 current->in_execve = 0;
1357 mutex_unlock(&current->cred_exec_mutex); 1357 mutex_unlock(&current->cred_guard_mutex);
1358 1358
1359out_free: 1359out_free:
1360 free_bprm(bprm); 1360 free_bprm(bprm);
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index c1462d43e721..941c8425c10b 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -30,6 +30,7 @@
30#include <linux/dnotify.h> 30#include <linux/dnotify.h>
31#include <linux/statfs.h> 31#include <linux/statfs.h>
32#include <linux/security.h> 32#include <linux/security.h>
33#include <linux/ima.h>
33 34
34#include <asm/uaccess.h> 35#include <asm/uaccess.h>
35 36
@@ -986,6 +987,7 @@ struct file *hugetlb_file_setup(const char *name, size_t size, int acctflag)
986 &hugetlbfs_file_operations); 987 &hugetlbfs_file_operations);
987 if (!file) 988 if (!file)
988 goto out_dentry; /* inode is already attached */ 989 goto out_dentry; /* inode is already attached */
990 ima_counts_get(file);
989 991
990 return file; 992 return file;
991 993
diff --git a/fs/namei.c b/fs/namei.c
index 967c3db92724..c82805d088e1 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -853,7 +853,8 @@ static int __link_path_walk(const char *name, struct nameidata *nd)
853 err = inode_permission(nd->path.dentry->d_inode, 853 err = inode_permission(nd->path.dentry->d_inode,
854 MAY_EXEC); 854 MAY_EXEC);
855 if (!err) 855 if (!err)
856 err = ima_path_check(&nd->path, MAY_EXEC); 856 err = ima_path_check(&nd->path, MAY_EXEC,
857 IMA_COUNT_UPDATE);
857 if (err) 858 if (err)
858 break; 859 break;
859 860
@@ -1515,7 +1516,8 @@ int may_open(struct path *path, int acc_mode, int flag)
1515 return error; 1516 return error;
1516 1517
1517 error = ima_path_check(path, 1518 error = ima_path_check(path,
1518 acc_mode & (MAY_READ | MAY_WRITE | MAY_EXEC)); 1519 acc_mode & (MAY_READ | MAY_WRITE | MAY_EXEC),
1520 IMA_COUNT_UPDATE);
1519 if (error) 1521 if (error)
1520 return error; 1522 return error;
1521 /* 1523 /*
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index b660435978d2..bd584bcf1d9f 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -55,6 +55,7 @@
55#include <linux/security.h> 55#include <linux/security.h>
56#endif /* CONFIG_NFSD_V4 */ 56#endif /* CONFIG_NFSD_V4 */
57#include <linux/jhash.h> 57#include <linux/jhash.h>
58#include <linux/ima.h>
58 59
59#include <asm/uaccess.h> 60#include <asm/uaccess.h>
60 61
@@ -735,6 +736,8 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
735 flags, cred); 736 flags, cred);
736 if (IS_ERR(*filp)) 737 if (IS_ERR(*filp))
737 host_err = PTR_ERR(*filp); 738 host_err = PTR_ERR(*filp);
739 else
740 ima_counts_get(*filp);
738out_nfserr: 741out_nfserr:
739 err = nfserrno(host_err); 742 err = nfserrno(host_err);
740out: 743out:
@@ -2024,6 +2027,7 @@ nfsd_permission(struct svc_rqst *rqstp, struct svc_export *exp,
2024 struct dentry *dentry, int acc) 2027 struct dentry *dentry, int acc)
2025{ 2028{
2026 struct inode *inode = dentry->d_inode; 2029 struct inode *inode = dentry->d_inode;
2030 struct path path;
2027 int err; 2031 int err;
2028 2032
2029 if (acc == NFSD_MAY_NOP) 2033 if (acc == NFSD_MAY_NOP)
@@ -2096,7 +2100,17 @@ nfsd_permission(struct svc_rqst *rqstp, struct svc_export *exp,
2096 if (err == -EACCES && S_ISREG(inode->i_mode) && 2100 if (err == -EACCES && S_ISREG(inode->i_mode) &&
2097 acc == (NFSD_MAY_READ | NFSD_MAY_OWNER_OVERRIDE)) 2101 acc == (NFSD_MAY_READ | NFSD_MAY_OWNER_OVERRIDE))
2098 err = inode_permission(inode, MAY_EXEC); 2102 err = inode_permission(inode, MAY_EXEC);
2103 if (err)
2104 goto nfsd_out;
2099 2105
2106 /* Do integrity (permission) checking now, but defer incrementing
2107 * IMA counts to the actual file open.
2108 */
2109 path.mnt = exp->ex_path.mnt;
2110 path.dentry = dentry;
2111 err = ima_path_check(&path, acc & (MAY_READ | MAY_WRITE | MAY_EXEC),
2112 IMA_COUNT_LEAVE);
2113nfsd_out:
2100 return err? nfserrno(err) : 0; 2114 return err? nfserrno(err) : 0;
2101} 2115}
2102 2116
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 3326bbf9ab95..1539e630c47d 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -2128,9 +2128,15 @@ static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf,
2128 if (copy_from_user(page, buf, count)) 2128 if (copy_from_user(page, buf, count))
2129 goto out_free; 2129 goto out_free;
2130 2130
2131 /* Guard against adverse ptrace interaction */
2132 length = mutex_lock_interruptible(&task->cred_guard_mutex);
2133 if (length < 0)
2134 goto out_free;
2135
2131 length = security_setprocattr(task, 2136 length = security_setprocattr(task,
2132 (char*)file->f_path.dentry->d_name.name, 2137 (char*)file->f_path.dentry->d_name.name,
2133 (void*)page, count); 2138 (void*)page, count);
2139 mutex_unlock(&task->cred_guard_mutex);
2134out_free: 2140out_free:
2135 free_page((unsigned long) page); 2141 free_page((unsigned long) page);
2136out: 2142out:
diff --git a/include/linux/ima.h b/include/linux/ima.h
index 0e2aa45cb0ce..b1b827d091a9 100644
--- a/include/linux/ima.h
+++ b/include/linux/ima.h
@@ -13,14 +13,17 @@
13#include <linux/fs.h> 13#include <linux/fs.h>
14struct linux_binprm; 14struct linux_binprm;
15 15
16#define IMA_COUNT_UPDATE 1
17#define IMA_COUNT_LEAVE 0
18
16#ifdef CONFIG_IMA 19#ifdef CONFIG_IMA
17extern int ima_bprm_check(struct linux_binprm *bprm); 20extern int ima_bprm_check(struct linux_binprm *bprm);
18extern int ima_inode_alloc(struct inode *inode); 21extern int ima_inode_alloc(struct inode *inode);
19extern void ima_inode_free(struct inode *inode); 22extern void ima_inode_free(struct inode *inode);
20extern int ima_path_check(struct path *path, int mask); 23extern int ima_path_check(struct path *path, int mask, int update_counts);
21extern void ima_file_free(struct file *file); 24extern void ima_file_free(struct file *file);
22extern int ima_file_mmap(struct file *file, unsigned long prot); 25extern int ima_file_mmap(struct file *file, unsigned long prot);
23extern void ima_shm_check(struct file *file); 26extern void ima_counts_get(struct file *file);
24 27
25#else 28#else
26static inline int ima_bprm_check(struct linux_binprm *bprm) 29static inline int ima_bprm_check(struct linux_binprm *bprm)
@@ -38,7 +41,7 @@ static inline void ima_inode_free(struct inode *inode)
38 return; 41 return;
39} 42}
40 43
41static inline int ima_path_check(struct path *path, int mask) 44static inline int ima_path_check(struct path *path, int mask, int update_counts)
42{ 45{
43 return 0; 46 return 0;
44} 47}
@@ -53,7 +56,7 @@ static inline int ima_file_mmap(struct file *file, unsigned long prot)
53 return 0; 56 return 0;
54} 57}
55 58
56static inline void ima_shm_check(struct file *file) 59static inline void ima_counts_get(struct file *file)
57{ 60{
58 return; 61 return;
59} 62}
diff --git a/include/linux/init_task.h b/include/linux/init_task.h
index d87247d2641f..7f54ba942429 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -145,8 +145,8 @@ extern struct cred init_cred;
145 .group_leader = &tsk, \ 145 .group_leader = &tsk, \
146 .real_cred = &init_cred, \ 146 .real_cred = &init_cred, \
147 .cred = &init_cred, \ 147 .cred = &init_cred, \
148 .cred_exec_mutex = \ 148 .cred_guard_mutex = \
149 __MUTEX_INITIALIZER(tsk.cred_exec_mutex), \ 149 __MUTEX_INITIALIZER(tsk.cred_guard_mutex), \
150 .comm = "swapper", \ 150 .comm = "swapper", \
151 .thread = INIT_THREAD, \ 151 .thread = INIT_THREAD, \
152 .fs = &init_fs, \ 152 .fs = &init_fs, \
diff --git a/include/linux/lsm_audit.h b/include/linux/lsm_audit.h
new file mode 100644
index 000000000000..e461b2c3d711
--- /dev/null
+++ b/include/linux/lsm_audit.h
@@ -0,0 +1,111 @@
1/*
2 * Common LSM logging functions
3 * Heavily borrowed from selinux/avc.h
4 *
5 * Author : Etienne BASSET <etienne.basset@ensta.org>
6 *
7 * All credits to : Stephen Smalley, <sds@epoch.ncsc.mil>
8 * All BUGS to : Etienne BASSET <etienne.basset@ensta.org>
9 */
10#ifndef _LSM_COMMON_LOGGING_
11#define _LSM_COMMON_LOGGING_
12
13#include <linux/stddef.h>
14#include <linux/errno.h>
15#include <linux/kernel.h>
16#include <linux/kdev_t.h>
17#include <linux/spinlock.h>
18#include <linux/init.h>
19#include <linux/audit.h>
20#include <linux/in6.h>
21#include <linux/path.h>
22#include <linux/key.h>
23#include <linux/skbuff.h>
24#include <asm/system.h>
25
26
27/* Auxiliary data to use in generating the audit record. */
28struct common_audit_data {
29 char type;
30#define LSM_AUDIT_DATA_FS 1
31#define LSM_AUDIT_DATA_NET 2
32#define LSM_AUDIT_DATA_CAP 3
33#define LSM_AUDIT_DATA_IPC 4
34#define LSM_AUDIT_DATA_TASK 5
35#define LSM_AUDIT_DATA_KEY 6
36 struct task_struct *tsk;
37 union {
38 struct {
39 struct path path;
40 struct inode *inode;
41 } fs;
42 struct {
43 int netif;
44 struct sock *sk;
45 u16 family;
46 __be16 dport;
47 __be16 sport;
48 union {
49 struct {
50 __be32 daddr;
51 __be32 saddr;
52 } v4;
53 struct {
54 struct in6_addr daddr;
55 struct in6_addr saddr;
56 } v6;
57 } fam;
58 } net;
59 int cap;
60 int ipc_id;
61 struct task_struct *tsk;
62#ifdef CONFIG_KEYS
63 struct {
64 key_serial_t key;
65 char *key_desc;
66 } key_struct;
67#endif
68 } u;
69 const char *function;
70 /* this union contains LSM specific data */
71 union {
72 /* SMACK data */
73 struct smack_audit_data {
74 char *subject;
75 char *object;
76 char *request;
77 int result;
78 } smack_audit_data;
79 /* SELinux data */
80 struct {
81 u32 ssid;
82 u32 tsid;
83 u16 tclass;
84 u32 requested;
85 u32 audited;
86 struct av_decision *avd;
87 int result;
88 } selinux_audit_data;
89 } lsm_priv;
90 /* these callback will be implemented by a specific LSM */
91 void (*lsm_pre_audit)(struct audit_buffer *, void *);
92 void (*lsm_post_audit)(struct audit_buffer *, void *);
93};
94
95#define v4info fam.v4
96#define v6info fam.v6
97
98int ipv4_skb_to_auditdata(struct sk_buff *skb,
99 struct common_audit_data *ad, u8 *proto);
100
101int ipv6_skb_to_auditdata(struct sk_buff *skb,
102 struct common_audit_data *ad, u8 *proto);
103
104/* Initialize an LSM audit data structure. */
105#define COMMON_AUDIT_DATA_INIT(_d, _t) \
106 { memset((_d), 0, sizeof(struct common_audit_data)); \
107 (_d)->type = LSM_AUDIT_DATA_##_t; (_d)->function = __func__; }
108
109void common_lsm_audit(struct common_audit_data *a);
110
111#endif
diff --git a/include/linux/magic.h b/include/linux/magic.h
index 5b4e28bcb788..927138cf3050 100644
--- a/include/linux/magic.h
+++ b/include/linux/magic.h
@@ -9,6 +9,7 @@
9#define DEBUGFS_MAGIC 0x64626720 9#define DEBUGFS_MAGIC 0x64626720
10#define SYSFS_MAGIC 0x62656572 10#define SYSFS_MAGIC 0x62656572
11#define SECURITYFS_MAGIC 0x73636673 11#define SECURITYFS_MAGIC 0x73636673
12#define SELINUX_MAGIC 0xf97cff8c
12#define TMPFS_MAGIC 0x01021994 13#define TMPFS_MAGIC 0x01021994
13#define SQUASHFS_MAGIC 0x73717368 14#define SQUASHFS_MAGIC 0x73717368
14#define EFS_SUPER_MAGIC 0x414A53 15#define EFS_SUPER_MAGIC 0x414A53
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 511b09867096..5528ff32512e 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -580,12 +580,10 @@ static inline void set_page_links(struct page *page, enum zone_type zone,
580 */ 580 */
581static inline unsigned long round_hint_to_min(unsigned long hint) 581static inline unsigned long round_hint_to_min(unsigned long hint)
582{ 582{
583#ifdef CONFIG_SECURITY
584 hint &= PAGE_MASK; 583 hint &= PAGE_MASK;
585 if (((void *)hint != NULL) && 584 if (((void *)hint != NULL) &&
586 (hint < mmap_min_addr)) 585 (hint < mmap_min_addr))
587 return PAGE_ALIGN(mmap_min_addr); 586 return PAGE_ALIGN(mmap_min_addr);
588#endif
589 return hint; 587 return hint;
590} 588}
591 589
diff --git a/include/linux/sched.h b/include/linux/sched.h
index dbb1043e8656..ff687281f233 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1267,7 +1267,9 @@ struct task_struct {
1267 * credentials (COW) */ 1267 * credentials (COW) */
1268 const struct cred *cred; /* effective (overridable) subjective task 1268 const struct cred *cred; /* effective (overridable) subjective task
1269 * credentials (COW) */ 1269 * credentials (COW) */
1270 struct mutex cred_exec_mutex; /* execve vs ptrace cred calculation mutex */ 1270 struct mutex cred_guard_mutex; /* guard against foreign influences on
1271 * credential calculations
1272 * (notably. ptrace) */
1271 1273
1272 char comm[TASK_COMM_LEN]; /* executable name excluding path 1274 char comm[TASK_COMM_LEN]; /* executable name excluding path
1273 - access with [gs]et_task_comm (which lock 1275 - access with [gs]et_task_comm (which lock
@@ -1905,6 +1907,7 @@ extern void sched_dead(struct task_struct *p);
1905 1907
1906extern void proc_caches_init(void); 1908extern void proc_caches_init(void);
1907extern void flush_signals(struct task_struct *); 1909extern void flush_signals(struct task_struct *);
1910extern void __flush_signals(struct task_struct *);
1908extern void ignore_signals(struct task_struct *); 1911extern void ignore_signals(struct task_struct *);
1909extern void flush_signal_handlers(struct task_struct *, int force_default); 1912extern void flush_signal_handlers(struct task_struct *, int force_default);
1910extern int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info); 1913extern int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info);
diff --git a/include/linux/security.h b/include/linux/security.h
index d5fd6163606f..5eff459b3833 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -2197,6 +2197,8 @@ static inline int security_file_mmap(struct file *file, unsigned long reqprot,
2197 unsigned long addr, 2197 unsigned long addr,
2198 unsigned long addr_only) 2198 unsigned long addr_only)
2199{ 2199{
2200 if ((addr < mmap_min_addr) && !capable(CAP_SYS_RAWIO))
2201 return -EACCES;
2200 return 0; 2202 return 0;
2201} 2203}
2202 2204
diff --git a/ipc/shm.c b/ipc/shm.c
index 425971600485..15dd238e5338 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -384,7 +384,6 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params)
384 error = PTR_ERR(file); 384 error = PTR_ERR(file);
385 if (IS_ERR(file)) 385 if (IS_ERR(file))
386 goto no_file; 386 goto no_file;
387 ima_shm_check(file);
388 387
389 id = ipc_addid(&shm_ids(ns), &shp->shm_perm, ns->shm_ctlmni); 388 id = ipc_addid(&shm_ids(ns), &shp->shm_perm, ns->shm_ctlmni);
390 if (id < 0) { 389 if (id < 0) {
@@ -891,7 +890,7 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr)
891 file = alloc_file(path.mnt, path.dentry, f_mode, &shm_file_operations); 890 file = alloc_file(path.mnt, path.dentry, f_mode, &shm_file_operations);
892 if (!file) 891 if (!file)
893 goto out_free; 892 goto out_free;
894 ima_shm_check(file); 893 ima_counts_get(file);
895 894
896 file->private_data = sfd; 895 file->private_data = sfd;
897 file->f_mapping = shp->shm_file->f_mapping; 896 file->f_mapping = shp->shm_file->f_mapping;
diff --git a/kernel/cred.c b/kernel/cred.c
index 3a039189d707..1bb4d7e5d616 100644
--- a/kernel/cred.c
+++ b/kernel/cred.c
@@ -167,7 +167,7 @@ EXPORT_SYMBOL(prepare_creds);
167 167
168/* 168/*
169 * Prepare credentials for current to perform an execve() 169 * Prepare credentials for current to perform an execve()
170 * - The caller must hold current->cred_exec_mutex 170 * - The caller must hold current->cred_guard_mutex
171 */ 171 */
172struct cred *prepare_exec_creds(void) 172struct cred *prepare_exec_creds(void)
173{ 173{
@@ -276,7 +276,7 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags)
276 struct cred *new; 276 struct cred *new;
277 int ret; 277 int ret;
278 278
279 mutex_init(&p->cred_exec_mutex); 279 mutex_init(&p->cred_guard_mutex);
280 280
281 if ( 281 if (
282#ifdef CONFIG_KEYS 282#ifdef CONFIG_KEYS
diff --git a/kernel/exit.c b/kernel/exit.c
index abf9cf3b95c6..036e8d740169 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -1476,6 +1476,7 @@ static int wait_consider_task(struct task_struct *parent, int ptrace,
1476 */ 1476 */
1477 if (*notask_error) 1477 if (*notask_error)
1478 *notask_error = ret; 1478 *notask_error = ret;
1479 return 0;
1479 } 1480 }
1480 1481
1481 if (likely(!ptrace) && unlikely(p->ptrace)) { 1482 if (likely(!ptrace) && unlikely(p->ptrace)) {
diff --git a/kernel/module.c b/kernel/module.c
index e797812a4d95..cb3887e770e2 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -72,6 +72,9 @@ DEFINE_MUTEX(module_mutex);
72EXPORT_SYMBOL_GPL(module_mutex); 72EXPORT_SYMBOL_GPL(module_mutex);
73static LIST_HEAD(modules); 73static LIST_HEAD(modules);
74 74
75/* Block module loading/unloading? */
76int modules_disabled = 0;
77
75/* Waiting for a module to finish initializing? */ 78/* Waiting for a module to finish initializing? */
76static DECLARE_WAIT_QUEUE_HEAD(module_wq); 79static DECLARE_WAIT_QUEUE_HEAD(module_wq);
77 80
@@ -777,7 +780,7 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
777 char name[MODULE_NAME_LEN]; 780 char name[MODULE_NAME_LEN];
778 int ret, forced = 0; 781 int ret, forced = 0;
779 782
780 if (!capable(CAP_SYS_MODULE)) 783 if (!capable(CAP_SYS_MODULE) || modules_disabled)
781 return -EPERM; 784 return -EPERM;
782 785
783 if (strncpy_from_user(name, name_user, MODULE_NAME_LEN-1) < 0) 786 if (strncpy_from_user(name, name_user, MODULE_NAME_LEN-1) < 0)
@@ -2336,7 +2339,7 @@ SYSCALL_DEFINE3(init_module, void __user *, umod,
2336 int ret = 0; 2339 int ret = 0;
2337 2340
2338 /* Must have permission */ 2341 /* Must have permission */
2339 if (!capable(CAP_SYS_MODULE)) 2342 if (!capable(CAP_SYS_MODULE) || modules_disabled)
2340 return -EPERM; 2343 return -EPERM;
2341 2344
2342 /* Only one module load at a time, please */ 2345 /* Only one module load at a time, please */
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 42c317874cfa..43a5a3b0be79 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -185,10 +185,11 @@ int ptrace_attach(struct task_struct *task)
185 if (same_thread_group(task, current)) 185 if (same_thread_group(task, current))
186 goto out; 186 goto out;
187 187
188 /* Protect exec's credential calculations against our interference; 188 /* Protect the target's credential calculations against our
189 * SUID, SGID and LSM creds get determined differently under ptrace. 189 * interference; SUID, SGID and LSM creds get determined differently
190 * under ptrace.
190 */ 191 */
191 retval = mutex_lock_interruptible(&task->cred_exec_mutex); 192 retval = mutex_lock_interruptible(&task->cred_guard_mutex);
192 if (retval < 0) 193 if (retval < 0)
193 goto out; 194 goto out;
194 195
@@ -232,7 +233,7 @@ repeat:
232bad: 233bad:
233 write_unlock_irqrestore(&tasklist_lock, flags); 234 write_unlock_irqrestore(&tasklist_lock, flags);
234 task_unlock(task); 235 task_unlock(task);
235 mutex_unlock(&task->cred_exec_mutex); 236 mutex_unlock(&task->cred_guard_mutex);
236out: 237out:
237 return retval; 238 return retval;
238} 239}
diff --git a/kernel/signal.c b/kernel/signal.c
index d8034737db4c..d2dd9cf5dcc6 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -249,14 +249,19 @@ void flush_sigqueue(struct sigpending *queue)
249/* 249/*
250 * Flush all pending signals for a task. 250 * Flush all pending signals for a task.
251 */ 251 */
252void __flush_signals(struct task_struct *t)
253{
254 clear_tsk_thread_flag(t, TIF_SIGPENDING);
255 flush_sigqueue(&t->pending);
256 flush_sigqueue(&t->signal->shared_pending);
257}
258
252void flush_signals(struct task_struct *t) 259void flush_signals(struct task_struct *t)
253{ 260{
254 unsigned long flags; 261 unsigned long flags;
255 262
256 spin_lock_irqsave(&t->sighand->siglock, flags); 263 spin_lock_irqsave(&t->sighand->siglock, flags);
257 clear_tsk_thread_flag(t, TIF_SIGPENDING); 264 __flush_signals(t);
258 flush_sigqueue(&t->pending);
259 flush_sigqueue(&t->signal->shared_pending);
260 spin_unlock_irqrestore(&t->sighand->siglock, flags); 265 spin_unlock_irqrestore(&t->sighand->siglock, flags);
261} 266}
262 267
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 6a463716ecbf..944ba03cae19 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -114,6 +114,7 @@ static int ngroups_max = NGROUPS_MAX;
114 114
115#ifdef CONFIG_MODULES 115#ifdef CONFIG_MODULES
116extern char modprobe_path[]; 116extern char modprobe_path[];
117extern int modules_disabled;
117#endif 118#endif
118#ifdef CONFIG_CHR_DEV_SG 119#ifdef CONFIG_CHR_DEV_SG
119extern int sg_big_buff; 120extern int sg_big_buff;
@@ -534,6 +535,17 @@ static struct ctl_table kern_table[] = {
534 .proc_handler = &proc_dostring, 535 .proc_handler = &proc_dostring,
535 .strategy = &sysctl_string, 536 .strategy = &sysctl_string,
536 }, 537 },
538 {
539 .ctl_name = CTL_UNNUMBERED,
540 .procname = "modules_disabled",
541 .data = &modules_disabled,
542 .maxlen = sizeof(int),
543 .mode = 0644,
544 /* only handle a transition from default "0" to "1" */
545 .proc_handler = &proc_dointvec_minmax,
546 .extra1 = &one,
547 .extra2 = &one,
548 },
537#endif 549#endif
538#if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET) 550#if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET)
539 { 551 {
@@ -1233,7 +1245,6 @@ static struct ctl_table vm_table[] = {
1233 .strategy = &sysctl_jiffies, 1245 .strategy = &sysctl_jiffies,
1234 }, 1246 },
1235#endif 1247#endif
1236#ifdef CONFIG_SECURITY
1237 { 1248 {
1238 .ctl_name = CTL_UNNUMBERED, 1249 .ctl_name = CTL_UNNUMBERED,
1239 .procname = "mmap_min_addr", 1250 .procname = "mmap_min_addr",
@@ -1242,7 +1253,6 @@ static struct ctl_table vm_table[] = {
1242 .mode = 0644, 1253 .mode = 0644,
1243 .proc_handler = &proc_doulongvec_minmax, 1254 .proc_handler = &proc_doulongvec_minmax,
1244 }, 1255 },
1245#endif
1246#ifdef CONFIG_NUMA 1256#ifdef CONFIG_NUMA
1247 { 1257 {
1248 .ctl_name = CTL_UNNUMBERED, 1258 .ctl_name = CTL_UNNUMBERED,
diff --git a/mm/Kconfig b/mm/Kconfig
index c2b57d81e153..71830ba7b986 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -226,6 +226,25 @@ config HAVE_MLOCKED_PAGE_BIT
226config MMU_NOTIFIER 226config MMU_NOTIFIER
227 bool 227 bool
228 228
229config DEFAULT_MMAP_MIN_ADDR
230 int "Low address space to protect from user allocation"
231 default 4096
232 help
233 This is the portion of low virtual memory which should be protected
234 from userspace allocation. Keeping a user from writing to low pages
235 can help reduce the impact of kernel NULL pointer bugs.
236
237 For most ia64, ppc64 and x86 users with lots of address space
238 a value of 65536 is reasonable and should cause no problems.
239 On arm and other archs it should not be higher than 32768.
240 Programs which use vm86 functionality would either need additional
241 permissions from either the LSM or the capabilities module or have
242 this protection disabled.
243
244 This value can be changed after boot using the
245 /proc/sys/vm/mmap_min_addr tunable.
246
247
229config NOMMU_INITIAL_TRIM_EXCESS 248config NOMMU_INITIAL_TRIM_EXCESS
230 int "Turn on mmap() excess space trimming before booting" 249 int "Turn on mmap() excess space trimming before booting"
231 depends on !MMU 250 depends on !MMU
diff --git a/mm/mmap.c b/mm/mmap.c
index 6b7b1a95944b..2b43fa1aa3c8 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -87,6 +87,9 @@ int sysctl_overcommit_ratio = 50; /* default is 50% */
87int sysctl_max_map_count __read_mostly = DEFAULT_MAX_MAP_COUNT; 87int sysctl_max_map_count __read_mostly = DEFAULT_MAX_MAP_COUNT;
88struct percpu_counter vm_committed_as; 88struct percpu_counter vm_committed_as;
89 89
90/* amount of vm to protect from userspace access */
91unsigned long mmap_min_addr = CONFIG_DEFAULT_MMAP_MIN_ADDR;
92
90/* 93/*
91 * Check that a process has enough memory to allocate a new virtual 94 * Check that a process has enough memory to allocate a new virtual
92 * mapping. 0 means there is enough memory for the allocation to 95 * mapping. 0 means there is enough memory for the allocation to
diff --git a/mm/nommu.c b/mm/nommu.c
index b571ef707428..2fd2ad5da98e 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -69,6 +69,9 @@ int sysctl_max_map_count = DEFAULT_MAX_MAP_COUNT;
69int sysctl_nr_trim_pages = CONFIG_NOMMU_INITIAL_TRIM_EXCESS; 69int sysctl_nr_trim_pages = CONFIG_NOMMU_INITIAL_TRIM_EXCESS;
70int heap_stack_gap = 0; 70int heap_stack_gap = 0;
71 71
72/* amount of vm to protect from userspace access */
73unsigned long mmap_min_addr = CONFIG_DEFAULT_MMAP_MIN_ADDR;
74
72atomic_long_t mmap_pages_allocated; 75atomic_long_t mmap_pages_allocated;
73 76
74EXPORT_SYMBOL(mem_map); 77EXPORT_SYMBOL(mem_map);
diff --git a/mm/shmem.c b/mm/shmem.c
index b25f95ce3db7..0132fbd45a23 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -2659,6 +2659,7 @@ struct file *shmem_file_setup(char *name, loff_t size, unsigned long flags)
2659 if (error) 2659 if (error)
2660 goto close_file; 2660 goto close_file;
2661#endif 2661#endif
2662 ima_counts_get(file);
2662 return file; 2663 return file;
2663 2664
2664close_file: 2665close_file:
@@ -2684,7 +2685,6 @@ int shmem_zero_setup(struct vm_area_struct *vma)
2684 if (IS_ERR(file)) 2685 if (IS_ERR(file))
2685 return PTR_ERR(file); 2686 return PTR_ERR(file);
2686 2687
2687 ima_shm_check(file);
2688 if (vma->vm_file) 2688 if (vma->vm_file)
2689 fput(vma->vm_file); 2689 fput(vma->vm_file);
2690 vma->vm_file = file; 2690 vma->vm_file = file;
diff --git a/security/Kconfig b/security/Kconfig
index bb244774e9d7..d23c839038f0 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -110,28 +110,8 @@ config SECURITY_ROOTPLUG
110 110
111 See <http://www.linuxjournal.com/article.php?sid=6279> for 111 See <http://www.linuxjournal.com/article.php?sid=6279> for
112 more information about this module. 112 more information about this module.
113
114 If you are unsure how to answer this question, answer N.
115
116config SECURITY_DEFAULT_MMAP_MIN_ADDR
117 int "Low address space to protect from user allocation"
118 depends on SECURITY
119 default 0
120 help
121 This is the portion of low virtual memory which should be protected
122 from userspace allocation. Keeping a user from writing to low pages
123 can help reduce the impact of kernel NULL pointer bugs.
124
125 For most ia64, ppc64 and x86 users with lots of address space
126 a value of 65536 is reasonable and should cause no problems.
127 On arm and other archs it should not be higher than 32768.
128 Programs which use vm86 functionality would either need additional
129 permissions from either the LSM or the capabilities module or have
130 this protection disabled.
131
132 This value can be changed after boot using the
133 /proc/sys/vm/mmap_min_addr tunable.
134 113
114 If you are unsure how to answer this question, answer N.
135 115
136source security/selinux/Kconfig 116source security/selinux/Kconfig
137source security/smack/Kconfig 117source security/smack/Kconfig
diff --git a/security/Makefile b/security/Makefile
index fa77021d9778..c67557cdaa85 100644
--- a/security/Makefile
+++ b/security/Makefile
@@ -16,6 +16,9 @@ obj-$(CONFIG_SECURITYFS) += inode.o
16# Must precede capability.o in order to stack properly. 16# Must precede capability.o in order to stack properly.
17obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o 17obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o
18obj-$(CONFIG_SECURITY_SMACK) += smack/built-in.o 18obj-$(CONFIG_SECURITY_SMACK) += smack/built-in.o
19ifeq ($(CONFIG_AUDIT),y)
20obj-$(CONFIG_SECURITY_SMACK) += lsm_audit.o
21endif
19obj-$(CONFIG_SECURITY_TOMOYO) += tomoyo/built-in.o 22obj-$(CONFIG_SECURITY_TOMOYO) += tomoyo/built-in.o
20obj-$(CONFIG_SECURITY_ROOTPLUG) += root_plug.o 23obj-$(CONFIG_SECURITY_ROOTPLUG) += root_plug.o
21obj-$(CONFIG_CGROUP_DEVICE) += device_cgroup.o 24obj-$(CONFIG_CGROUP_DEVICE) += device_cgroup.o
diff --git a/security/commoncap.c b/security/commoncap.c
index beac0258c2a8..48b7e0228fa3 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -28,6 +28,28 @@
28#include <linux/prctl.h> 28#include <linux/prctl.h>
29#include <linux/securebits.h> 29#include <linux/securebits.h>
30 30
31/*
32 * If a non-root user executes a setuid-root binary in
33 * !secure(SECURE_NOROOT) mode, then we raise capabilities.
34 * However if fE is also set, then the intent is for only
35 * the file capabilities to be applied, and the setuid-root
36 * bit is left on either to change the uid (plausible) or
37 * to get full privilege on a kernel without file capabilities
38 * support. So in that case we do not raise capabilities.
39 *
40 * Warn if that happens, once per boot.
41 */
42static void warn_setuid_and_fcaps_mixed(char *fname)
43{
44 static int warned;
45 if (!warned) {
46 printk(KERN_INFO "warning: `%s' has both setuid-root and"
47 " effective capabilities. Therefore not raising all"
48 " capabilities.\n", fname);
49 warned = 1;
50 }
51}
52
31int cap_netlink_send(struct sock *sk, struct sk_buff *skb) 53int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
32{ 54{
33 NETLINK_CB(skb).eff_cap = current_cap(); 55 NETLINK_CB(skb).eff_cap = current_cap();
@@ -464,6 +486,15 @@ int cap_bprm_set_creds(struct linux_binprm *bprm)
464 486
465 if (!issecure(SECURE_NOROOT)) { 487 if (!issecure(SECURE_NOROOT)) {
466 /* 488 /*
489 * If the legacy file capability is set, then don't set privs
490 * for a setuid root binary run by a non-root user. Do set it
491 * for a root user just to cause least surprise to an admin.
492 */
493 if (effective && new->uid != 0 && new->euid == 0) {
494 warn_setuid_and_fcaps_mixed(bprm->filename);
495 goto skip;
496 }
497 /*
467 * To support inheritance of root-permissions and suid-root 498 * To support inheritance of root-permissions and suid-root
468 * executables under compatibility mode, we override the 499 * executables under compatibility mode, we override the
469 * capability sets for the file. 500 * capability sets for the file.
@@ -478,6 +509,7 @@ int cap_bprm_set_creds(struct linux_binprm *bprm)
478 if (new->euid == 0) 509 if (new->euid == 0)
479 effective = true; 510 effective = true;
480 } 511 }
512skip:
481 513
482 /* Don't let someone trace a set[ug]id/setpcap binary with the revised 514 /* Don't let someone trace a set[ug]id/setpcap binary with the revised
483 * credentials unless they have the appropriate permit 515 * credentials unless they have the appropriate permit
diff --git a/security/inode.c b/security/inode.c
index f3b91bfbe4cb..f7496c6a022b 100644
--- a/security/inode.c
+++ b/security/inode.c
@@ -287,7 +287,7 @@ void securityfs_remove(struct dentry *dentry)
287{ 287{
288 struct dentry *parent; 288 struct dentry *parent;
289 289
290 if (!dentry) 290 if (!dentry || IS_ERR(dentry))
291 return; 291 return;
292 292
293 parent = dentry->d_parent; 293 parent = dentry->d_parent;
diff --git a/security/integrity/ima/ima_audit.c b/security/integrity/ima/ima_audit.c
index 1e082bb987be..ff513ff737f5 100644
--- a/security/integrity/ima/ima_audit.c
+++ b/security/integrity/ima/ima_audit.c
@@ -22,18 +22,9 @@ static int ima_audit;
22static int __init ima_audit_setup(char *str) 22static int __init ima_audit_setup(char *str)
23{ 23{
24 unsigned long audit; 24 unsigned long audit;
25 int rc, result = 0;
26 char *op = "ima_audit";
27 char *cause;
28 25
29 rc = strict_strtoul(str, 0, &audit); 26 if (!strict_strtoul(str, 0, &audit))
30 if (rc || audit > 1) 27 ima_audit = audit ? 1 : 0;
31 result = 1;
32 else
33 ima_audit = audit;
34 cause = ima_audit ? "enabled" : "not_enabled";
35 integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, NULL,
36 op, cause, result, 0);
37 return 1; 28 return 1;
38} 29}
39__setup("ima_audit=", ima_audit_setup); 30__setup("ima_audit=", ima_audit_setup);
@@ -50,23 +41,14 @@ void integrity_audit_msg(int audit_msgno, struct inode *inode,
50 41
51 ab = audit_log_start(current->audit_context, GFP_KERNEL, audit_msgno); 42 ab = audit_log_start(current->audit_context, GFP_KERNEL, audit_msgno);
52 audit_log_format(ab, "integrity: pid=%d uid=%u auid=%u ses=%u", 43 audit_log_format(ab, "integrity: pid=%d uid=%u auid=%u ses=%u",
53 current->pid, current->cred->uid, 44 current->pid, current_cred()->uid,
54 audit_get_loginuid(current), 45 audit_get_loginuid(current),
55 audit_get_sessionid(current)); 46 audit_get_sessionid(current));
56 audit_log_task_context(ab); 47 audit_log_task_context(ab);
57 switch (audit_msgno) { 48 audit_log_format(ab, " op=");
58 case AUDIT_INTEGRITY_DATA: 49 audit_log_string(ab, op);
59 case AUDIT_INTEGRITY_METADATA: 50 audit_log_format(ab, " cause=");
60 case AUDIT_INTEGRITY_PCR: 51 audit_log_string(ab, cause);
61 case AUDIT_INTEGRITY_STATUS:
62 audit_log_format(ab, " op=%s cause=%s", op, cause);
63 break;
64 case AUDIT_INTEGRITY_HASH:
65 audit_log_format(ab, " op=%s hash=%s", op, cause);
66 break;
67 default:
68 audit_log_format(ab, " op=%s", op);
69 }
70 audit_log_format(ab, " comm="); 52 audit_log_format(ab, " comm=");
71 audit_log_untrustedstring(ab, current->comm); 53 audit_log_untrustedstring(ab, current->comm);
72 if (fname) { 54 if (fname) {
diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c
index 50d572b74caf..63003a63aaee 100644
--- a/security/integrity/ima/ima_crypto.c
+++ b/security/integrity/ima/ima_crypto.c
@@ -103,7 +103,7 @@ int ima_calc_template_hash(int template_len, void *template, char *digest)
103 return rc; 103 return rc;
104} 104}
105 105
106static void ima_pcrread(int idx, u8 *pcr) 106static void __init ima_pcrread(int idx, u8 *pcr)
107{ 107{
108 if (!ima_used_chip) 108 if (!ima_used_chip)
109 return; 109 return;
@@ -115,7 +115,7 @@ static void ima_pcrread(int idx, u8 *pcr)
115/* 115/*
116 * Calculate the boot aggregate hash 116 * Calculate the boot aggregate hash
117 */ 117 */
118int ima_calc_boot_aggregate(char *digest) 118int __init ima_calc_boot_aggregate(char *digest)
119{ 119{
120 struct hash_desc desc; 120 struct hash_desc desc;
121 struct scatterlist sg; 121 struct scatterlist sg;
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index ffbe259700b1..7039b14e1f73 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -15,6 +15,7 @@
15 * implemenents security file system for reporting 15 * implemenents security file system for reporting
16 * current measurement list and IMA statistics 16 * current measurement list and IMA statistics
17 */ 17 */
18#include <linux/fcntl.h>
18#include <linux/module.h> 19#include <linux/module.h>
19#include <linux/seq_file.h> 20#include <linux/seq_file.h>
20#include <linux/rculist.h> 21#include <linux/rculist.h>
@@ -283,6 +284,9 @@ static atomic_t policy_opencount = ATOMIC_INIT(1);
283 */ 284 */
284int ima_open_policy(struct inode * inode, struct file * filp) 285int ima_open_policy(struct inode * inode, struct file * filp)
285{ 286{
287 /* No point in being allowed to open it if you aren't going to write */
288 if (!(filp->f_flags & O_WRONLY))
289 return -EACCES;
286 if (atomic_dec_and_test(&policy_opencount)) 290 if (atomic_dec_and_test(&policy_opencount))
287 return 0; 291 return 0;
288 return -EBUSY; 292 return -EBUSY;
@@ -315,7 +319,7 @@ static struct file_operations ima_measure_policy_ops = {
315 .release = ima_release_policy 319 .release = ima_release_policy
316}; 320};
317 321
318int ima_fs_init(void) 322int __init ima_fs_init(void)
319{ 323{
320 ima_dir = securityfs_create_dir("ima", NULL); 324 ima_dir = securityfs_create_dir("ima", NULL);
321 if (IS_ERR(ima_dir)) 325 if (IS_ERR(ima_dir))
@@ -349,7 +353,7 @@ int ima_fs_init(void)
349 goto out; 353 goto out;
350 354
351 ima_policy = securityfs_create_file("policy", 355 ima_policy = securityfs_create_file("policy",
352 S_IRUSR | S_IRGRP | S_IWUSR, 356 S_IWUSR,
353 ima_dir, NULL, 357 ima_dir, NULL,
354 &ima_measure_policy_ops); 358 &ima_measure_policy_ops);
355 if (IS_ERR(ima_policy)) 359 if (IS_ERR(ima_policy))
diff --git a/security/integrity/ima/ima_iint.c b/security/integrity/ima/ima_iint.c
index ec79f1ee992c..b8dd693f8790 100644
--- a/security/integrity/ima/ima_iint.c
+++ b/security/integrity/ima/ima_iint.c
@@ -196,7 +196,7 @@ static void init_once(void *foo)
196 kref_set(&iint->refcount, 1); 196 kref_set(&iint->refcount, 1);
197} 197}
198 198
199void ima_iintcache_init(void) 199void __init ima_iintcache_init(void)
200{ 200{
201 iint_cache = 201 iint_cache =
202 kmem_cache_create("iint_cache", sizeof(struct ima_iint_cache), 0, 202 kmem_cache_create("iint_cache", sizeof(struct ima_iint_cache), 0,
diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c
index 0b0bb8c978cc..a40da7ae5900 100644
--- a/security/integrity/ima/ima_init.c
+++ b/security/integrity/ima/ima_init.c
@@ -38,7 +38,7 @@ int ima_used_chip;
38 * a different value.) Violations add a zero entry to the measurement 38 * a different value.) Violations add a zero entry to the measurement
39 * list and extend the aggregate PCR value with ff...ff's. 39 * list and extend the aggregate PCR value with ff...ff's.
40 */ 40 */
41static void ima_add_boot_aggregate(void) 41static void __init ima_add_boot_aggregate(void)
42{ 42{
43 struct ima_template_entry *entry; 43 struct ima_template_entry *entry;
44 const char *op = "add_boot_aggregate"; 44 const char *op = "add_boot_aggregate";
@@ -71,7 +71,7 @@ err_out:
71 audit_cause, result, 0); 71 audit_cause, result, 0);
72} 72}
73 73
74int ima_init(void) 74int __init ima_init(void)
75{ 75{
76 u8 pcr_i[IMA_DIGEST_SIZE]; 76 u8 pcr_i[IMA_DIGEST_SIZE];
77 int rc; 77 int rc;
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index f4e7266f5aee..6f611874d10e 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -29,20 +29,8 @@ int ima_initialized;
29char *ima_hash = "sha1"; 29char *ima_hash = "sha1";
30static int __init hash_setup(char *str) 30static int __init hash_setup(char *str)
31{ 31{
32 const char *op = "hash_setup"; 32 if (strncmp(str, "md5", 3) == 0)
33 const char *hash = "sha1"; 33 ima_hash = "md5";
34 int result = 0;
35 int audit_info = 0;
36
37 if (strncmp(str, "md5", 3) == 0) {
38 hash = "md5";
39 ima_hash = str;
40 } else if (strncmp(str, "sha1", 4) != 0) {
41 hash = "invalid_hash_type";
42 result = 1;
43 }
44 integrity_audit_msg(AUDIT_INTEGRITY_HASH, NULL, NULL, op, hash,
45 result, audit_info);
46 return 1; 34 return 1;
47} 35}
48__setup("ima_hash=", hash_setup); 36__setup("ima_hash=", hash_setup);
@@ -128,10 +116,6 @@ static int get_path_measurement(struct ima_iint_cache *iint, struct file *file,
128{ 116{
129 int rc = 0; 117 int rc = 0;
130 118
131 if (IS_ERR(file)) {
132 pr_info("%s dentry_open failed\n", filename);
133 return rc;
134 }
135 iint->opencount++; 119 iint->opencount++;
136 iint->readcount++; 120 iint->readcount++;
137 121
@@ -141,6 +125,15 @@ static int get_path_measurement(struct ima_iint_cache *iint, struct file *file,
141 return rc; 125 return rc;
142} 126}
143 127
128static void ima_update_counts(struct ima_iint_cache *iint, int mask)
129{
130 iint->opencount++;
131 if ((mask & MAY_WRITE) || (mask == 0))
132 iint->writecount++;
133 else if (mask & (MAY_READ | MAY_EXEC))
134 iint->readcount++;
135}
136
144/** 137/**
145 * ima_path_check - based on policy, collect/store measurement. 138 * ima_path_check - based on policy, collect/store measurement.
146 * @path: contains a pointer to the path to be measured 139 * @path: contains a pointer to the path to be measured
@@ -156,10 +149,10 @@ static int get_path_measurement(struct ima_iint_cache *iint, struct file *file,
156 * - Opening a file for read when already open for write, 149 * - Opening a file for read when already open for write,
157 * could result in a file measurement error. 150 * could result in a file measurement error.
158 * 151 *
159 * Return 0 on success, an error code on failure. 152 * Always return 0 and audit dentry_open failures.
160 * (Based on the results of appraise_measurement().) 153 * (Return code will be based upon measurement appraisal.)
161 */ 154 */
162int ima_path_check(struct path *path, int mask) 155int ima_path_check(struct path *path, int mask, int update_counts)
163{ 156{
164 struct inode *inode = path->dentry->d_inode; 157 struct inode *inode = path->dentry->d_inode;
165 struct ima_iint_cache *iint; 158 struct ima_iint_cache *iint;
@@ -173,11 +166,8 @@ int ima_path_check(struct path *path, int mask)
173 return 0; 166 return 0;
174 167
175 mutex_lock(&iint->mutex); 168 mutex_lock(&iint->mutex);
176 iint->opencount++; 169 if (update_counts)
177 if ((mask & MAY_WRITE) || (mask == 0)) 170 ima_update_counts(iint, mask);
178 iint->writecount++;
179 else if (mask & (MAY_READ | MAY_EXEC))
180 iint->readcount++;
181 171
182 rc = ima_must_measure(iint, inode, MAY_READ, PATH_CHECK); 172 rc = ima_must_measure(iint, inode, MAY_READ, PATH_CHECK);
183 if (rc < 0) 173 if (rc < 0)
@@ -196,7 +186,19 @@ int ima_path_check(struct path *path, int mask)
196 struct dentry *dentry = dget(path->dentry); 186 struct dentry *dentry = dget(path->dentry);
197 struct vfsmount *mnt = mntget(path->mnt); 187 struct vfsmount *mnt = mntget(path->mnt);
198 188
199 file = dentry_open(dentry, mnt, O_RDONLY, current->cred); 189 file = dentry_open(dentry, mnt, O_RDONLY | O_LARGEFILE,
190 current_cred());
191 if (IS_ERR(file)) {
192 int audit_info = 0;
193
194 integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode,
195 dentry->d_name.name,
196 "add_measurement",
197 "dentry_open failed",
198 1, audit_info);
199 file = NULL;
200 goto out;
201 }
200 rc = get_path_measurement(iint, file, dentry->d_name.name); 202 rc = get_path_measurement(iint, file, dentry->d_name.name);
201 } 203 }
202out: 204out:
@@ -206,6 +208,7 @@ out:
206 kref_put(&iint->refcount, iint_free); 208 kref_put(&iint->refcount, iint_free);
207 return 0; 209 return 0;
208} 210}
211EXPORT_SYMBOL_GPL(ima_path_check);
209 212
210static int process_measurement(struct file *file, const unsigned char *filename, 213static int process_measurement(struct file *file, const unsigned char *filename,
211 int mask, int function) 214 int mask, int function)
@@ -234,7 +237,16 @@ out:
234 return rc; 237 return rc;
235} 238}
236 239
237static void opencount_get(struct file *file) 240/*
241 * ima_opens_get - increment file counts
242 *
243 * - for IPC shm and shmat file.
244 * - for nfsd exported files.
245 *
246 * Increment the counts for these files to prevent unnecessary
247 * imbalance messages.
248 */
249void ima_counts_get(struct file *file)
238{ 250{
239 struct inode *inode = file->f_dentry->d_inode; 251 struct inode *inode = file->f_dentry->d_inode;
240 struct ima_iint_cache *iint; 252 struct ima_iint_cache *iint;
@@ -246,8 +258,14 @@ static void opencount_get(struct file *file)
246 return; 258 return;
247 mutex_lock(&iint->mutex); 259 mutex_lock(&iint->mutex);
248 iint->opencount++; 260 iint->opencount++;
261 if ((file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
262 iint->readcount++;
263
264 if (file->f_mode & FMODE_WRITE)
265 iint->writecount++;
249 mutex_unlock(&iint->mutex); 266 mutex_unlock(&iint->mutex);
250} 267}
268EXPORT_SYMBOL_GPL(ima_counts_get);
251 269
252/** 270/**
253 * ima_file_mmap - based on policy, collect/store measurement. 271 * ima_file_mmap - based on policy, collect/store measurement.
@@ -272,18 +290,6 @@ int ima_file_mmap(struct file *file, unsigned long prot)
272 return 0; 290 return 0;
273} 291}
274 292
275/*
276 * ima_shm_check - IPC shm and shmat create/fput a file
277 *
278 * Maintain the opencount for these files to prevent unnecessary
279 * imbalance messages.
280 */
281void ima_shm_check(struct file *file)
282{
283 opencount_get(file);
284 return;
285}
286
287/** 293/**
288 * ima_bprm_check - based on policy, collect/store measurement. 294 * ima_bprm_check - based on policy, collect/store measurement.
289 * @bprm: contains the linux_binprm structure 295 * @bprm: contains the linux_binprm structure
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index b5291ad5ef56..e1278399b345 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -45,24 +45,30 @@ struct ima_measure_rule_entry {
45 } lsm[MAX_LSM_RULES]; 45 } lsm[MAX_LSM_RULES];
46}; 46};
47 47
48/* Without LSM specific knowledge, the default policy can only be 48/*
49 * Without LSM specific knowledge, the default policy can only be
49 * written in terms of .action, .func, .mask, .fsmagic, and .uid 50 * written in terms of .action, .func, .mask, .fsmagic, and .uid
50 */ 51 */
52
53/*
54 * The minimum rule set to allow for full TCB coverage. Measures all files
55 * opened or mmap for exec and everything read by root. Dangerous because
56 * normal users can easily run the machine out of memory simply building
57 * and running executables.
58 */
51static struct ima_measure_rule_entry default_rules[] = { 59static struct ima_measure_rule_entry default_rules[] = {
52 {.action = DONT_MEASURE,.fsmagic = PROC_SUPER_MAGIC, 60 {.action = DONT_MEASURE,.fsmagic = PROC_SUPER_MAGIC,.flags = IMA_FSMAGIC},
53 .flags = IMA_FSMAGIC},
54 {.action = DONT_MEASURE,.fsmagic = SYSFS_MAGIC,.flags = IMA_FSMAGIC}, 61 {.action = DONT_MEASURE,.fsmagic = SYSFS_MAGIC,.flags = IMA_FSMAGIC},
55 {.action = DONT_MEASURE,.fsmagic = DEBUGFS_MAGIC,.flags = IMA_FSMAGIC}, 62 {.action = DONT_MEASURE,.fsmagic = DEBUGFS_MAGIC,.flags = IMA_FSMAGIC},
56 {.action = DONT_MEASURE,.fsmagic = TMPFS_MAGIC,.flags = IMA_FSMAGIC}, 63 {.action = DONT_MEASURE,.fsmagic = TMPFS_MAGIC,.flags = IMA_FSMAGIC},
57 {.action = DONT_MEASURE,.fsmagic = SECURITYFS_MAGIC, 64 {.action = DONT_MEASURE,.fsmagic = SECURITYFS_MAGIC,.flags = IMA_FSMAGIC},
58 .flags = IMA_FSMAGIC}, 65 {.action = DONT_MEASURE,.fsmagic = SELINUX_MAGIC,.flags = IMA_FSMAGIC},
59 {.action = DONT_MEASURE,.fsmagic = 0xF97CFF8C,.flags = IMA_FSMAGIC},
60 {.action = MEASURE,.func = FILE_MMAP,.mask = MAY_EXEC, 66 {.action = MEASURE,.func = FILE_MMAP,.mask = MAY_EXEC,
61 .flags = IMA_FUNC | IMA_MASK}, 67 .flags = IMA_FUNC | IMA_MASK},
62 {.action = MEASURE,.func = BPRM_CHECK,.mask = MAY_EXEC, 68 {.action = MEASURE,.func = BPRM_CHECK,.mask = MAY_EXEC,
63 .flags = IMA_FUNC | IMA_MASK}, 69 .flags = IMA_FUNC | IMA_MASK},
64 {.action = MEASURE,.func = PATH_CHECK,.mask = MAY_READ,.uid = 0, 70 {.action = MEASURE,.func = PATH_CHECK,.mask = MAY_READ,.uid = 0,
65 .flags = IMA_FUNC | IMA_MASK | IMA_UID} 71 .flags = IMA_FUNC | IMA_MASK | IMA_UID},
66}; 72};
67 73
68static LIST_HEAD(measure_default_rules); 74static LIST_HEAD(measure_default_rules);
@@ -71,6 +77,14 @@ static struct list_head *ima_measure;
71 77
72static DEFINE_MUTEX(ima_measure_mutex); 78static DEFINE_MUTEX(ima_measure_mutex);
73 79
80static bool ima_use_tcb __initdata;
81static int __init default_policy_setup(char *str)
82{
83 ima_use_tcb = 1;
84 return 1;
85}
86__setup("ima_tcb", default_policy_setup);
87
74/** 88/**
75 * ima_match_rules - determine whether an inode matches the measure rule. 89 * ima_match_rules - determine whether an inode matches the measure rule.
76 * @rule: a pointer to a rule 90 * @rule: a pointer to a rule
@@ -96,7 +110,7 @@ static bool ima_match_rules(struct ima_measure_rule_entry *rule,
96 if ((rule->flags & IMA_UID) && rule->uid != tsk->cred->uid) 110 if ((rule->flags & IMA_UID) && rule->uid != tsk->cred->uid)
97 return false; 111 return false;
98 for (i = 0; i < MAX_LSM_RULES; i++) { 112 for (i = 0; i < MAX_LSM_RULES; i++) {
99 int rc; 113 int rc = 0;
100 u32 osid, sid; 114 u32 osid, sid;
101 115
102 if (!rule->lsm[i].rule) 116 if (!rule->lsm[i].rule)
@@ -109,7 +123,7 @@ static bool ima_match_rules(struct ima_measure_rule_entry *rule,
109 security_inode_getsecid(inode, &osid); 123 security_inode_getsecid(inode, &osid);
110 rc = security_filter_rule_match(osid, 124 rc = security_filter_rule_match(osid,
111 rule->lsm[i].type, 125 rule->lsm[i].type,
112 AUDIT_EQUAL, 126 Audit_equal,
113 rule->lsm[i].rule, 127 rule->lsm[i].rule,
114 NULL); 128 NULL);
115 break; 129 break;
@@ -119,7 +133,7 @@ static bool ima_match_rules(struct ima_measure_rule_entry *rule,
119 security_task_getsecid(tsk, &sid); 133 security_task_getsecid(tsk, &sid);
120 rc = security_filter_rule_match(sid, 134 rc = security_filter_rule_match(sid,
121 rule->lsm[i].type, 135 rule->lsm[i].type,
122 AUDIT_EQUAL, 136 Audit_equal,
123 rule->lsm[i].rule, 137 rule->lsm[i].rule,
124 NULL); 138 NULL);
125 default: 139 default:
@@ -164,11 +178,17 @@ int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask)
164 * ima_measure points to either the measure_default_rules or the 178 * ima_measure points to either the measure_default_rules or the
165 * the new measure_policy_rules. 179 * the new measure_policy_rules.
166 */ 180 */
167void ima_init_policy(void) 181void __init ima_init_policy(void)
168{ 182{
169 int i; 183 int i, entries;
184
185 /* if !ima_use_tcb set entries = 0 so we load NO default rules */
186 if (ima_use_tcb)
187 entries = ARRAY_SIZE(default_rules);
188 else
189 entries = 0;
170 190
171 for (i = 0; i < ARRAY_SIZE(default_rules); i++) 191 for (i = 0; i < entries; i++)
172 list_add_tail(&default_rules[i].list, &measure_default_rules); 192 list_add_tail(&default_rules[i].list, &measure_default_rules);
173 ima_measure = &measure_default_rules; 193 ima_measure = &measure_default_rules;
174} 194}
@@ -227,7 +247,7 @@ static int ima_lsm_rule_init(struct ima_measure_rule_entry *entry,
227 247
228 entry->lsm[lsm_rule].type = audit_type; 248 entry->lsm[lsm_rule].type = audit_type;
229 result = security_filter_rule_init(entry->lsm[lsm_rule].type, 249 result = security_filter_rule_init(entry->lsm[lsm_rule].type,
230 AUDIT_EQUAL, args, 250 Audit_equal, args,
231 &entry->lsm[lsm_rule].rule); 251 &entry->lsm[lsm_rule].rule);
232 return result; 252 return result;
233} 253}
diff --git a/security/lsm_audit.c b/security/lsm_audit.c
new file mode 100644
index 000000000000..94b868494b31
--- /dev/null
+++ b/security/lsm_audit.c
@@ -0,0 +1,386 @@
1/*
2 * common LSM auditing functions
3 *
4 * Based on code written for SELinux by :
5 * Stephen Smalley, <sds@epoch.ncsc.mil>
6 * James Morris <jmorris@redhat.com>
7 * Author : Etienne Basset, <etienne.basset@ensta.org>
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,
11 * as published by the Free Software Foundation.
12 */
13
14#include <linux/types.h>
15#include <linux/stddef.h>
16#include <linux/kernel.h>
17#include <linux/fs.h>
18#include <linux/init.h>
19#include <net/sock.h>
20#include <linux/un.h>
21#include <net/af_unix.h>
22#include <linux/audit.h>
23#include <linux/ipv6.h>
24#include <linux/ip.h>
25#include <net/ip.h>
26#include <net/ipv6.h>
27#include <linux/tcp.h>
28#include <linux/udp.h>
29#include <linux/dccp.h>
30#include <linux/sctp.h>
31#include <linux/lsm_audit.h>
32
33/**
34 * ipv4_skb_to_auditdata : fill auditdata from skb
35 * @skb : the skb
36 * @ad : the audit data to fill
37 * @proto : the layer 4 protocol
38 *
39 * return 0 on success
40 */
41int ipv4_skb_to_auditdata(struct sk_buff *skb,
42 struct common_audit_data *ad, u8 *proto)
43{
44 int ret = 0;
45 struct iphdr *ih;
46
47 ih = ip_hdr(skb);
48 if (ih == NULL)
49 return -EINVAL;
50
51 ad->u.net.v4info.saddr = ih->saddr;
52 ad->u.net.v4info.daddr = ih->daddr;
53
54 if (proto)
55 *proto = ih->protocol;
56 /* non initial fragment */
57 if (ntohs(ih->frag_off) & IP_OFFSET)
58 return 0;
59
60 switch (ih->protocol) {
61 case IPPROTO_TCP: {
62 struct tcphdr *th = tcp_hdr(skb);
63 if (th == NULL)
64 break;
65
66 ad->u.net.sport = th->source;
67 ad->u.net.dport = th->dest;
68 break;
69 }
70 case IPPROTO_UDP: {
71 struct udphdr *uh = udp_hdr(skb);
72 if (uh == NULL)
73 break;
74
75 ad->u.net.sport = uh->source;
76 ad->u.net.dport = uh->dest;
77 break;
78 }
79 case IPPROTO_DCCP: {
80 struct dccp_hdr *dh = dccp_hdr(skb);
81 if (dh == NULL)
82 break;
83
84 ad->u.net.sport = dh->dccph_sport;
85 ad->u.net.dport = dh->dccph_dport;
86 break;
87 }
88 case IPPROTO_SCTP: {
89 struct sctphdr *sh = sctp_hdr(skb);
90 if (sh == NULL)
91 break;
92 ad->u.net.sport = sh->source;
93 ad->u.net.dport = sh->dest;
94 break;
95 }
96 default:
97 ret = -EINVAL;
98 }
99 return ret;
100}
101#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
102/**
103 * ipv6_skb_to_auditdata : fill auditdata from skb
104 * @skb : the skb
105 * @ad : the audit data to fill
106 * @proto : the layer 4 protocol
107 *
108 * return 0 on success
109 */
110int ipv6_skb_to_auditdata(struct sk_buff *skb,
111 struct common_audit_data *ad, u8 *proto)
112{
113 int offset, ret = 0;
114 struct ipv6hdr *ip6;
115 u8 nexthdr;
116
117 ip6 = ipv6_hdr(skb);
118 if (ip6 == NULL)
119 return -EINVAL;
120 ipv6_addr_copy(&ad->u.net.v6info.saddr, &ip6->saddr);
121 ipv6_addr_copy(&ad->u.net.v6info.daddr, &ip6->daddr);
122 ret = 0;
123 /* IPv6 can have several extension header before the Transport header
124 * skip them */
125 offset = skb_network_offset(skb);
126 offset += sizeof(*ip6);
127 nexthdr = ip6->nexthdr;
128 offset = ipv6_skip_exthdr(skb, offset, &nexthdr);
129 if (offset < 0)
130 return 0;
131 if (proto)
132 *proto = nexthdr;
133 switch (nexthdr) {
134 case IPPROTO_TCP: {
135 struct tcphdr _tcph, *th;
136
137 th = skb_header_pointer(skb, offset, sizeof(_tcph), &_tcph);
138 if (th == NULL)
139 break;
140
141 ad->u.net.sport = th->source;
142 ad->u.net.dport = th->dest;
143 break;
144 }
145 case IPPROTO_UDP: {
146 struct udphdr _udph, *uh;
147
148 uh = skb_header_pointer(skb, offset, sizeof(_udph), &_udph);
149 if (uh == NULL)
150 break;
151
152 ad->u.net.sport = uh->source;
153 ad->u.net.dport = uh->dest;
154 break;
155 }
156 case IPPROTO_DCCP: {
157 struct dccp_hdr _dccph, *dh;
158
159 dh = skb_header_pointer(skb, offset, sizeof(_dccph), &_dccph);
160 if (dh == NULL)
161 break;
162
163 ad->u.net.sport = dh->dccph_sport;
164 ad->u.net.dport = dh->dccph_dport;
165 break;
166 }
167 case IPPROTO_SCTP: {
168 struct sctphdr _sctph, *sh;
169
170 sh = skb_header_pointer(skb, offset, sizeof(_sctph), &_sctph);
171 if (sh == NULL)
172 break;
173 ad->u.net.sport = sh->source;
174 ad->u.net.dport = sh->dest;
175 break;
176 }
177 default:
178 ret = -EINVAL;
179 }
180 return ret;
181}
182#endif
183
184
185static inline void print_ipv6_addr(struct audit_buffer *ab,
186 struct in6_addr *addr, __be16 port,
187 char *name1, char *name2)
188{
189 if (!ipv6_addr_any(addr))
190 audit_log_format(ab, " %s=%pI6", name1, addr);
191 if (port)
192 audit_log_format(ab, " %s=%d", name2, ntohs(port));
193}
194
195static inline void print_ipv4_addr(struct audit_buffer *ab, __be32 addr,
196 __be16 port, char *name1, char *name2)
197{
198 if (addr)
199 audit_log_format(ab, " %s=%pI4", name1, &addr);
200 if (port)
201 audit_log_format(ab, " %s=%d", name2, ntohs(port));
202}
203
204/**
205 * dump_common_audit_data - helper to dump common audit data
206 * @a : common audit data
207 *
208 */
209static void dump_common_audit_data(struct audit_buffer *ab,
210 struct common_audit_data *a)
211{
212 struct inode *inode = NULL;
213 struct task_struct *tsk = current;
214
215 if (a->tsk)
216 tsk = a->tsk;
217 if (tsk && tsk->pid) {
218 audit_log_format(ab, " pid=%d comm=", tsk->pid);
219 audit_log_untrustedstring(ab, tsk->comm);
220 }
221
222 switch (a->type) {
223 case LSM_AUDIT_DATA_IPC:
224 audit_log_format(ab, " key=%d ", a->u.ipc_id);
225 break;
226 case LSM_AUDIT_DATA_CAP:
227 audit_log_format(ab, " capability=%d ", a->u.cap);
228 break;
229 case LSM_AUDIT_DATA_FS:
230 if (a->u.fs.path.dentry) {
231 struct dentry *dentry = a->u.fs.path.dentry;
232 if (a->u.fs.path.mnt) {
233 audit_log_d_path(ab, "path=", &a->u.fs.path);
234 } else {
235 audit_log_format(ab, " name=");
236 audit_log_untrustedstring(ab,
237 dentry->d_name.name);
238 }
239 inode = dentry->d_inode;
240 } else if (a->u.fs.inode) {
241 struct dentry *dentry;
242 inode = a->u.fs.inode;
243 dentry = d_find_alias(inode);
244 if (dentry) {
245 audit_log_format(ab, " name=");
246 audit_log_untrustedstring(ab,
247 dentry->d_name.name);
248 dput(dentry);
249 }
250 }
251 if (inode)
252 audit_log_format(ab, " dev=%s ino=%lu",
253 inode->i_sb->s_id,
254 inode->i_ino);
255 break;
256 case LSM_AUDIT_DATA_TASK:
257 tsk = a->u.tsk;
258 if (tsk && tsk->pid) {
259 audit_log_format(ab, " pid=%d comm=", tsk->pid);
260 audit_log_untrustedstring(ab, tsk->comm);
261 }
262 break;
263 case LSM_AUDIT_DATA_NET:
264 if (a->u.net.sk) {
265 struct sock *sk = a->u.net.sk;
266 struct unix_sock *u;
267 int len = 0;
268 char *p = NULL;
269
270 switch (sk->sk_family) {
271 case AF_INET: {
272 struct inet_sock *inet = inet_sk(sk);
273
274 print_ipv4_addr(ab, inet->rcv_saddr,
275 inet->sport,
276 "laddr", "lport");
277 print_ipv4_addr(ab, inet->daddr,
278 inet->dport,
279 "faddr", "fport");
280 break;
281 }
282 case AF_INET6: {
283 struct inet_sock *inet = inet_sk(sk);
284 struct ipv6_pinfo *inet6 = inet6_sk(sk);
285
286 print_ipv6_addr(ab, &inet6->rcv_saddr,
287 inet->sport,
288 "laddr", "lport");
289 print_ipv6_addr(ab, &inet6->daddr,
290 inet->dport,
291 "faddr", "fport");
292 break;
293 }
294 case AF_UNIX:
295 u = unix_sk(sk);
296 if (u->dentry) {
297 struct path path = {
298 .dentry = u->dentry,
299 .mnt = u->mnt
300 };
301 audit_log_d_path(ab, "path=", &path);
302 break;
303 }
304 if (!u->addr)
305 break;
306 len = u->addr->len-sizeof(short);
307 p = &u->addr->name->sun_path[0];
308 audit_log_format(ab, " path=");
309 if (*p)
310 audit_log_untrustedstring(ab, p);
311 else
312 audit_log_n_hex(ab, p, len);
313 break;
314 }
315 }
316
317 switch (a->u.net.family) {
318 case AF_INET:
319 print_ipv4_addr(ab, a->u.net.v4info.saddr,
320 a->u.net.sport,
321 "saddr", "src");
322 print_ipv4_addr(ab, a->u.net.v4info.daddr,
323 a->u.net.dport,
324 "daddr", "dest");
325 break;
326 case AF_INET6:
327 print_ipv6_addr(ab, &a->u.net.v6info.saddr,
328 a->u.net.sport,
329 "saddr", "src");
330 print_ipv6_addr(ab, &a->u.net.v6info.daddr,
331 a->u.net.dport,
332 "daddr", "dest");
333 break;
334 }
335 if (a->u.net.netif > 0) {
336 struct net_device *dev;
337
338 /* NOTE: we always use init's namespace */
339 dev = dev_get_by_index(&init_net, a->u.net.netif);
340 if (dev) {
341 audit_log_format(ab, " netif=%s", dev->name);
342 dev_put(dev);
343 }
344 }
345 break;
346#ifdef CONFIG_KEYS
347 case LSM_AUDIT_DATA_KEY:
348 audit_log_format(ab, " key_serial=%u", a->u.key_struct.key);
349 if (a->u.key_struct.key_desc) {
350 audit_log_format(ab, " key_desc=");
351 audit_log_untrustedstring(ab, a->u.key_struct.key_desc);
352 }
353 break;
354#endif
355 } /* switch (a->type) */
356}
357
358/**
359 * common_lsm_audit - generic LSM auditing function
360 * @a: auxiliary audit data
361 *
362 * setup the audit buffer for common security information
363 * uses callback to print LSM specific information
364 */
365void common_lsm_audit(struct common_audit_data *a)
366{
367 struct audit_buffer *ab;
368
369 if (a == NULL)
370 return;
371 /* we use GFP_ATOMIC so we won't sleep */
372 ab = audit_log_start(current->audit_context, GFP_ATOMIC, AUDIT_AVC);
373
374 if (ab == NULL)
375 return;
376
377 if (a->lsm_pre_audit)
378 a->lsm_pre_audit(ab, a);
379
380 dump_common_audit_data(ab, a);
381
382 if (a->lsm_post_audit)
383 a->lsm_post_audit(ab, a);
384
385 audit_log_end(ab);
386}
diff --git a/security/root_plug.c b/security/root_plug.c
index 40fb4f15e27b..2f7ffa67c4d2 100644
--- a/security/root_plug.c
+++ b/security/root_plug.c
@@ -71,18 +71,6 @@ static int rootplug_bprm_check_security (struct linux_binprm *bprm)
71} 71}
72 72
73static struct security_operations rootplug_security_ops = { 73static struct security_operations rootplug_security_ops = {
74 /* Use the capability functions for some of the hooks */
75 .ptrace_may_access = cap_ptrace_may_access,
76 .ptrace_traceme = cap_ptrace_traceme,
77 .capget = cap_capget,
78 .capset = cap_capset,
79 .capable = cap_capable,
80
81 .bprm_set_creds = cap_bprm_set_creds,
82
83 .task_fix_setuid = cap_task_fix_setuid,
84 .task_prctl = cap_task_prctl,
85
86 .bprm_check_security = rootplug_bprm_check_security, 74 .bprm_check_security = rootplug_bprm_check_security,
87}; 75};
88 76
diff --git a/security/security.c b/security/security.c
index 5284255c5cdf..dc7674fbfc7a 100644
--- a/security/security.c
+++ b/security/security.c
@@ -26,9 +26,6 @@ extern void security_fixup_ops(struct security_operations *ops);
26 26
27struct security_operations *security_ops; /* Initialized to NULL */ 27struct security_operations *security_ops; /* Initialized to NULL */
28 28
29/* amount of vm to protect from userspace access */
30unsigned long mmap_min_addr = CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR;
31
32static inline int verify(struct security_operations *ops) 29static inline int verify(struct security_operations *ops)
33{ 30{
34 /* verify the security_operations structure exists */ 31 /* verify the security_operations structure exists */
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index 7f9b5fac8779..b2ab60859832 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -927,7 +927,7 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid,
927 if (denied) { 927 if (denied) {
928 if (flags & AVC_STRICT) 928 if (flags & AVC_STRICT)
929 rc = -EACCES; 929 rc = -EACCES;
930 else if (!selinux_enforcing || security_permissive_sid(ssid)) 930 else if (!selinux_enforcing || (avd->flags & AVD_FLAGS_PERMISSIVE))
931 avc_update_node(AVC_CALLBACK_GRANT, requested, ssid, 931 avc_update_node(AVC_CALLBACK_GRANT, requested, ssid,
932 tsid, tclass, avd->seqno); 932 tsid, tclass, avd->seqno);
933 else 933 else
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 2fcad7c33eaf..195906bce266 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -1980,10 +1980,6 @@ static int selinux_sysctl(ctl_table *table, int op)
1980 u32 tsid, sid; 1980 u32 tsid, sid;
1981 int rc; 1981 int rc;
1982 1982
1983 rc = secondary_ops->sysctl(table, op);
1984 if (rc)
1985 return rc;
1986
1987 sid = current_sid(); 1983 sid = current_sid();
1988 1984
1989 rc = selinux_sysctl_get_sid(table, (op == 0001) ? 1985 rc = selinux_sysctl_get_sid(table, (op == 0001) ?
@@ -2375,10 +2371,8 @@ static void selinux_bprm_committed_creds(struct linux_binprm *bprm)
2375{ 2371{
2376 const struct task_security_struct *tsec = current_security(); 2372 const struct task_security_struct *tsec = current_security();
2377 struct itimerval itimer; 2373 struct itimerval itimer;
2378 struct sighand_struct *psig;
2379 u32 osid, sid; 2374 u32 osid, sid;
2380 int rc, i; 2375 int rc, i;
2381 unsigned long flags;
2382 2376
2383 osid = tsec->osid; 2377 osid = tsec->osid;
2384 sid = tsec->sid; 2378 sid = tsec->sid;
@@ -2398,22 +2392,20 @@ static void selinux_bprm_committed_creds(struct linux_binprm *bprm)
2398 memset(&itimer, 0, sizeof itimer); 2392 memset(&itimer, 0, sizeof itimer);
2399 for (i = 0; i < 3; i++) 2393 for (i = 0; i < 3; i++)
2400 do_setitimer(i, &itimer, NULL); 2394 do_setitimer(i, &itimer, NULL);
2401 flush_signals(current);
2402 spin_lock_irq(&current->sighand->siglock); 2395 spin_lock_irq(&current->sighand->siglock);
2403 flush_signal_handlers(current, 1); 2396 if (!(current->signal->flags & SIGNAL_GROUP_EXIT)) {
2404 sigemptyset(&current->blocked); 2397 __flush_signals(current);
2405 recalc_sigpending(); 2398 flush_signal_handlers(current, 1);
2399 sigemptyset(&current->blocked);
2400 }
2406 spin_unlock_irq(&current->sighand->siglock); 2401 spin_unlock_irq(&current->sighand->siglock);
2407 } 2402 }
2408 2403
2409 /* Wake up the parent if it is waiting so that it can recheck 2404 /* Wake up the parent if it is waiting so that it can recheck
2410 * wait permission to the new task SID. */ 2405 * wait permission to the new task SID. */
2411 read_lock_irq(&tasklist_lock); 2406 read_lock(&tasklist_lock);
2412 psig = current->parent->sighand; 2407 wake_up_interruptible(&current->real_parent->signal->wait_chldexit);
2413 spin_lock_irqsave(&psig->siglock, flags); 2408 read_unlock(&tasklist_lock);
2414 wake_up_interruptible(&current->parent->signal->wait_chldexit);
2415 spin_unlock_irqrestore(&psig->siglock, flags);
2416 read_unlock_irq(&tasklist_lock);
2417} 2409}
2418 2410
2419/* superblock security operations */ 2411/* superblock security operations */
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index 5c3434f7626f..ca835795a8b3 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -8,14 +8,13 @@
8#ifndef _SELINUX_SECURITY_H_ 8#ifndef _SELINUX_SECURITY_H_
9#define _SELINUX_SECURITY_H_ 9#define _SELINUX_SECURITY_H_
10 10
11#include <linux/magic.h>
11#include "flask.h" 12#include "flask.h"
12 13
13#define SECSID_NULL 0x00000000 /* unspecified SID */ 14#define SECSID_NULL 0x00000000 /* unspecified SID */
14#define SECSID_WILD 0xffffffff /* wildcard SID */ 15#define SECSID_WILD 0xffffffff /* wildcard SID */
15#define SECCLASS_NULL 0x0000 /* no class */ 16#define SECCLASS_NULL 0x0000 /* no class */
16 17
17#define SELINUX_MAGIC 0xf97cff8c
18
19/* Identify specific policy version changes */ 18/* Identify specific policy version changes */
20#define POLICYDB_VERSION_BASE 15 19#define POLICYDB_VERSION_BASE 15
21#define POLICYDB_VERSION_BOOL 16 20#define POLICYDB_VERSION_BOOL 16
@@ -91,9 +90,11 @@ struct av_decision {
91 u32 auditallow; 90 u32 auditallow;
92 u32 auditdeny; 91 u32 auditdeny;
93 u32 seqno; 92 u32 seqno;
93 u32 flags;
94}; 94};
95 95
96int security_permissive_sid(u32 sid); 96/* definitions of av_decision.flags */
97#define AVD_FLAGS_PERMISSIVE 0x0001
97 98
98int security_compute_av(u32 ssid, u32 tsid, 99int security_compute_av(u32 ssid, u32 tsid,
99 u16 tclass, u32 requested, 100 u16 tclass, u32 requested,
diff --git a/security/selinux/nlmsgtab.c b/security/selinux/nlmsgtab.c
index c6875fd3b9d6..dd7cc6de77f9 100644
--- a/security/selinux/nlmsgtab.c
+++ b/security/selinux/nlmsgtab.c
@@ -112,6 +112,8 @@ static struct nlmsg_perm nlmsg_audit_perms[] =
112 { AUDIT_DEL_RULE, NETLINK_AUDIT_SOCKET__NLMSG_WRITE }, 112 { AUDIT_DEL_RULE, NETLINK_AUDIT_SOCKET__NLMSG_WRITE },
113 { AUDIT_USER, NETLINK_AUDIT_SOCKET__NLMSG_RELAY }, 113 { AUDIT_USER, NETLINK_AUDIT_SOCKET__NLMSG_RELAY },
114 { AUDIT_SIGNAL_INFO, NETLINK_AUDIT_SOCKET__NLMSG_READ }, 114 { AUDIT_SIGNAL_INFO, NETLINK_AUDIT_SOCKET__NLMSG_READ },
115 { AUDIT_TRIM, NETLINK_AUDIT_SOCKET__NLMSG_WRITE },
116 { AUDIT_MAKE_EQUIV, NETLINK_AUDIT_SOCKET__NLMSG_WRITE },
115 { AUDIT_TTY_GET, NETLINK_AUDIT_SOCKET__NLMSG_READ }, 117 { AUDIT_TTY_GET, NETLINK_AUDIT_SOCKET__NLMSG_READ },
116 { AUDIT_TTY_SET, NETLINK_AUDIT_SOCKET__NLMSG_TTY_AUDIT }, 118 { AUDIT_TTY_SET, NETLINK_AUDIT_SOCKET__NLMSG_TTY_AUDIT },
117}; 119};
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 2d5136ec3d54..b4fc506e7a87 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -527,10 +527,10 @@ static ssize_t sel_write_access(struct file *file, char *buf, size_t size)
527 goto out2; 527 goto out2;
528 528
529 length = scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, 529 length = scnprintf(buf, SIMPLE_TRANSACTION_LIMIT,
530 "%x %x %x %x %u", 530 "%x %x %x %x %u %x",
531 avd.allowed, 0xffffffff, 531 avd.allowed, 0xffffffff,
532 avd.auditallow, avd.auditdeny, 532 avd.auditallow, avd.auditdeny,
533 avd.seqno); 533 avd.seqno, avd.flags);
534out2: 534out2:
535 kfree(tcon); 535 kfree(tcon);
536out: 536out:
@@ -803,10 +803,6 @@ static ssize_t sel_read_bool(struct file *filep, char __user *buf,
803 goto out; 803 goto out;
804 } 804 }
805 805
806 if (count > PAGE_SIZE) {
807 ret = -EINVAL;
808 goto out;
809 }
810 page = (char *)get_zeroed_page(GFP_KERNEL); 806 page = (char *)get_zeroed_page(GFP_KERNEL);
811 if (!page) { 807 if (!page) {
812 ret = -ENOMEM; 808 ret = -ENOMEM;
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index deeec6c013ae..500e6f78e115 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -410,6 +410,7 @@ static int context_struct_compute_av(struct context *scontext,
410 avd->auditallow = 0; 410 avd->auditallow = 0;
411 avd->auditdeny = 0xffffffff; 411 avd->auditdeny = 0xffffffff;
412 avd->seqno = latest_granting; 412 avd->seqno = latest_granting;
413 avd->flags = 0;
413 414
414 /* 415 /*
415 * Check for all the invalid cases. 416 * Check for all the invalid cases.
@@ -528,31 +529,6 @@ inval_class:
528 return 0; 529 return 0;
529} 530}
530 531
531/*
532 * Given a sid find if the type has the permissive flag set
533 */
534int security_permissive_sid(u32 sid)
535{
536 struct context *context;
537 u32 type;
538 int rc;
539
540 read_lock(&policy_rwlock);
541
542 context = sidtab_search(&sidtab, sid);
543 BUG_ON(!context);
544
545 type = context->type;
546 /*
547 * we are intentionally using type here, not type-1, the 0th bit may
548 * someday indicate that we are globally setting permissive in policy.
549 */
550 rc = ebitmap_get_bit(&policydb.permissive_map, type);
551
552 read_unlock(&policy_rwlock);
553 return rc;
554}
555
556static int security_validtrans_handle_fail(struct context *ocontext, 532static int security_validtrans_handle_fail(struct context *ocontext,
557 struct context *ncontext, 533 struct context *ncontext,
558 struct context *tcontext, 534 struct context *tcontext,
@@ -767,6 +743,10 @@ int security_compute_av(u32 ssid,
767 743
768 rc = context_struct_compute_av(scontext, tcontext, tclass, 744 rc = context_struct_compute_av(scontext, tcontext, tclass,
769 requested, avd); 745 requested, avd);
746
747 /* permissive domain? */
748 if (ebitmap_get_bit(&policydb.permissive_map, scontext->type))
749 avd->flags |= AVD_FLAGS_PERMISSIVE;
770out: 750out:
771 read_unlock(&policy_rwlock); 751 read_unlock(&policy_rwlock);
772 return rc; 752 return rc;
diff --git a/security/smack/smack.h b/security/smack/smack.h
index 42ef313f9856..243bec175be0 100644
--- a/security/smack/smack.h
+++ b/security/smack/smack.h
@@ -20,6 +20,7 @@
20#include <net/netlabel.h> 20#include <net/netlabel.h>
21#include <linux/list.h> 21#include <linux/list.h>
22#include <linux/rculist.h> 22#include <linux/rculist.h>
23#include <linux/lsm_audit.h>
23 24
24/* 25/*
25 * Why 23? CIPSO is constrained to 30, so a 32 byte buffer is 26 * Why 23? CIPSO is constrained to 30, so a 32 byte buffer is
@@ -179,6 +180,20 @@ struct smack_known {
179#define MAY_NOT 0 180#define MAY_NOT 0
180 181
181/* 182/*
183 * Number of access types used by Smack (rwxa)
184 */
185#define SMK_NUM_ACCESS_TYPE 4
186
187/*
188 * Smack audit data; is empty if CONFIG_AUDIT not set
189 * to save some stack
190 */
191struct smk_audit_info {
192#ifdef CONFIG_AUDIT
193 struct common_audit_data a;
194#endif
195};
196/*
182 * These functions are in smack_lsm.c 197 * These functions are in smack_lsm.c
183 */ 198 */
184struct inode_smack *new_inode_smack(char *); 199struct inode_smack *new_inode_smack(char *);
@@ -186,8 +201,8 @@ struct inode_smack *new_inode_smack(char *);
186/* 201/*
187 * These functions are in smack_access.c 202 * These functions are in smack_access.c
188 */ 203 */
189int smk_access(char *, char *, int); 204int smk_access(char *, char *, int, struct smk_audit_info *);
190int smk_curacc(char *, u32); 205int smk_curacc(char *, u32, struct smk_audit_info *);
191int smack_to_cipso(const char *, struct smack_cipso *); 206int smack_to_cipso(const char *, struct smack_cipso *);
192void smack_from_cipso(u32, char *, char *); 207void smack_from_cipso(u32, char *, char *);
193char *smack_from_secid(const u32); 208char *smack_from_secid(const u32);
@@ -237,4 +252,93 @@ static inline char *smk_of_inode(const struct inode *isp)
237 return sip->smk_inode; 252 return sip->smk_inode;
238} 253}
239 254
255/*
256 * logging functions
257 */
258#define SMACK_AUDIT_DENIED 0x1
259#define SMACK_AUDIT_ACCEPT 0x2
260extern int log_policy;
261
262void smack_log(char *subject_label, char *object_label,
263 int request,
264 int result, struct smk_audit_info *auditdata);
265
266#ifdef CONFIG_AUDIT
267
268/*
269 * some inline functions to set up audit data
270 * they do nothing if CONFIG_AUDIT is not set
271 *
272 */
273static inline void smk_ad_init(struct smk_audit_info *a, const char *func,
274 char type)
275{
276 memset(a, 0, sizeof(*a));
277 a->a.type = type;
278 a->a.function = func;
279}
280
281static inline void smk_ad_setfield_u_tsk(struct smk_audit_info *a,
282 struct task_struct *t)
283{
284 a->a.u.tsk = t;
285}
286static inline void smk_ad_setfield_u_fs_path_dentry(struct smk_audit_info *a,
287 struct dentry *d)
288{
289 a->a.u.fs.path.dentry = d;
290}
291static inline void smk_ad_setfield_u_fs_path_mnt(struct smk_audit_info *a,
292 struct vfsmount *m)
293{
294 a->a.u.fs.path.mnt = m;
295}
296static inline void smk_ad_setfield_u_fs_inode(struct smk_audit_info *a,
297 struct inode *i)
298{
299 a->a.u.fs.inode = i;
300}
301static inline void smk_ad_setfield_u_fs_path(struct smk_audit_info *a,
302 struct path p)
303{
304 a->a.u.fs.path = p;
305}
306static inline void smk_ad_setfield_u_net_sk(struct smk_audit_info *a,
307 struct sock *sk)
308{
309 a->a.u.net.sk = sk;
310}
311
312#else /* no AUDIT */
313
314static inline void smk_ad_init(struct smk_audit_info *a, const char *func,
315 char type)
316{
317}
318static inline void smk_ad_setfield_u_tsk(struct smk_audit_info *a,
319 struct task_struct *t)
320{
321}
322static inline void smk_ad_setfield_u_fs_path_dentry(struct smk_audit_info *a,
323 struct dentry *d)
324{
325}
326static inline void smk_ad_setfield_u_fs_path_mnt(struct smk_audit_info *a,
327 struct vfsmount *m)
328{
329}
330static inline void smk_ad_setfield_u_fs_inode(struct smk_audit_info *a,
331 struct inode *i)
332{
333}
334static inline void smk_ad_setfield_u_fs_path(struct smk_audit_info *a,
335 struct path p)
336{
337}
338static inline void smk_ad_setfield_u_net_sk(struct smk_audit_info *a,
339 struct sock *sk)
340{
341}
342#endif
343
240#endif /* _SECURITY_SMACK_H */ 344#endif /* _SECURITY_SMACK_H */
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c
index ac0a2707f6d4..513dc1aa16dd 100644
--- a/security/smack/smack_access.c
+++ b/security/smack/smack_access.c
@@ -59,11 +59,18 @@ LIST_HEAD(smack_known_list);
59 */ 59 */
60static u32 smack_next_secid = 10; 60static u32 smack_next_secid = 10;
61 61
62/*
63 * what events do we log
64 * can be overwritten at run-time by /smack/logging
65 */
66int log_policy = SMACK_AUDIT_DENIED;
67
62/** 68/**
63 * smk_access - determine if a subject has a specific access to an object 69 * smk_access - determine if a subject has a specific access to an object
64 * @subject_label: a pointer to the subject's Smack label 70 * @subject_label: a pointer to the subject's Smack label
65 * @object_label: a pointer to the object's Smack label 71 * @object_label: a pointer to the object's Smack label
66 * @request: the access requested, in "MAY" format 72 * @request: the access requested, in "MAY" format
73 * @a : a pointer to the audit data
67 * 74 *
68 * This function looks up the subject/object pair in the 75 * This function looks up the subject/object pair in the
69 * access rule list and returns 0 if the access is permitted, 76 * access rule list and returns 0 if the access is permitted,
@@ -78,10 +85,12 @@ static u32 smack_next_secid = 10;
78 * will be on the list, so checking the pointers may be a worthwhile 85 * will be on the list, so checking the pointers may be a worthwhile
79 * optimization. 86 * optimization.
80 */ 87 */
81int smk_access(char *subject_label, char *object_label, int request) 88int smk_access(char *subject_label, char *object_label, int request,
89 struct smk_audit_info *a)
82{ 90{
83 u32 may = MAY_NOT; 91 u32 may = MAY_NOT;
84 struct smack_rule *srp; 92 struct smack_rule *srp;
93 int rc = 0;
85 94
86 /* 95 /*
87 * Hardcoded comparisons. 96 * Hardcoded comparisons.
@@ -89,8 +98,10 @@ int smk_access(char *subject_label, char *object_label, int request)
89 * A star subject can't access any object. 98 * A star subject can't access any object.
90 */ 99 */
91 if (subject_label == smack_known_star.smk_known || 100 if (subject_label == smack_known_star.smk_known ||
92 strcmp(subject_label, smack_known_star.smk_known) == 0) 101 strcmp(subject_label, smack_known_star.smk_known) == 0) {
93 return -EACCES; 102 rc = -EACCES;
103 goto out_audit;
104 }
94 /* 105 /*
95 * An internet object can be accessed by any subject. 106 * An internet object can be accessed by any subject.
96 * Tasks cannot be assigned the internet label. 107 * Tasks cannot be assigned the internet label.
@@ -100,20 +111,20 @@ int smk_access(char *subject_label, char *object_label, int request)
100 subject_label == smack_known_web.smk_known || 111 subject_label == smack_known_web.smk_known ||
101 strcmp(object_label, smack_known_web.smk_known) == 0 || 112 strcmp(object_label, smack_known_web.smk_known) == 0 ||
102 strcmp(subject_label, smack_known_web.smk_known) == 0) 113 strcmp(subject_label, smack_known_web.smk_known) == 0)
103 return 0; 114 goto out_audit;
104 /* 115 /*
105 * A star object can be accessed by any subject. 116 * A star object can be accessed by any subject.
106 */ 117 */
107 if (object_label == smack_known_star.smk_known || 118 if (object_label == smack_known_star.smk_known ||
108 strcmp(object_label, smack_known_star.smk_known) == 0) 119 strcmp(object_label, smack_known_star.smk_known) == 0)
109 return 0; 120 goto out_audit;
110 /* 121 /*
111 * An object can be accessed in any way by a subject 122 * An object can be accessed in any way by a subject
112 * with the same label. 123 * with the same label.
113 */ 124 */
114 if (subject_label == object_label || 125 if (subject_label == object_label ||
115 strcmp(subject_label, object_label) == 0) 126 strcmp(subject_label, object_label) == 0)
116 return 0; 127 goto out_audit;
117 /* 128 /*
118 * A hat subject can read any object. 129 * A hat subject can read any object.
119 * A floor object can be read by any subject. 130 * A floor object can be read by any subject.
@@ -121,10 +132,10 @@ int smk_access(char *subject_label, char *object_label, int request)
121 if ((request & MAY_ANYREAD) == request) { 132 if ((request & MAY_ANYREAD) == request) {
122 if (object_label == smack_known_floor.smk_known || 133 if (object_label == smack_known_floor.smk_known ||
123 strcmp(object_label, smack_known_floor.smk_known) == 0) 134 strcmp(object_label, smack_known_floor.smk_known) == 0)
124 return 0; 135 goto out_audit;
125 if (subject_label == smack_known_hat.smk_known || 136 if (subject_label == smack_known_hat.smk_known ||
126 strcmp(subject_label, smack_known_hat.smk_known) == 0) 137 strcmp(subject_label, smack_known_hat.smk_known) == 0)
127 return 0; 138 goto out_audit;
128 } 139 }
129 /* 140 /*
130 * Beyond here an explicit relationship is required. 141 * Beyond here an explicit relationship is required.
@@ -148,28 +159,36 @@ int smk_access(char *subject_label, char *object_label, int request)
148 * This is a bit map operation. 159 * This is a bit map operation.
149 */ 160 */
150 if ((request & may) == request) 161 if ((request & may) == request)
151 return 0; 162 goto out_audit;
152 163
153 return -EACCES; 164 rc = -EACCES;
165out_audit:
166#ifdef CONFIG_AUDIT
167 if (a)
168 smack_log(subject_label, object_label, request, rc, a);
169#endif
170 return rc;
154} 171}
155 172
156/** 173/**
157 * smk_curacc - determine if current has a specific access to an object 174 * smk_curacc - determine if current has a specific access to an object
158 * @obj_label: a pointer to the object's Smack label 175 * @obj_label: a pointer to the object's Smack label
159 * @mode: the access requested, in "MAY" format 176 * @mode: the access requested, in "MAY" format
177 * @a : common audit data
160 * 178 *
161 * This function checks the current subject label/object label pair 179 * This function checks the current subject label/object label pair
162 * in the access rule list and returns 0 if the access is permitted, 180 * in the access rule list and returns 0 if the access is permitted,
163 * non zero otherwise. It allows that current may have the capability 181 * non zero otherwise. It allows that current may have the capability
164 * to override the rules. 182 * to override the rules.
165 */ 183 */
166int smk_curacc(char *obj_label, u32 mode) 184int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a)
167{ 185{
168 int rc; 186 int rc;
187 char *sp = current_security();
169 188
170 rc = smk_access(current_security(), obj_label, mode); 189 rc = smk_access(sp, obj_label, mode, NULL);
171 if (rc == 0) 190 if (rc == 0)
172 return 0; 191 goto out_audit;
173 192
174 /* 193 /*
175 * Return if a specific label has been designated as the 194 * Return if a specific label has been designated as the
@@ -177,14 +196,105 @@ int smk_curacc(char *obj_label, u32 mode)
177 * have that label. 196 * have that label.
178 */ 197 */
179 if (smack_onlycap != NULL && smack_onlycap != current->cred->security) 198 if (smack_onlycap != NULL && smack_onlycap != current->cred->security)
180 return rc; 199 goto out_audit;
181 200
182 if (capable(CAP_MAC_OVERRIDE)) 201 if (capable(CAP_MAC_OVERRIDE))
183 return 0; 202 return 0;
184 203
204out_audit:
205#ifdef CONFIG_AUDIT
206 if (a)
207 smack_log(sp, obj_label, mode, rc, a);
208#endif
185 return rc; 209 return rc;
186} 210}
187 211
212#ifdef CONFIG_AUDIT
213/**
214 * smack_str_from_perm : helper to transalate an int to a
215 * readable string
216 * @string : the string to fill
217 * @access : the int
218 *
219 */
220static inline void smack_str_from_perm(char *string, int access)
221{
222 int i = 0;
223 if (access & MAY_READ)
224 string[i++] = 'r';
225 if (access & MAY_WRITE)
226 string[i++] = 'w';
227 if (access & MAY_EXEC)
228 string[i++] = 'x';
229 if (access & MAY_APPEND)
230 string[i++] = 'a';
231 string[i] = '\0';
232}
233/**
234 * smack_log_callback - SMACK specific information
235 * will be called by generic audit code
236 * @ab : the audit_buffer
237 * @a : audit_data
238 *
239 */
240static void smack_log_callback(struct audit_buffer *ab, void *a)
241{
242 struct common_audit_data *ad = a;
243 struct smack_audit_data *sad = &ad->lsm_priv.smack_audit_data;
244 audit_log_format(ab, "lsm=SMACK fn=%s action=%s", ad->function,
245 sad->result ? "denied" : "granted");
246 audit_log_format(ab, " subject=");
247 audit_log_untrustedstring(ab, sad->subject);
248 audit_log_format(ab, " object=");
249 audit_log_untrustedstring(ab, sad->object);
250 audit_log_format(ab, " requested=%s", sad->request);
251}
252
253/**
254 * smack_log - Audit the granting or denial of permissions.
255 * @subject_label : smack label of the requester
256 * @object_label : smack label of the object being accessed
257 * @request: requested permissions
258 * @result: result from smk_access
259 * @a: auxiliary audit data
260 *
261 * Audit the granting or denial of permissions in accordance
262 * with the policy.
263 */
264void smack_log(char *subject_label, char *object_label, int request,
265 int result, struct smk_audit_info *ad)
266{
267 char request_buffer[SMK_NUM_ACCESS_TYPE + 1];
268 struct smack_audit_data *sad;
269 struct common_audit_data *a = &ad->a;
270
271 /* check if we have to log the current event */
272 if (result != 0 && (log_policy & SMACK_AUDIT_DENIED) == 0)
273 return;
274 if (result == 0 && (log_policy & SMACK_AUDIT_ACCEPT) == 0)
275 return;
276
277 if (a->function == NULL)
278 a->function = "unknown";
279
280 /* end preparing the audit data */
281 sad = &a->lsm_priv.smack_audit_data;
282 smack_str_from_perm(request_buffer, request);
283 sad->subject = subject_label;
284 sad->object = object_label;
285 sad->request = request_buffer;
286 sad->result = result;
287 a->lsm_pre_audit = smack_log_callback;
288
289 common_lsm_audit(a);
290}
291#else /* #ifdef CONFIG_AUDIT */
292void smack_log(char *subject_label, char *object_label, int request,
293 int result, struct smk_audit_info *ad)
294{
295}
296#endif
297
188static DEFINE_MUTEX(smack_known_lock); 298static DEFINE_MUTEX(smack_known_lock);
189 299
190/** 300/**
@@ -209,7 +319,8 @@ struct smack_known *smk_import_entry(const char *string, int len)
209 if (found) 319 if (found)
210 smack[i] = '\0'; 320 smack[i] = '\0';
211 else if (i >= len || string[i] > '~' || string[i] <= ' ' || 321 else if (i >= len || string[i] > '~' || string[i] <= ' ' ||
212 string[i] == '/') { 322 string[i] == '/' || string[i] == '"' ||
323 string[i] == '\\' || string[i] == '\'') {
213 smack[i] = '\0'; 324 smack[i] = '\0';
214 found = 1; 325 found = 1;
215 } else 326 } else
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 98b3195347ab..0023182078c7 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -30,7 +30,6 @@
30#include <net/netlabel.h> 30#include <net/netlabel.h>
31#include <net/cipso_ipv4.h> 31#include <net/cipso_ipv4.h>
32#include <linux/audit.h> 32#include <linux/audit.h>
33
34#include "smack.h" 33#include "smack.h"
35 34
36#define task_security(task) (task_cred_xxx((task), security)) 35#define task_security(task) (task_cred_xxx((task), security))
@@ -103,14 +102,24 @@ struct inode_smack *new_inode_smack(char *smack)
103static int smack_ptrace_may_access(struct task_struct *ctp, unsigned int mode) 102static int smack_ptrace_may_access(struct task_struct *ctp, unsigned int mode)
104{ 103{
105 int rc; 104 int rc;
105 struct smk_audit_info ad;
106 char *sp, *tsp;
106 107
107 rc = cap_ptrace_may_access(ctp, mode); 108 rc = cap_ptrace_may_access(ctp, mode);
108 if (rc != 0) 109 if (rc != 0)
109 return rc; 110 return rc;
110 111
111 rc = smk_access(current_security(), task_security(ctp), MAY_READWRITE); 112 sp = current_security();
113 tsp = task_security(ctp);
114 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
115 smk_ad_setfield_u_tsk(&ad, ctp);
116
117 /* we won't log here, because rc can be overriden */
118 rc = smk_access(sp, tsp, MAY_READWRITE, NULL);
112 if (rc != 0 && capable(CAP_MAC_OVERRIDE)) 119 if (rc != 0 && capable(CAP_MAC_OVERRIDE))
113 return 0; 120 rc = 0;
121
122 smack_log(sp, tsp, MAY_READWRITE, rc, &ad);
114 return rc; 123 return rc;
115} 124}
116 125
@@ -125,14 +134,24 @@ static int smack_ptrace_may_access(struct task_struct *ctp, unsigned int mode)
125static int smack_ptrace_traceme(struct task_struct *ptp) 134static int smack_ptrace_traceme(struct task_struct *ptp)
126{ 135{
127 int rc; 136 int rc;
137 struct smk_audit_info ad;
138 char *sp, *tsp;
128 139
129 rc = cap_ptrace_traceme(ptp); 140 rc = cap_ptrace_traceme(ptp);
130 if (rc != 0) 141 if (rc != 0)
131 return rc; 142 return rc;
132 143
133 rc = smk_access(task_security(ptp), current_security(), MAY_READWRITE); 144 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
145 smk_ad_setfield_u_tsk(&ad, ptp);
146
147 sp = current_security();
148 tsp = task_security(ptp);
149 /* we won't log here, because rc can be overriden */
150 rc = smk_access(tsp, sp, MAY_READWRITE, NULL);
134 if (rc != 0 && has_capability(ptp, CAP_MAC_OVERRIDE)) 151 if (rc != 0 && has_capability(ptp, CAP_MAC_OVERRIDE))
135 return 0; 152 rc = 0;
153
154 smack_log(tsp, sp, MAY_READWRITE, rc, &ad);
136 return rc; 155 return rc;
137} 156}
138 157
@@ -327,8 +346,14 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data)
327static int smack_sb_statfs(struct dentry *dentry) 346static int smack_sb_statfs(struct dentry *dentry)
328{ 347{
329 struct superblock_smack *sbp = dentry->d_sb->s_security; 348 struct superblock_smack *sbp = dentry->d_sb->s_security;
349 int rc;
350 struct smk_audit_info ad;
351
352 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
353 smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
330 354
331 return smk_curacc(sbp->smk_floor, MAY_READ); 355 rc = smk_curacc(sbp->smk_floor, MAY_READ, &ad);
356 return rc;
332} 357}
333 358
334/** 359/**
@@ -346,8 +371,12 @@ static int smack_sb_mount(char *dev_name, struct path *path,
346 char *type, unsigned long flags, void *data) 371 char *type, unsigned long flags, void *data)
347{ 372{
348 struct superblock_smack *sbp = path->mnt->mnt_sb->s_security; 373 struct superblock_smack *sbp = path->mnt->mnt_sb->s_security;
374 struct smk_audit_info ad;
375
376 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
377 smk_ad_setfield_u_fs_path(&ad, *path);
349 378
350 return smk_curacc(sbp->smk_floor, MAY_WRITE); 379 return smk_curacc(sbp->smk_floor, MAY_WRITE, &ad);
351} 380}
352 381
353/** 382/**
@@ -361,10 +390,14 @@ static int smack_sb_mount(char *dev_name, struct path *path,
361static int smack_sb_umount(struct vfsmount *mnt, int flags) 390static int smack_sb_umount(struct vfsmount *mnt, int flags)
362{ 391{
363 struct superblock_smack *sbp; 392 struct superblock_smack *sbp;
393 struct smk_audit_info ad;
364 394
365 sbp = mnt->mnt_sb->s_security; 395 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
396 smk_ad_setfield_u_fs_path_dentry(&ad, mnt->mnt_mountpoint);
397 smk_ad_setfield_u_fs_path_mnt(&ad, mnt);
366 398
367 return smk_curacc(sbp->smk_floor, MAY_WRITE); 399 sbp = mnt->mnt_sb->s_security;
400 return smk_curacc(sbp->smk_floor, MAY_WRITE, &ad);
368} 401}
369 402
370/* 403/*
@@ -441,15 +474,20 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir,
441static int smack_inode_link(struct dentry *old_dentry, struct inode *dir, 474static int smack_inode_link(struct dentry *old_dentry, struct inode *dir,
442 struct dentry *new_dentry) 475 struct dentry *new_dentry)
443{ 476{
444 int rc;
445 char *isp; 477 char *isp;
478 struct smk_audit_info ad;
479 int rc;
480
481 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
482 smk_ad_setfield_u_fs_path_dentry(&ad, old_dentry);
446 483
447 isp = smk_of_inode(old_dentry->d_inode); 484 isp = smk_of_inode(old_dentry->d_inode);
448 rc = smk_curacc(isp, MAY_WRITE); 485 rc = smk_curacc(isp, MAY_WRITE, &ad);
449 486
450 if (rc == 0 && new_dentry->d_inode != NULL) { 487 if (rc == 0 && new_dentry->d_inode != NULL) {
451 isp = smk_of_inode(new_dentry->d_inode); 488 isp = smk_of_inode(new_dentry->d_inode);
452 rc = smk_curacc(isp, MAY_WRITE); 489 smk_ad_setfield_u_fs_path_dentry(&ad, new_dentry);
490 rc = smk_curacc(isp, MAY_WRITE, &ad);
453 } 491 }
454 492
455 return rc; 493 return rc;
@@ -466,18 +504,24 @@ static int smack_inode_link(struct dentry *old_dentry, struct inode *dir,
466static int smack_inode_unlink(struct inode *dir, struct dentry *dentry) 504static int smack_inode_unlink(struct inode *dir, struct dentry *dentry)
467{ 505{
468 struct inode *ip = dentry->d_inode; 506 struct inode *ip = dentry->d_inode;
507 struct smk_audit_info ad;
469 int rc; 508 int rc;
470 509
510 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
511 smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
512
471 /* 513 /*
472 * You need write access to the thing you're unlinking 514 * You need write access to the thing you're unlinking
473 */ 515 */
474 rc = smk_curacc(smk_of_inode(ip), MAY_WRITE); 516 rc = smk_curacc(smk_of_inode(ip), MAY_WRITE, &ad);
475 if (rc == 0) 517 if (rc == 0) {
476 /* 518 /*
477 * You also need write access to the containing directory 519 * You also need write access to the containing directory
478 */ 520 */
479 rc = smk_curacc(smk_of_inode(dir), MAY_WRITE); 521 smk_ad_setfield_u_fs_path_dentry(&ad, NULL);
480 522 smk_ad_setfield_u_fs_inode(&ad, dir);
523 rc = smk_curacc(smk_of_inode(dir), MAY_WRITE, &ad);
524 }
481 return rc; 525 return rc;
482} 526}
483 527
@@ -491,17 +535,24 @@ static int smack_inode_unlink(struct inode *dir, struct dentry *dentry)
491 */ 535 */
492static int smack_inode_rmdir(struct inode *dir, struct dentry *dentry) 536static int smack_inode_rmdir(struct inode *dir, struct dentry *dentry)
493{ 537{
538 struct smk_audit_info ad;
494 int rc; 539 int rc;
495 540
541 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
542 smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
543
496 /* 544 /*
497 * You need write access to the thing you're removing 545 * You need write access to the thing you're removing
498 */ 546 */
499 rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE); 547 rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad);
500 if (rc == 0) 548 if (rc == 0) {
501 /* 549 /*
502 * You also need write access to the containing directory 550 * You also need write access to the containing directory
503 */ 551 */
504 rc = smk_curacc(smk_of_inode(dir), MAY_WRITE); 552 smk_ad_setfield_u_fs_path_dentry(&ad, NULL);
553 smk_ad_setfield_u_fs_inode(&ad, dir);
554 rc = smk_curacc(smk_of_inode(dir), MAY_WRITE, &ad);
555 }
505 556
506 return rc; 557 return rc;
507} 558}
@@ -525,15 +576,19 @@ static int smack_inode_rename(struct inode *old_inode,
525{ 576{
526 int rc; 577 int rc;
527 char *isp; 578 char *isp;
579 struct smk_audit_info ad;
580
581 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
582 smk_ad_setfield_u_fs_path_dentry(&ad, old_dentry);
528 583
529 isp = smk_of_inode(old_dentry->d_inode); 584 isp = smk_of_inode(old_dentry->d_inode);
530 rc = smk_curacc(isp, MAY_READWRITE); 585 rc = smk_curacc(isp, MAY_READWRITE, &ad);
531 586
532 if (rc == 0 && new_dentry->d_inode != NULL) { 587 if (rc == 0 && new_dentry->d_inode != NULL) {
533 isp = smk_of_inode(new_dentry->d_inode); 588 isp = smk_of_inode(new_dentry->d_inode);
534 rc = smk_curacc(isp, MAY_READWRITE); 589 smk_ad_setfield_u_fs_path_dentry(&ad, new_dentry);
590 rc = smk_curacc(isp, MAY_READWRITE, &ad);
535 } 591 }
536
537 return rc; 592 return rc;
538} 593}
539 594
@@ -548,13 +603,15 @@ static int smack_inode_rename(struct inode *old_inode,
548 */ 603 */
549static int smack_inode_permission(struct inode *inode, int mask) 604static int smack_inode_permission(struct inode *inode, int mask)
550{ 605{
606 struct smk_audit_info ad;
551 /* 607 /*
552 * No permission to check. Existence test. Yup, it's there. 608 * No permission to check. Existence test. Yup, it's there.
553 */ 609 */
554 if (mask == 0) 610 if (mask == 0)
555 return 0; 611 return 0;
556 612 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
557 return smk_curacc(smk_of_inode(inode), mask); 613 smk_ad_setfield_u_fs_inode(&ad, inode);
614 return smk_curacc(smk_of_inode(inode), mask, &ad);
558} 615}
559 616
560/** 617/**
@@ -566,13 +623,16 @@ static int smack_inode_permission(struct inode *inode, int mask)
566 */ 623 */
567static int smack_inode_setattr(struct dentry *dentry, struct iattr *iattr) 624static int smack_inode_setattr(struct dentry *dentry, struct iattr *iattr)
568{ 625{
626 struct smk_audit_info ad;
569 /* 627 /*
570 * Need to allow for clearing the setuid bit. 628 * Need to allow for clearing the setuid bit.
571 */ 629 */
572 if (iattr->ia_valid & ATTR_FORCE) 630 if (iattr->ia_valid & ATTR_FORCE)
573 return 0; 631 return 0;
632 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
633 smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
574 634
575 return smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE); 635 return smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad);
576} 636}
577 637
578/** 638/**
@@ -584,7 +644,12 @@ static int smack_inode_setattr(struct dentry *dentry, struct iattr *iattr)
584 */ 644 */
585static int smack_inode_getattr(struct vfsmount *mnt, struct dentry *dentry) 645static int smack_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
586{ 646{
587 return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ); 647 struct smk_audit_info ad;
648
649 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
650 smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
651 smk_ad_setfield_u_fs_path_mnt(&ad, mnt);
652 return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad);
588} 653}
589 654
590/** 655/**
@@ -602,6 +667,7 @@ static int smack_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
602static int smack_inode_setxattr(struct dentry *dentry, const char *name, 667static int smack_inode_setxattr(struct dentry *dentry, const char *name,
603 const void *value, size_t size, int flags) 668 const void *value, size_t size, int flags)
604{ 669{
670 struct smk_audit_info ad;
605 int rc = 0; 671 int rc = 0;
606 672
607 if (strcmp(name, XATTR_NAME_SMACK) == 0 || 673 if (strcmp(name, XATTR_NAME_SMACK) == 0 ||
@@ -619,8 +685,11 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name,
619 } else 685 } else
620 rc = cap_inode_setxattr(dentry, name, value, size, flags); 686 rc = cap_inode_setxattr(dentry, name, value, size, flags);
621 687
688 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
689 smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
690
622 if (rc == 0) 691 if (rc == 0)
623 rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE); 692 rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad);
624 693
625 return rc; 694 return rc;
626} 695}
@@ -672,7 +741,12 @@ static void smack_inode_post_setxattr(struct dentry *dentry, const char *name,
672 */ 741 */
673static int smack_inode_getxattr(struct dentry *dentry, const char *name) 742static int smack_inode_getxattr(struct dentry *dentry, const char *name)
674{ 743{
675 return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ); 744 struct smk_audit_info ad;
745
746 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
747 smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
748
749 return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad);
676} 750}
677 751
678/* 752/*
@@ -686,6 +760,7 @@ static int smack_inode_getxattr(struct dentry *dentry, const char *name)
686 */ 760 */
687static int smack_inode_removexattr(struct dentry *dentry, const char *name) 761static int smack_inode_removexattr(struct dentry *dentry, const char *name)
688{ 762{
763 struct smk_audit_info ad;
689 int rc = 0; 764 int rc = 0;
690 765
691 if (strcmp(name, XATTR_NAME_SMACK) == 0 || 766 if (strcmp(name, XATTR_NAME_SMACK) == 0 ||
@@ -696,8 +771,10 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name)
696 } else 771 } else
697 rc = cap_inode_removexattr(dentry, name); 772 rc = cap_inode_removexattr(dentry, name);
698 773
774 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
775 smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
699 if (rc == 0) 776 if (rc == 0)
700 rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE); 777 rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad);
701 778
702 return rc; 779 return rc;
703} 780}
@@ -856,12 +933,16 @@ static int smack_file_ioctl(struct file *file, unsigned int cmd,
856 unsigned long arg) 933 unsigned long arg)
857{ 934{
858 int rc = 0; 935 int rc = 0;
936 struct smk_audit_info ad;
937
938 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
939 smk_ad_setfield_u_fs_path(&ad, file->f_path);
859 940
860 if (_IOC_DIR(cmd) & _IOC_WRITE) 941 if (_IOC_DIR(cmd) & _IOC_WRITE)
861 rc = smk_curacc(file->f_security, MAY_WRITE); 942 rc = smk_curacc(file->f_security, MAY_WRITE, &ad);
862 943
863 if (rc == 0 && (_IOC_DIR(cmd) & _IOC_READ)) 944 if (rc == 0 && (_IOC_DIR(cmd) & _IOC_READ))
864 rc = smk_curacc(file->f_security, MAY_READ); 945 rc = smk_curacc(file->f_security, MAY_READ, &ad);
865 946
866 return rc; 947 return rc;
867} 948}
@@ -875,7 +956,11 @@ static int smack_file_ioctl(struct file *file, unsigned int cmd,
875 */ 956 */
876static int smack_file_lock(struct file *file, unsigned int cmd) 957static int smack_file_lock(struct file *file, unsigned int cmd)
877{ 958{
878 return smk_curacc(file->f_security, MAY_WRITE); 959 struct smk_audit_info ad;
960
961 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
962 smk_ad_setfield_u_fs_path_dentry(&ad, file->f_path.dentry);
963 return smk_curacc(file->f_security, MAY_WRITE, &ad);
879} 964}
880 965
881/** 966/**
@@ -889,8 +974,12 @@ static int smack_file_lock(struct file *file, unsigned int cmd)
889static int smack_file_fcntl(struct file *file, unsigned int cmd, 974static int smack_file_fcntl(struct file *file, unsigned int cmd,
890 unsigned long arg) 975 unsigned long arg)
891{ 976{
977 struct smk_audit_info ad;
892 int rc; 978 int rc;
893 979
980 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
981 smk_ad_setfield_u_fs_path(&ad, file->f_path);
982
894 switch (cmd) { 983 switch (cmd) {
895 case F_DUPFD: 984 case F_DUPFD:
896 case F_GETFD: 985 case F_GETFD:
@@ -898,7 +987,7 @@ static int smack_file_fcntl(struct file *file, unsigned int cmd,
898 case F_GETLK: 987 case F_GETLK:
899 case F_GETOWN: 988 case F_GETOWN:
900 case F_GETSIG: 989 case F_GETSIG:
901 rc = smk_curacc(file->f_security, MAY_READ); 990 rc = smk_curacc(file->f_security, MAY_READ, &ad);
902 break; 991 break;
903 case F_SETFD: 992 case F_SETFD:
904 case F_SETFL: 993 case F_SETFL:
@@ -906,10 +995,10 @@ static int smack_file_fcntl(struct file *file, unsigned int cmd,
906 case F_SETLKW: 995 case F_SETLKW:
907 case F_SETOWN: 996 case F_SETOWN:
908 case F_SETSIG: 997 case F_SETSIG:
909 rc = smk_curacc(file->f_security, MAY_WRITE); 998 rc = smk_curacc(file->f_security, MAY_WRITE, &ad);
910 break; 999 break;
911 default: 1000 default:
912 rc = smk_curacc(file->f_security, MAY_READWRITE); 1001 rc = smk_curacc(file->f_security, MAY_READWRITE, &ad);
913 } 1002 }
914 1003
915 return rc; 1004 return rc;
@@ -944,14 +1033,21 @@ static int smack_file_send_sigiotask(struct task_struct *tsk,
944{ 1033{
945 struct file *file; 1034 struct file *file;
946 int rc; 1035 int rc;
1036 char *tsp = tsk->cred->security;
1037 struct smk_audit_info ad;
947 1038
948 /* 1039 /*
949 * struct fown_struct is never outside the context of a struct file 1040 * struct fown_struct is never outside the context of a struct file
950 */ 1041 */
951 file = container_of(fown, struct file, f_owner); 1042 file = container_of(fown, struct file, f_owner);
952 rc = smk_access(file->f_security, tsk->cred->security, MAY_WRITE); 1043 /* we don't log here as rc can be overriden */
1044 rc = smk_access(file->f_security, tsp, MAY_WRITE, NULL);
953 if (rc != 0 && has_capability(tsk, CAP_MAC_OVERRIDE)) 1045 if (rc != 0 && has_capability(tsk, CAP_MAC_OVERRIDE))
954 return 0; 1046 rc = 0;
1047
1048 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
1049 smk_ad_setfield_u_tsk(&ad, tsk);
1050 smack_log(file->f_security, tsp, MAY_WRITE, rc, &ad);
955 return rc; 1051 return rc;
956} 1052}
957 1053
@@ -964,7 +1060,10 @@ static int smack_file_send_sigiotask(struct task_struct *tsk,
964static int smack_file_receive(struct file *file) 1060static int smack_file_receive(struct file *file)
965{ 1061{
966 int may = 0; 1062 int may = 0;
1063 struct smk_audit_info ad;
967 1064
1065 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
1066 smk_ad_setfield_u_fs_path(&ad, file->f_path);
968 /* 1067 /*
969 * This code relies on bitmasks. 1068 * This code relies on bitmasks.
970 */ 1069 */
@@ -973,7 +1072,7 @@ static int smack_file_receive(struct file *file)
973 if (file->f_mode & FMODE_WRITE) 1072 if (file->f_mode & FMODE_WRITE)
974 may |= MAY_WRITE; 1073 may |= MAY_WRITE;
975 1074
976 return smk_curacc(file->f_security, may); 1075 return smk_curacc(file->f_security, may, &ad);
977} 1076}
978 1077
979/* 1078/*
@@ -1053,6 +1152,22 @@ static int smack_kernel_create_files_as(struct cred *new,
1053} 1152}
1054 1153
1055/** 1154/**
1155 * smk_curacc_on_task - helper to log task related access
1156 * @p: the task object
1157 * @access : the access requested
1158 *
1159 * Return 0 if access is permitted
1160 */
1161static int smk_curacc_on_task(struct task_struct *p, int access)
1162{
1163 struct smk_audit_info ad;
1164
1165 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
1166 smk_ad_setfield_u_tsk(&ad, p);
1167 return smk_curacc(task_security(p), access, &ad);
1168}
1169
1170/**
1056 * smack_task_setpgid - Smack check on setting pgid 1171 * smack_task_setpgid - Smack check on setting pgid
1057 * @p: the task object 1172 * @p: the task object
1058 * @pgid: unused 1173 * @pgid: unused
@@ -1061,7 +1176,7 @@ static int smack_kernel_create_files_as(struct cred *new,
1061 */ 1176 */
1062static int smack_task_setpgid(struct task_struct *p, pid_t pgid) 1177static int smack_task_setpgid(struct task_struct *p, pid_t pgid)
1063{ 1178{
1064 return smk_curacc(task_security(p), MAY_WRITE); 1179 return smk_curacc_on_task(p, MAY_WRITE);
1065} 1180}
1066 1181
1067/** 1182/**
@@ -1072,7 +1187,7 @@ static int smack_task_setpgid(struct task_struct *p, pid_t pgid)
1072 */ 1187 */
1073static int smack_task_getpgid(struct task_struct *p) 1188static int smack_task_getpgid(struct task_struct *p)
1074{ 1189{
1075 return smk_curacc(task_security(p), MAY_READ); 1190 return smk_curacc_on_task(p, MAY_READ);
1076} 1191}
1077 1192
1078/** 1193/**
@@ -1083,7 +1198,7 @@ static int smack_task_getpgid(struct task_struct *p)
1083 */ 1198 */
1084static int smack_task_getsid(struct task_struct *p) 1199static int smack_task_getsid(struct task_struct *p)
1085{ 1200{
1086 return smk_curacc(task_security(p), MAY_READ); 1201 return smk_curacc_on_task(p, MAY_READ);
1087} 1202}
1088 1203
1089/** 1204/**
@@ -1111,7 +1226,7 @@ static int smack_task_setnice(struct task_struct *p, int nice)
1111 1226
1112 rc = cap_task_setnice(p, nice); 1227 rc = cap_task_setnice(p, nice);
1113 if (rc == 0) 1228 if (rc == 0)
1114 rc = smk_curacc(task_security(p), MAY_WRITE); 1229 rc = smk_curacc_on_task(p, MAY_WRITE);
1115 return rc; 1230 return rc;
1116} 1231}
1117 1232
@@ -1128,7 +1243,7 @@ static int smack_task_setioprio(struct task_struct *p, int ioprio)
1128 1243
1129 rc = cap_task_setioprio(p, ioprio); 1244 rc = cap_task_setioprio(p, ioprio);
1130 if (rc == 0) 1245 if (rc == 0)
1131 rc = smk_curacc(task_security(p), MAY_WRITE); 1246 rc = smk_curacc_on_task(p, MAY_WRITE);
1132 return rc; 1247 return rc;
1133} 1248}
1134 1249
@@ -1140,7 +1255,7 @@ static int smack_task_setioprio(struct task_struct *p, int ioprio)
1140 */ 1255 */
1141static int smack_task_getioprio(struct task_struct *p) 1256static int smack_task_getioprio(struct task_struct *p)
1142{ 1257{
1143 return smk_curacc(task_security(p), MAY_READ); 1258 return smk_curacc_on_task(p, MAY_READ);
1144} 1259}
1145 1260
1146/** 1261/**
@@ -1158,7 +1273,7 @@ static int smack_task_setscheduler(struct task_struct *p, int policy,
1158 1273
1159 rc = cap_task_setscheduler(p, policy, lp); 1274 rc = cap_task_setscheduler(p, policy, lp);
1160 if (rc == 0) 1275 if (rc == 0)
1161 rc = smk_curacc(task_security(p), MAY_WRITE); 1276 rc = smk_curacc_on_task(p, MAY_WRITE);
1162 return rc; 1277 return rc;
1163} 1278}
1164 1279
@@ -1170,7 +1285,7 @@ static int smack_task_setscheduler(struct task_struct *p, int policy,
1170 */ 1285 */
1171static int smack_task_getscheduler(struct task_struct *p) 1286static int smack_task_getscheduler(struct task_struct *p)
1172{ 1287{
1173 return smk_curacc(task_security(p), MAY_READ); 1288 return smk_curacc_on_task(p, MAY_READ);
1174} 1289}
1175 1290
1176/** 1291/**
@@ -1181,7 +1296,7 @@ static int smack_task_getscheduler(struct task_struct *p)
1181 */ 1296 */
1182static int smack_task_movememory(struct task_struct *p) 1297static int smack_task_movememory(struct task_struct *p)
1183{ 1298{
1184 return smk_curacc(task_security(p), MAY_WRITE); 1299 return smk_curacc_on_task(p, MAY_WRITE);
1185} 1300}
1186 1301
1187/** 1302/**
@@ -1199,18 +1314,23 @@ static int smack_task_movememory(struct task_struct *p)
1199static int smack_task_kill(struct task_struct *p, struct siginfo *info, 1314static int smack_task_kill(struct task_struct *p, struct siginfo *info,
1200 int sig, u32 secid) 1315 int sig, u32 secid)
1201{ 1316{
1317 struct smk_audit_info ad;
1318
1319 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
1320 smk_ad_setfield_u_tsk(&ad, p);
1202 /* 1321 /*
1203 * Sending a signal requires that the sender 1322 * Sending a signal requires that the sender
1204 * can write the receiver. 1323 * can write the receiver.
1205 */ 1324 */
1206 if (secid == 0) 1325 if (secid == 0)
1207 return smk_curacc(task_security(p), MAY_WRITE); 1326 return smk_curacc(task_security(p), MAY_WRITE, &ad);
1208 /* 1327 /*
1209 * If the secid isn't 0 we're dealing with some USB IO 1328 * If the secid isn't 0 we're dealing with some USB IO
1210 * specific behavior. This is not clean. For one thing 1329 * specific behavior. This is not clean. For one thing
1211 * we can't take privilege into account. 1330 * we can't take privilege into account.
1212 */ 1331 */
1213 return smk_access(smack_from_secid(secid), task_security(p), MAY_WRITE); 1332 return smk_access(smack_from_secid(secid), task_security(p),
1333 MAY_WRITE, &ad);
1214} 1334}
1215 1335
1216/** 1336/**
@@ -1221,11 +1341,15 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info,
1221 */ 1341 */
1222static int smack_task_wait(struct task_struct *p) 1342static int smack_task_wait(struct task_struct *p)
1223{ 1343{
1344 struct smk_audit_info ad;
1345 char *sp = current_security();
1346 char *tsp = task_security(p);
1224 int rc; 1347 int rc;
1225 1348
1226 rc = smk_access(current_security(), task_security(p), MAY_WRITE); 1349 /* we don't log here, we can be overriden */
1350 rc = smk_access(sp, tsp, MAY_WRITE, NULL);
1227 if (rc == 0) 1351 if (rc == 0)
1228 return 0; 1352 goto out_log;
1229 1353
1230 /* 1354 /*
1231 * Allow the operation to succeed if either task 1355 * Allow the operation to succeed if either task
@@ -1239,8 +1363,12 @@ static int smack_task_wait(struct task_struct *p)
1239 * the smack value. 1363 * the smack value.
1240 */ 1364 */
1241 if (capable(CAP_MAC_OVERRIDE) || has_capability(p, CAP_MAC_OVERRIDE)) 1365 if (capable(CAP_MAC_OVERRIDE) || has_capability(p, CAP_MAC_OVERRIDE))
1242 return 0; 1366 rc = 0;
1243 1367 /* we log only if we didn't get overriden */
1368 out_log:
1369 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
1370 smk_ad_setfield_u_tsk(&ad, p);
1371 smack_log(sp, tsp, MAY_WRITE, rc, &ad);
1244 return rc; 1372 return rc;
1245} 1373}
1246 1374
@@ -1456,12 +1584,19 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap)
1456 int sk_lbl; 1584 int sk_lbl;
1457 char *hostsp; 1585 char *hostsp;
1458 struct socket_smack *ssp = sk->sk_security; 1586 struct socket_smack *ssp = sk->sk_security;
1587 struct smk_audit_info ad;
1459 1588
1460 rcu_read_lock(); 1589 rcu_read_lock();
1461 hostsp = smack_host_label(sap); 1590 hostsp = smack_host_label(sap);
1462 if (hostsp != NULL) { 1591 if (hostsp != NULL) {
1463 sk_lbl = SMACK_UNLABELED_SOCKET; 1592 sk_lbl = SMACK_UNLABELED_SOCKET;
1464 rc = smk_access(ssp->smk_out, hostsp, MAY_WRITE); 1593#ifdef CONFIG_AUDIT
1594 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET);
1595 ad.a.u.net.family = sap->sin_family;
1596 ad.a.u.net.dport = sap->sin_port;
1597 ad.a.u.net.v4info.daddr = sap->sin_addr.s_addr;
1598#endif
1599 rc = smk_access(ssp->smk_out, hostsp, MAY_WRITE, &ad);
1465 } else { 1600 } else {
1466 sk_lbl = SMACK_CIPSO_SOCKET; 1601 sk_lbl = SMACK_CIPSO_SOCKET;
1467 rc = 0; 1602 rc = 0;
@@ -1657,6 +1792,25 @@ static void smack_shm_free_security(struct shmid_kernel *shp)
1657} 1792}
1658 1793
1659/** 1794/**
1795 * smk_curacc_shm : check if current has access on shm
1796 * @shp : the object
1797 * @access : access requested
1798 *
1799 * Returns 0 if current has the requested access, error code otherwise
1800 */
1801static int smk_curacc_shm(struct shmid_kernel *shp, int access)
1802{
1803 char *ssp = smack_of_shm(shp);
1804 struct smk_audit_info ad;
1805
1806#ifdef CONFIG_AUDIT
1807 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC);
1808 ad.a.u.ipc_id = shp->shm_perm.id;
1809#endif
1810 return smk_curacc(ssp, access, &ad);
1811}
1812
1813/**
1660 * smack_shm_associate - Smack access check for shm 1814 * smack_shm_associate - Smack access check for shm
1661 * @shp: the object 1815 * @shp: the object
1662 * @shmflg: access requested 1816 * @shmflg: access requested
@@ -1665,11 +1819,10 @@ static void smack_shm_free_security(struct shmid_kernel *shp)
1665 */ 1819 */
1666static int smack_shm_associate(struct shmid_kernel *shp, int shmflg) 1820static int smack_shm_associate(struct shmid_kernel *shp, int shmflg)
1667{ 1821{
1668 char *ssp = smack_of_shm(shp);
1669 int may; 1822 int may;
1670 1823
1671 may = smack_flags_to_may(shmflg); 1824 may = smack_flags_to_may(shmflg);
1672 return smk_curacc(ssp, may); 1825 return smk_curacc_shm(shp, may);
1673} 1826}
1674 1827
1675/** 1828/**
@@ -1681,7 +1834,6 @@ static int smack_shm_associate(struct shmid_kernel *shp, int shmflg)
1681 */ 1834 */
1682static int smack_shm_shmctl(struct shmid_kernel *shp, int cmd) 1835static int smack_shm_shmctl(struct shmid_kernel *shp, int cmd)
1683{ 1836{
1684 char *ssp;
1685 int may; 1837 int may;
1686 1838
1687 switch (cmd) { 1839 switch (cmd) {
@@ -1704,9 +1856,7 @@ static int smack_shm_shmctl(struct shmid_kernel *shp, int cmd)
1704 default: 1856 default:
1705 return -EINVAL; 1857 return -EINVAL;
1706 } 1858 }
1707 1859 return smk_curacc_shm(shp, may);
1708 ssp = smack_of_shm(shp);
1709 return smk_curacc(ssp, may);
1710} 1860}
1711 1861
1712/** 1862/**
@@ -1720,11 +1870,10 @@ static int smack_shm_shmctl(struct shmid_kernel *shp, int cmd)
1720static int smack_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr, 1870static int smack_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr,
1721 int shmflg) 1871 int shmflg)
1722{ 1872{
1723 char *ssp = smack_of_shm(shp);
1724 int may; 1873 int may;
1725 1874
1726 may = smack_flags_to_may(shmflg); 1875 may = smack_flags_to_may(shmflg);
1727 return smk_curacc(ssp, may); 1876 return smk_curacc_shm(shp, may);
1728} 1877}
1729 1878
1730/** 1879/**
@@ -1766,6 +1915,25 @@ static void smack_sem_free_security(struct sem_array *sma)
1766} 1915}
1767 1916
1768/** 1917/**
1918 * smk_curacc_sem : check if current has access on sem
1919 * @sma : the object
1920 * @access : access requested
1921 *
1922 * Returns 0 if current has the requested access, error code otherwise
1923 */
1924static int smk_curacc_sem(struct sem_array *sma, int access)
1925{
1926 char *ssp = smack_of_sem(sma);
1927 struct smk_audit_info ad;
1928
1929#ifdef CONFIG_AUDIT
1930 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC);
1931 ad.a.u.ipc_id = sma->sem_perm.id;
1932#endif
1933 return smk_curacc(ssp, access, &ad);
1934}
1935
1936/**
1769 * smack_sem_associate - Smack access check for sem 1937 * smack_sem_associate - Smack access check for sem
1770 * @sma: the object 1938 * @sma: the object
1771 * @semflg: access requested 1939 * @semflg: access requested
@@ -1774,11 +1942,10 @@ static void smack_sem_free_security(struct sem_array *sma)
1774 */ 1942 */
1775static int smack_sem_associate(struct sem_array *sma, int semflg) 1943static int smack_sem_associate(struct sem_array *sma, int semflg)
1776{ 1944{
1777 char *ssp = smack_of_sem(sma);
1778 int may; 1945 int may;
1779 1946
1780 may = smack_flags_to_may(semflg); 1947 may = smack_flags_to_may(semflg);
1781 return smk_curacc(ssp, may); 1948 return smk_curacc_sem(sma, may);
1782} 1949}
1783 1950
1784/** 1951/**
@@ -1790,7 +1957,6 @@ static int smack_sem_associate(struct sem_array *sma, int semflg)
1790 */ 1957 */
1791static int smack_sem_semctl(struct sem_array *sma, int cmd) 1958static int smack_sem_semctl(struct sem_array *sma, int cmd)
1792{ 1959{
1793 char *ssp;
1794 int may; 1960 int may;
1795 1961
1796 switch (cmd) { 1962 switch (cmd) {
@@ -1819,8 +1985,7 @@ static int smack_sem_semctl(struct sem_array *sma, int cmd)
1819 return -EINVAL; 1985 return -EINVAL;
1820 } 1986 }
1821 1987
1822 ssp = smack_of_sem(sma); 1988 return smk_curacc_sem(sma, may);
1823 return smk_curacc(ssp, may);
1824} 1989}
1825 1990
1826/** 1991/**
@@ -1837,9 +2002,7 @@ static int smack_sem_semctl(struct sem_array *sma, int cmd)
1837static int smack_sem_semop(struct sem_array *sma, struct sembuf *sops, 2002static int smack_sem_semop(struct sem_array *sma, struct sembuf *sops,
1838 unsigned nsops, int alter) 2003 unsigned nsops, int alter)
1839{ 2004{
1840 char *ssp = smack_of_sem(sma); 2005 return smk_curacc_sem(sma, MAY_READWRITE);
1841
1842 return smk_curacc(ssp, MAY_READWRITE);
1843} 2006}
1844 2007
1845/** 2008/**
@@ -1881,6 +2044,25 @@ static char *smack_of_msq(struct msg_queue *msq)
1881} 2044}
1882 2045
1883/** 2046/**
2047 * smk_curacc_msq : helper to check if current has access on msq
2048 * @msq : the msq
2049 * @access : access requested
2050 *
2051 * return 0 if current has access, error otherwise
2052 */
2053static int smk_curacc_msq(struct msg_queue *msq, int access)
2054{
2055 char *msp = smack_of_msq(msq);
2056 struct smk_audit_info ad;
2057
2058#ifdef CONFIG_AUDIT
2059 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC);
2060 ad.a.u.ipc_id = msq->q_perm.id;
2061#endif
2062 return smk_curacc(msp, access, &ad);
2063}
2064
2065/**
1884 * smack_msg_queue_associate - Smack access check for msg_queue 2066 * smack_msg_queue_associate - Smack access check for msg_queue
1885 * @msq: the object 2067 * @msq: the object
1886 * @msqflg: access requested 2068 * @msqflg: access requested
@@ -1889,11 +2071,10 @@ static char *smack_of_msq(struct msg_queue *msq)
1889 */ 2071 */
1890static int smack_msg_queue_associate(struct msg_queue *msq, int msqflg) 2072static int smack_msg_queue_associate(struct msg_queue *msq, int msqflg)
1891{ 2073{
1892 char *msp = smack_of_msq(msq);
1893 int may; 2074 int may;
1894 2075
1895 may = smack_flags_to_may(msqflg); 2076 may = smack_flags_to_may(msqflg);
1896 return smk_curacc(msp, may); 2077 return smk_curacc_msq(msq, may);
1897} 2078}
1898 2079
1899/** 2080/**
@@ -1905,7 +2086,6 @@ static int smack_msg_queue_associate(struct msg_queue *msq, int msqflg)
1905 */ 2086 */
1906static int smack_msg_queue_msgctl(struct msg_queue *msq, int cmd) 2087static int smack_msg_queue_msgctl(struct msg_queue *msq, int cmd)
1907{ 2088{
1908 char *msp;
1909 int may; 2089 int may;
1910 2090
1911 switch (cmd) { 2091 switch (cmd) {
@@ -1927,8 +2107,7 @@ static int smack_msg_queue_msgctl(struct msg_queue *msq, int cmd)
1927 return -EINVAL; 2107 return -EINVAL;
1928 } 2108 }
1929 2109
1930 msp = smack_of_msq(msq); 2110 return smk_curacc_msq(msq, may);
1931 return smk_curacc(msp, may);
1932} 2111}
1933 2112
1934/** 2113/**
@@ -1942,11 +2121,10 @@ static int smack_msg_queue_msgctl(struct msg_queue *msq, int cmd)
1942static int smack_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg, 2121static int smack_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg,
1943 int msqflg) 2122 int msqflg)
1944{ 2123{
1945 char *msp = smack_of_msq(msq); 2124 int may;
1946 int rc;
1947 2125
1948 rc = smack_flags_to_may(msqflg); 2126 may = smack_flags_to_may(msqflg);
1949 return smk_curacc(msp, rc); 2127 return smk_curacc_msq(msq, may);
1950} 2128}
1951 2129
1952/** 2130/**
@@ -1962,9 +2140,7 @@ static int smack_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg,
1962static int smack_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg, 2140static int smack_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg,
1963 struct task_struct *target, long type, int mode) 2141 struct task_struct *target, long type, int mode)
1964{ 2142{
1965 char *msp = smack_of_msq(msq); 2143 return smk_curacc_msq(msq, MAY_READWRITE);
1966
1967 return smk_curacc(msp, MAY_READWRITE);
1968} 2144}
1969 2145
1970/** 2146/**
@@ -1977,10 +2153,14 @@ static int smack_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg,
1977static int smack_ipc_permission(struct kern_ipc_perm *ipp, short flag) 2153static int smack_ipc_permission(struct kern_ipc_perm *ipp, short flag)
1978{ 2154{
1979 char *isp = ipp->security; 2155 char *isp = ipp->security;
1980 int may; 2156 int may = smack_flags_to_may(flag);
2157 struct smk_audit_info ad;
1981 2158
1982 may = smack_flags_to_may(flag); 2159#ifdef CONFIG_AUDIT
1983 return smk_curacc(isp, may); 2160 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC);
2161 ad.a.u.ipc_id = ipp->id;
2162#endif
2163 return smk_curacc(isp, may, &ad);
1984} 2164}
1985 2165
1986/** 2166/**
@@ -2239,8 +2419,12 @@ static int smack_unix_stream_connect(struct socket *sock,
2239{ 2419{
2240 struct inode *sp = SOCK_INODE(sock); 2420 struct inode *sp = SOCK_INODE(sock);
2241 struct inode *op = SOCK_INODE(other); 2421 struct inode *op = SOCK_INODE(other);
2422 struct smk_audit_info ad;
2242 2423
2243 return smk_access(smk_of_inode(sp), smk_of_inode(op), MAY_READWRITE); 2424 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET);
2425 smk_ad_setfield_u_net_sk(&ad, other->sk);
2426 return smk_access(smk_of_inode(sp), smk_of_inode(op),
2427 MAY_READWRITE, &ad);
2244} 2428}
2245 2429
2246/** 2430/**
@@ -2255,8 +2439,11 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other)
2255{ 2439{
2256 struct inode *sp = SOCK_INODE(sock); 2440 struct inode *sp = SOCK_INODE(sock);
2257 struct inode *op = SOCK_INODE(other); 2441 struct inode *op = SOCK_INODE(other);
2442 struct smk_audit_info ad;
2258 2443
2259 return smk_access(smk_of_inode(sp), smk_of_inode(op), MAY_WRITE); 2444 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET);
2445 smk_ad_setfield_u_net_sk(&ad, other->sk);
2446 return smk_access(smk_of_inode(sp), smk_of_inode(op), MAY_WRITE, &ad);
2260} 2447}
2261 2448
2262/** 2449/**
@@ -2371,7 +2558,7 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
2371 char smack[SMK_LABELLEN]; 2558 char smack[SMK_LABELLEN];
2372 char *csp; 2559 char *csp;
2373 int rc; 2560 int rc;
2374 2561 struct smk_audit_info ad;
2375 if (sk->sk_family != PF_INET && sk->sk_family != PF_INET6) 2562 if (sk->sk_family != PF_INET && sk->sk_family != PF_INET6)
2376 return 0; 2563 return 0;
2377 2564
@@ -2389,13 +2576,19 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
2389 2576
2390 netlbl_secattr_destroy(&secattr); 2577 netlbl_secattr_destroy(&secattr);
2391 2578
2579#ifdef CONFIG_AUDIT
2580 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET);
2581 ad.a.u.net.family = sk->sk_family;
2582 ad.a.u.net.netif = skb->iif;
2583 ipv4_skb_to_auditdata(skb, &ad.a, NULL);
2584#endif
2392 /* 2585 /*
2393 * Receiving a packet requires that the other end 2586 * Receiving a packet requires that the other end
2394 * be able to write here. Read access is not required. 2587 * be able to write here. Read access is not required.
2395 * This is the simplist possible security model 2588 * This is the simplist possible security model
2396 * for networking. 2589 * for networking.
2397 */ 2590 */
2398 rc = smk_access(csp, ssp->smk_in, MAY_WRITE); 2591 rc = smk_access(csp, ssp->smk_in, MAY_WRITE, &ad);
2399 if (rc != 0) 2592 if (rc != 0)
2400 netlbl_skbuff_err(skb, rc, 0); 2593 netlbl_skbuff_err(skb, rc, 0);
2401 return rc; 2594 return rc;
@@ -2524,6 +2717,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
2524 struct iphdr *hdr; 2717 struct iphdr *hdr;
2525 char smack[SMK_LABELLEN]; 2718 char smack[SMK_LABELLEN];
2526 int rc; 2719 int rc;
2720 struct smk_audit_info ad;
2527 2721
2528 /* handle mapped IPv4 packets arriving via IPv6 sockets */ 2722 /* handle mapped IPv4 packets arriving via IPv6 sockets */
2529 if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP)) 2723 if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP))
@@ -2537,11 +2731,17 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
2537 strncpy(smack, smack_known_huh.smk_known, SMK_MAXLEN); 2731 strncpy(smack, smack_known_huh.smk_known, SMK_MAXLEN);
2538 netlbl_secattr_destroy(&secattr); 2732 netlbl_secattr_destroy(&secattr);
2539 2733
2734#ifdef CONFIG_AUDIT
2735 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET);
2736 ad.a.u.net.family = family;
2737 ad.a.u.net.netif = skb->iif;
2738 ipv4_skb_to_auditdata(skb, &ad.a, NULL);
2739#endif
2540 /* 2740 /*
2541 * Receiving a packet requires that the other end be able to write 2741 * Receiving a packet requires that the other end be able to write
2542 * here. Read access is not required. 2742 * here. Read access is not required.
2543 */ 2743 */
2544 rc = smk_access(smack, ssp->smk_in, MAY_WRITE); 2744 rc = smk_access(smack, ssp->smk_in, MAY_WRITE, &ad);
2545 if (rc != 0) 2745 if (rc != 0)
2546 return rc; 2746 return rc;
2547 2747
@@ -2643,6 +2843,7 @@ static int smack_key_permission(key_ref_t key_ref,
2643 const struct cred *cred, key_perm_t perm) 2843 const struct cred *cred, key_perm_t perm)
2644{ 2844{
2645 struct key *keyp; 2845 struct key *keyp;
2846 struct smk_audit_info ad;
2646 2847
2647 keyp = key_ref_to_ptr(key_ref); 2848 keyp = key_ref_to_ptr(key_ref);
2648 if (keyp == NULL) 2849 if (keyp == NULL)
@@ -2658,8 +2859,13 @@ static int smack_key_permission(key_ref_t key_ref,
2658 */ 2859 */
2659 if (cred->security == NULL) 2860 if (cred->security == NULL)
2660 return -EACCES; 2861 return -EACCES;
2661 2862#ifdef CONFIG_AUDIT
2662 return smk_access(cred->security, keyp->security, MAY_READWRITE); 2863 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_KEY);
2864 ad.a.u.key_struct.key = keyp->serial;
2865 ad.a.u.key_struct.key_desc = keyp->description;
2866#endif
2867 return smk_access(cred->security, keyp->security,
2868 MAY_READWRITE, &ad);
2663} 2869}
2664#endif /* CONFIG_KEYS */ 2870#endif /* CONFIG_KEYS */
2665 2871
@@ -2828,15 +3034,7 @@ struct security_operations smack_ops = {
2828 3034
2829 .ptrace_may_access = smack_ptrace_may_access, 3035 .ptrace_may_access = smack_ptrace_may_access,
2830 .ptrace_traceme = smack_ptrace_traceme, 3036 .ptrace_traceme = smack_ptrace_traceme,
2831 .capget = cap_capget,
2832 .capset = cap_capset,
2833 .capable = cap_capable,
2834 .syslog = smack_syslog, 3037 .syslog = smack_syslog,
2835 .settime = cap_settime,
2836 .vm_enough_memory = cap_vm_enough_memory,
2837
2838 .bprm_set_creds = cap_bprm_set_creds,
2839 .bprm_secureexec = cap_bprm_secureexec,
2840 3038
2841 .sb_alloc_security = smack_sb_alloc_security, 3039 .sb_alloc_security = smack_sb_alloc_security,
2842 .sb_free_security = smack_sb_free_security, 3040 .sb_free_security = smack_sb_free_security,
@@ -2860,8 +3058,6 @@ struct security_operations smack_ops = {
2860 .inode_post_setxattr = smack_inode_post_setxattr, 3058 .inode_post_setxattr = smack_inode_post_setxattr,
2861 .inode_getxattr = smack_inode_getxattr, 3059 .inode_getxattr = smack_inode_getxattr,
2862 .inode_removexattr = smack_inode_removexattr, 3060 .inode_removexattr = smack_inode_removexattr,
2863 .inode_need_killpriv = cap_inode_need_killpriv,
2864 .inode_killpriv = cap_inode_killpriv,
2865 .inode_getsecurity = smack_inode_getsecurity, 3061 .inode_getsecurity = smack_inode_getsecurity,
2866 .inode_setsecurity = smack_inode_setsecurity, 3062 .inode_setsecurity = smack_inode_setsecurity,
2867 .inode_listsecurity = smack_inode_listsecurity, 3063 .inode_listsecurity = smack_inode_listsecurity,
@@ -2882,7 +3078,6 @@ struct security_operations smack_ops = {
2882 .cred_commit = smack_cred_commit, 3078 .cred_commit = smack_cred_commit,
2883 .kernel_act_as = smack_kernel_act_as, 3079 .kernel_act_as = smack_kernel_act_as,
2884 .kernel_create_files_as = smack_kernel_create_files_as, 3080 .kernel_create_files_as = smack_kernel_create_files_as,
2885 .task_fix_setuid = cap_task_fix_setuid,
2886 .task_setpgid = smack_task_setpgid, 3081 .task_setpgid = smack_task_setpgid,
2887 .task_getpgid = smack_task_getpgid, 3082 .task_getpgid = smack_task_getpgid,
2888 .task_getsid = smack_task_getsid, 3083 .task_getsid = smack_task_getsid,
@@ -2896,7 +3091,6 @@ struct security_operations smack_ops = {
2896 .task_kill = smack_task_kill, 3091 .task_kill = smack_task_kill,
2897 .task_wait = smack_task_wait, 3092 .task_wait = smack_task_wait,
2898 .task_to_inode = smack_task_to_inode, 3093 .task_to_inode = smack_task_to_inode,
2899 .task_prctl = cap_task_prctl,
2900 3094
2901 .ipc_permission = smack_ipc_permission, 3095 .ipc_permission = smack_ipc_permission,
2902 .ipc_getsecid = smack_ipc_getsecid, 3096 .ipc_getsecid = smack_ipc_getsecid,
@@ -2923,9 +3117,6 @@ struct security_operations smack_ops = {
2923 .sem_semctl = smack_sem_semctl, 3117 .sem_semctl = smack_sem_semctl,
2924 .sem_semop = smack_sem_semop, 3118 .sem_semop = smack_sem_semop,
2925 3119
2926 .netlink_send = cap_netlink_send,
2927 .netlink_recv = cap_netlink_recv,
2928
2929 .d_instantiate = smack_d_instantiate, 3120 .d_instantiate = smack_d_instantiate,
2930 3121
2931 .getprocattr = smack_getprocattr, 3122 .getprocattr = smack_getprocattr,
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index e03a7e19c73b..8d3c2a051c7b 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -41,6 +41,7 @@ enum smk_inos {
41 SMK_AMBIENT = 7, /* internet ambient label */ 41 SMK_AMBIENT = 7, /* internet ambient label */
42 SMK_NETLBLADDR = 8, /* single label hosts */ 42 SMK_NETLBLADDR = 8, /* single label hosts */
43 SMK_ONLYCAP = 9, /* the only "capable" label */ 43 SMK_ONLYCAP = 9, /* the only "capable" label */
44 SMK_LOGGING = 10, /* logging */
44}; 45};
45 46
46/* 47/*
@@ -775,7 +776,7 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
775 struct sockaddr_in newname; 776 struct sockaddr_in newname;
776 char smack[SMK_LABELLEN]; 777 char smack[SMK_LABELLEN];
777 char *sp; 778 char *sp;
778 char data[SMK_NETLBLADDRMAX]; 779 char data[SMK_NETLBLADDRMAX + 1];
779 char *host = (char *)&newname.sin_addr.s_addr; 780 char *host = (char *)&newname.sin_addr.s_addr;
780 int rc; 781 int rc;
781 struct netlbl_audit audit_info; 782 struct netlbl_audit audit_info;
@@ -1192,6 +1193,69 @@ static const struct file_operations smk_onlycap_ops = {
1192}; 1193};
1193 1194
1194/** 1195/**
1196 * smk_read_logging - read() for /smack/logging
1197 * @filp: file pointer, not actually used
1198 * @buf: where to put the result
1199 * @cn: maximum to send along
1200 * @ppos: where to start
1201 *
1202 * Returns number of bytes read or error code, as appropriate
1203 */
1204static ssize_t smk_read_logging(struct file *filp, char __user *buf,
1205 size_t count, loff_t *ppos)
1206{
1207 char temp[32];
1208 ssize_t rc;
1209
1210 if (*ppos != 0)
1211 return 0;
1212
1213 sprintf(temp, "%d\n", log_policy);
1214 rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp));
1215 return rc;
1216}
1217
1218/**
1219 * smk_write_logging - write() for /smack/logging
1220 * @file: file pointer, not actually used
1221 * @buf: where to get the data from
1222 * @count: bytes sent
1223 * @ppos: where to start
1224 *
1225 * Returns number of bytes written or error code, as appropriate
1226 */
1227static ssize_t smk_write_logging(struct file *file, const char __user *buf,
1228 size_t count, loff_t *ppos)
1229{
1230 char temp[32];
1231 int i;
1232
1233 if (!capable(CAP_MAC_ADMIN))
1234 return -EPERM;
1235
1236 if (count >= sizeof(temp) || count == 0)
1237 return -EINVAL;
1238
1239 if (copy_from_user(temp, buf, count) != 0)
1240 return -EFAULT;
1241
1242 temp[count] = '\0';
1243
1244 if (sscanf(temp, "%d", &i) != 1)
1245 return -EINVAL;
1246 if (i < 0 || i > 3)
1247 return -EINVAL;
1248 log_policy = i;
1249 return count;
1250}
1251
1252
1253
1254static const struct file_operations smk_logging_ops = {
1255 .read = smk_read_logging,
1256 .write = smk_write_logging,
1257};
1258/**
1195 * smk_fill_super - fill the /smackfs superblock 1259 * smk_fill_super - fill the /smackfs superblock
1196 * @sb: the empty superblock 1260 * @sb: the empty superblock
1197 * @data: unused 1261 * @data: unused
@@ -1221,6 +1285,8 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent)
1221 {"netlabel", &smk_netlbladdr_ops, S_IRUGO|S_IWUSR}, 1285 {"netlabel", &smk_netlbladdr_ops, S_IRUGO|S_IWUSR},
1222 [SMK_ONLYCAP] = 1286 [SMK_ONLYCAP] =
1223 {"onlycap", &smk_onlycap_ops, S_IRUGO|S_IWUSR}, 1287 {"onlycap", &smk_onlycap_ops, S_IRUGO|S_IWUSR},
1288 [SMK_LOGGING] =
1289 {"logging", &smk_logging_ops, S_IRUGO|S_IWUSR},
1224 /* last one */ {""} 1290 /* last one */ {""}
1225 }; 1291 };
1226 1292
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c
index ddfb9cccf468..fdd1f4b8c448 100644
--- a/security/tomoyo/common.c
+++ b/security/tomoyo/common.c
@@ -28,7 +28,13 @@ static const char *tomoyo_mode_2[4] = {
28 "disabled", "enabled", "enabled", "enabled" 28 "disabled", "enabled", "enabled", "enabled"
29}; 29};
30 30
31/* Table for profile. */ 31/*
32 * tomoyo_control_array is a static data which contains
33 *
34 * (1) functionality name used by /sys/kernel/security/tomoyo/profile .
35 * (2) initial values for "struct tomoyo_profile".
36 * (3) max values for "struct tomoyo_profile".
37 */
32static struct { 38static struct {
33 const char *keyword; 39 const char *keyword;
34 unsigned int current_value; 40 unsigned int current_value;
@@ -39,7 +45,13 @@ static struct {
39 [TOMOYO_VERBOSE] = { "TOMOYO_VERBOSE", 1, 1 }, 45 [TOMOYO_VERBOSE] = { "TOMOYO_VERBOSE", 1, 1 },
40}; 46};
41 47
42/* Profile table. Memory is allocated as needed. */ 48/*
49 * tomoyo_profile is a structure which is used for holding the mode of access
50 * controls. TOMOYO has 4 modes: disabled, learning, permissive, enforcing.
51 * An administrator can define up to 256 profiles.
52 * The ->profile of "struct tomoyo_domain_info" is used for remembering
53 * the profile's number (0 - 255) assigned to that domain.
54 */
43static struct tomoyo_profile { 55static struct tomoyo_profile {
44 unsigned int value[TOMOYO_MAX_CONTROL_INDEX]; 56 unsigned int value[TOMOYO_MAX_CONTROL_INDEX];
45 const struct tomoyo_path_info *comment; 57 const struct tomoyo_path_info *comment;
@@ -428,7 +440,6 @@ void tomoyo_fill_path_info(struct tomoyo_path_info *ptr)
428 const char *name = ptr->name; 440 const char *name = ptr->name;
429 const int len = strlen(name); 441 const int len = strlen(name);
430 442
431 ptr->total_len = len;
432 ptr->const_len = tomoyo_const_part_length(name); 443 ptr->const_len = tomoyo_const_part_length(name);
433 ptr->is_dir = len && (name[len - 1] == '/'); 444 ptr->is_dir = len && (name[len - 1] == '/');
434 ptr->is_patterned = (ptr->const_len < len); 445 ptr->is_patterned = (ptr->const_len < len);
@@ -866,7 +877,6 @@ static struct tomoyo_profile *tomoyo_find_or_assign_new_profile(const unsigned
866 877
867 if (profile >= TOMOYO_MAX_PROFILES) 878 if (profile >= TOMOYO_MAX_PROFILES)
868 return NULL; 879 return NULL;
869 /***** EXCLUSIVE SECTION START *****/
870 mutex_lock(&lock); 880 mutex_lock(&lock);
871 ptr = tomoyo_profile_ptr[profile]; 881 ptr = tomoyo_profile_ptr[profile];
872 if (ptr) 882 if (ptr)
@@ -880,7 +890,6 @@ static struct tomoyo_profile *tomoyo_find_or_assign_new_profile(const unsigned
880 tomoyo_profile_ptr[profile] = ptr; 890 tomoyo_profile_ptr[profile] = ptr;
881 ok: 891 ok:
882 mutex_unlock(&lock); 892 mutex_unlock(&lock);
883 /***** EXCLUSIVE SECTION END *****/
884 return ptr; 893 return ptr;
885} 894}
886 895
@@ -1009,7 +1018,19 @@ static int tomoyo_read_profile(struct tomoyo_io_buffer *head)
1009 return 0; 1018 return 0;
1010} 1019}
1011 1020
1012/* Structure for policy manager. */ 1021/*
1022 * tomoyo_policy_manager_entry is a structure which is used for holding list of
1023 * domainnames or programs which are permitted to modify configuration via
1024 * /sys/kernel/security/tomoyo/ interface.
1025 * It has following fields.
1026 *
1027 * (1) "list" which is linked to tomoyo_policy_manager_list .
1028 * (2) "manager" is a domainname or a program's pathname.
1029 * (3) "is_domain" is a bool which is true if "manager" is a domainname, false
1030 * otherwise.
1031 * (4) "is_deleted" is a bool which is true if marked as deleted, false
1032 * otherwise.
1033 */
1013struct tomoyo_policy_manager_entry { 1034struct tomoyo_policy_manager_entry {
1014 struct list_head list; 1035 struct list_head list;
1015 /* A path to program or a domainname. */ 1036 /* A path to program or a domainname. */
@@ -1018,7 +1039,36 @@ struct tomoyo_policy_manager_entry {
1018 bool is_deleted; /* True if this entry is deleted. */ 1039 bool is_deleted; /* True if this entry is deleted. */
1019}; 1040};
1020 1041
1021/* The list for "struct tomoyo_policy_manager_entry". */ 1042/*
1043 * tomoyo_policy_manager_list is used for holding list of domainnames or
1044 * programs which are permitted to modify configuration via
1045 * /sys/kernel/security/tomoyo/ interface.
1046 *
1047 * An entry is added by
1048 *
1049 * # echo '<kernel> /sbin/mingetty /bin/login /bin/bash' > \
1050 * /sys/kernel/security/tomoyo/manager
1051 * (if you want to specify by a domainname)
1052 *
1053 * or
1054 *
1055 * # echo '/usr/lib/ccs/editpolicy' > /sys/kernel/security/tomoyo/manager
1056 * (if you want to specify by a program's location)
1057 *
1058 * and is deleted by
1059 *
1060 * # echo 'delete <kernel> /sbin/mingetty /bin/login /bin/bash' > \
1061 * /sys/kernel/security/tomoyo/manager
1062 *
1063 * or
1064 *
1065 * # echo 'delete /usr/lib/ccs/editpolicy' > \
1066 * /sys/kernel/security/tomoyo/manager
1067 *
1068 * and all entries are retrieved by
1069 *
1070 * # cat /sys/kernel/security/tomoyo/manager
1071 */
1022static LIST_HEAD(tomoyo_policy_manager_list); 1072static LIST_HEAD(tomoyo_policy_manager_list);
1023static DECLARE_RWSEM(tomoyo_policy_manager_list_lock); 1073static DECLARE_RWSEM(tomoyo_policy_manager_list_lock);
1024 1074
@@ -1050,7 +1100,6 @@ static int tomoyo_update_manager_entry(const char *manager,
1050 saved_manager = tomoyo_save_name(manager); 1100 saved_manager = tomoyo_save_name(manager);
1051 if (!saved_manager) 1101 if (!saved_manager)
1052 return -ENOMEM; 1102 return -ENOMEM;
1053 /***** EXCLUSIVE SECTION START *****/
1054 down_write(&tomoyo_policy_manager_list_lock); 1103 down_write(&tomoyo_policy_manager_list_lock);
1055 list_for_each_entry(ptr, &tomoyo_policy_manager_list, list) { 1104 list_for_each_entry(ptr, &tomoyo_policy_manager_list, list) {
1056 if (ptr->manager != saved_manager) 1105 if (ptr->manager != saved_manager)
@@ -1072,7 +1121,6 @@ static int tomoyo_update_manager_entry(const char *manager,
1072 error = 0; 1121 error = 0;
1073 out: 1122 out:
1074 up_write(&tomoyo_policy_manager_list_lock); 1123 up_write(&tomoyo_policy_manager_list_lock);
1075 /***** EXCLUSIVE SECTION END *****/
1076 return error; 1124 return error;
1077} 1125}
1078 1126
@@ -1117,10 +1165,9 @@ static int tomoyo_read_manager_policy(struct tomoyo_io_buffer *head)
1117 list); 1165 list);
1118 if (ptr->is_deleted) 1166 if (ptr->is_deleted)
1119 continue; 1167 continue;
1120 if (!tomoyo_io_printf(head, "%s\n", ptr->manager->name)) { 1168 done = tomoyo_io_printf(head, "%s\n", ptr->manager->name);
1121 done = false; 1169 if (!done)
1122 break; 1170 break;
1123 }
1124 } 1171 }
1125 up_read(&tomoyo_policy_manager_list_lock); 1172 up_read(&tomoyo_policy_manager_list_lock);
1126 head->read_eof = done; 1173 head->read_eof = done;
@@ -1197,13 +1244,11 @@ static bool tomoyo_is_select_one(struct tomoyo_io_buffer *head,
1197 1244
1198 if (sscanf(data, "pid=%u", &pid) == 1) { 1245 if (sscanf(data, "pid=%u", &pid) == 1) {
1199 struct task_struct *p; 1246 struct task_struct *p;
1200 /***** CRITICAL SECTION START *****/
1201 read_lock(&tasklist_lock); 1247 read_lock(&tasklist_lock);
1202 p = find_task_by_vpid(pid); 1248 p = find_task_by_vpid(pid);
1203 if (p) 1249 if (p)
1204 domain = tomoyo_real_domain(p); 1250 domain = tomoyo_real_domain(p);
1205 read_unlock(&tasklist_lock); 1251 read_unlock(&tasklist_lock);
1206 /***** CRITICAL SECTION END *****/
1207 } else if (!strncmp(data, "domain=", 7)) { 1252 } else if (!strncmp(data, "domain=", 7)) {
1208 if (tomoyo_is_domain_def(data + 7)) { 1253 if (tomoyo_is_domain_def(data + 7)) {
1209 down_read(&tomoyo_domain_list_lock); 1254 down_read(&tomoyo_domain_list_lock);
@@ -1447,15 +1492,14 @@ static int tomoyo_read_domain_policy(struct tomoyo_io_buffer *head)
1447 TOMOYO_DOMAIN_FLAGS_IGNORE_GLOBAL_ALLOW_READ) 1492 TOMOYO_DOMAIN_FLAGS_IGNORE_GLOBAL_ALLOW_READ)
1448 ignore_global_allow_read 1493 ignore_global_allow_read
1449 = TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ "\n"; 1494 = TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ "\n";
1450 if (!tomoyo_io_printf(head, 1495 done = tomoyo_io_printf(head, "%s\n" TOMOYO_KEYWORD_USE_PROFILE
1451 "%s\n" TOMOYO_KEYWORD_USE_PROFILE "%u\n" 1496 "%u\n%s%s%s\n",
1452 "%s%s%s\n", domain->domainname->name, 1497 domain->domainname->name,
1453 domain->profile, quota_exceeded, 1498 domain->profile, quota_exceeded,
1454 transition_failed, 1499 transition_failed,
1455 ignore_global_allow_read)) { 1500 ignore_global_allow_read);
1456 done = false; 1501 if (!done)
1457 break; 1502 break;
1458 }
1459 head->read_step = 2; 1503 head->read_step = 2;
1460acl_loop: 1504acl_loop:
1461 if (head->read_step == 3) 1505 if (head->read_step == 3)
@@ -1463,24 +1507,22 @@ acl_loop:
1463 /* Print ACL entries in the domain. */ 1507 /* Print ACL entries in the domain. */
1464 down_read(&tomoyo_domain_acl_info_list_lock); 1508 down_read(&tomoyo_domain_acl_info_list_lock);
1465 list_for_each_cookie(apos, head->read_var2, 1509 list_for_each_cookie(apos, head->read_var2,
1466 &domain->acl_info_list) { 1510 &domain->acl_info_list) {
1467 struct tomoyo_acl_info *ptr 1511 struct tomoyo_acl_info *ptr
1468 = list_entry(apos, struct tomoyo_acl_info, 1512 = list_entry(apos, struct tomoyo_acl_info,
1469 list); 1513 list);
1470 if (!tomoyo_print_entry(head, ptr)) { 1514 done = tomoyo_print_entry(head, ptr);
1471 done = false; 1515 if (!done)
1472 break; 1516 break;
1473 }
1474 } 1517 }
1475 up_read(&tomoyo_domain_acl_info_list_lock); 1518 up_read(&tomoyo_domain_acl_info_list_lock);
1476 if (!done) 1519 if (!done)
1477 break; 1520 break;
1478 head->read_step = 3; 1521 head->read_step = 3;
1479tail_mark: 1522tail_mark:
1480 if (!tomoyo_io_printf(head, "\n")) { 1523 done = tomoyo_io_printf(head, "\n");
1481 done = false; 1524 if (!done)
1482 break; 1525 break;
1483 }
1484 head->read_step = 1; 1526 head->read_step = 1;
1485 if (head->read_single_domain) 1527 if (head->read_single_domain)
1486 break; 1528 break;
@@ -1550,11 +1592,10 @@ static int tomoyo_read_domain_profile(struct tomoyo_io_buffer *head)
1550 domain = list_entry(pos, struct tomoyo_domain_info, list); 1592 domain = list_entry(pos, struct tomoyo_domain_info, list);
1551 if (domain->is_deleted) 1593 if (domain->is_deleted)
1552 continue; 1594 continue;
1553 if (!tomoyo_io_printf(head, "%u %s\n", domain->profile, 1595 done = tomoyo_io_printf(head, "%u %s\n", domain->profile,
1554 domain->domainname->name)) { 1596 domain->domainname->name);
1555 done = false; 1597 if (!done)
1556 break; 1598 break;
1557 }
1558 } 1599 }
1559 up_read(&tomoyo_domain_list_lock); 1600 up_read(&tomoyo_domain_list_lock);
1560 head->read_eof = done; 1601 head->read_eof = done;
@@ -1594,13 +1635,11 @@ static int tomoyo_read_pid(struct tomoyo_io_buffer *head)
1594 const int pid = head->read_step; 1635 const int pid = head->read_step;
1595 struct task_struct *p; 1636 struct task_struct *p;
1596 struct tomoyo_domain_info *domain = NULL; 1637 struct tomoyo_domain_info *domain = NULL;
1597 /***** CRITICAL SECTION START *****/
1598 read_lock(&tasklist_lock); 1638 read_lock(&tasklist_lock);
1599 p = find_task_by_vpid(pid); 1639 p = find_task_by_vpid(pid);
1600 if (p) 1640 if (p)
1601 domain = tomoyo_real_domain(p); 1641 domain = tomoyo_real_domain(p);
1602 read_unlock(&tasklist_lock); 1642 read_unlock(&tasklist_lock);
1603 /***** CRITICAL SECTION END *****/
1604 if (domain) 1643 if (domain)
1605 tomoyo_io_printf(head, "%d %u %s", pid, domain->profile, 1644 tomoyo_io_printf(head, "%d %u %s", pid, domain->profile,
1606 domain->domainname->name); 1645 domain->domainname->name);
@@ -2138,7 +2177,13 @@ static ssize_t tomoyo_write(struct file *file, const char __user *buf,
2138 return tomoyo_write_control(file, buf, count); 2177 return tomoyo_write_control(file, buf, count);
2139} 2178}
2140 2179
2141/* Operations for /sys/kernel/security/tomoyo/ interface. */ 2180/*
2181 * tomoyo_operations is a "struct file_operations" which is used for handling
2182 * /sys/kernel/security/tomoyo/ interface.
2183 *
2184 * Some files under /sys/kernel/security/tomoyo/ directory accept open(O_RDWR).
2185 * See tomoyo_io_buffer for internals.
2186 */
2142static const struct file_operations tomoyo_operations = { 2187static const struct file_operations tomoyo_operations = {
2143 .open = tomoyo_open, 2188 .open = tomoyo_open,
2144 .release = tomoyo_release, 2189 .release = tomoyo_release,
diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h
index 678f4ff16aa4..6d6ba09af457 100644
--- a/security/tomoyo/common.h
+++ b/security/tomoyo/common.h
@@ -26,16 +26,43 @@
26struct dentry; 26struct dentry;
27struct vfsmount; 27struct vfsmount;
28 28
29/* Temporary buffer for holding pathnames. */ 29/*
30 * tomoyo_page_buffer is a structure which is used for holding a pathname
31 * obtained from "struct dentry" and "struct vfsmount" pair.
32 * As of now, it is 4096 bytes. If users complain that 4096 bytes is too small
33 * (because TOMOYO escapes non ASCII printable characters using \ooo format),
34 * we will make the buffer larger.
35 */
30struct tomoyo_page_buffer { 36struct tomoyo_page_buffer {
31 char buffer[4096]; 37 char buffer[4096];
32}; 38};
33 39
34/* Structure for holding a token. */ 40/*
41 * tomoyo_path_info is a structure which is used for holding a string data
42 * used by TOMOYO.
43 * This structure has several fields for supporting pattern matching.
44 *
45 * (1) "name" is the '\0' terminated string data.
46 * (2) "hash" is full_name_hash(name, strlen(name)).
47 * This allows tomoyo_pathcmp() to compare by hash before actually compare
48 * using strcmp().
49 * (3) "const_len" is the length of the initial segment of "name" which
50 * consists entirely of non wildcard characters. In other words, the length
51 * which we can compare two strings using strncmp().
52 * (4) "is_dir" is a bool which is true if "name" ends with "/",
53 * false otherwise.
54 * TOMOYO distinguishes directory and non-directory. A directory ends with
55 * "/" and non-directory does not end with "/".
56 * (5) "is_patterned" is a bool which is true if "name" contains wildcard
57 * characters, false otherwise. This allows TOMOYO to use "hash" and
58 * strcmp() for string comparison if "is_patterned" is false.
59 * (6) "depth" is calculated using the number of "/" characters in "name".
60 * This allows TOMOYO to avoid comparing two pathnames which never match
61 * (e.g. whether "/var/www/html/index.html" matches "/tmp/sh-thd-\$").
62 */
35struct tomoyo_path_info { 63struct tomoyo_path_info {
36 const char *name; 64 const char *name;
37 u32 hash; /* = full_name_hash(name, strlen(name)) */ 65 u32 hash; /* = full_name_hash(name, strlen(name)) */
38 u16 total_len; /* = strlen(name) */
39 u16 const_len; /* = tomoyo_const_part_length(name) */ 66 u16 const_len; /* = tomoyo_const_part_length(name) */
40 bool is_dir; /* = tomoyo_strendswith(name, "/") */ 67 bool is_dir; /* = tomoyo_strendswith(name, "/") */
41 bool is_patterned; /* = tomoyo_path_contains_pattern(name) */ 68 bool is_patterned; /* = tomoyo_path_contains_pattern(name) */
@@ -51,7 +78,20 @@ struct tomoyo_path_info {
51 */ 78 */
52#define TOMOYO_MAX_PATHNAME_LEN 4000 79#define TOMOYO_MAX_PATHNAME_LEN 4000
53 80
54/* Structure for holding requested pathname. */ 81/*
82 * tomoyo_path_info_with_data is a structure which is used for holding a
83 * pathname obtained from "struct dentry" and "struct vfsmount" pair.
84 *
85 * "struct tomoyo_path_info_with_data" consists of "struct tomoyo_path_info"
86 * and buffer for the pathname, while "struct tomoyo_page_buffer" consists of
87 * buffer for the pathname only.
88 *
89 * "struct tomoyo_path_info_with_data" is intended to allow TOMOYO to release
90 * both "struct tomoyo_path_info" and buffer for the pathname by single kfree()
91 * so that we don't need to return two pointers to the caller. If the caller
92 * puts "struct tomoyo_path_info" on stack memory, we will be able to remove
93 * "struct tomoyo_path_info_with_data".
94 */
55struct tomoyo_path_info_with_data { 95struct tomoyo_path_info_with_data {
56 /* Keep "head" first, for this pointer is passed to tomoyo_free(). */ 96 /* Keep "head" first, for this pointer is passed to tomoyo_free(). */
57 struct tomoyo_path_info head; 97 struct tomoyo_path_info head;
@@ -61,7 +101,15 @@ struct tomoyo_path_info_with_data {
61}; 101};
62 102
63/* 103/*
64 * Common header for holding ACL entries. 104 * tomoyo_acl_info is a structure which is used for holding
105 *
106 * (1) "list" which is linked to the ->acl_info_list of
107 * "struct tomoyo_domain_info"
108 * (2) "type" which tells
109 * (a) type & 0x7F : type of the entry (either
110 * "struct tomoyo_single_path_acl_record" or
111 * "struct tomoyo_double_path_acl_record")
112 * (b) type & 0x80 : whether the entry is marked as "deleted".
65 * 113 *
66 * Packing "struct tomoyo_acl_info" allows 114 * Packing "struct tomoyo_acl_info" allows
67 * "struct tomoyo_single_path_acl_record" to embed "u16" and 115 * "struct tomoyo_single_path_acl_record" to embed "u16" and
@@ -81,7 +129,28 @@ struct tomoyo_acl_info {
81/* This ACL entry is deleted. */ 129/* This ACL entry is deleted. */
82#define TOMOYO_ACL_DELETED 0x80 130#define TOMOYO_ACL_DELETED 0x80
83 131
84/* Structure for domain information. */ 132/*
133 * tomoyo_domain_info is a structure which is used for holding permissions
134 * (e.g. "allow_read /lib/libc-2.5.so") given to each domain.
135 * It has following fields.
136 *
137 * (1) "list" which is linked to tomoyo_domain_list .
138 * (2) "acl_info_list" which is linked to "struct tomoyo_acl_info".
139 * (3) "domainname" which holds the name of the domain.
140 * (4) "profile" which remembers profile number assigned to this domain.
141 * (5) "is_deleted" is a bool which is true if this domain is marked as
142 * "deleted", false otherwise.
143 * (6) "quota_warned" is a bool which is used for suppressing warning message
144 * when learning mode learned too much entries.
145 * (7) "flags" which remembers this domain's attributes.
146 *
147 * A domain's lifecycle is an analogy of files on / directory.
148 * Multiple domains with the same domainname cannot be created (as with
149 * creating files with the same filename fails with -EEXIST).
150 * If a process reached a domain, that process can reside in that domain after
151 * that domain is marked as "deleted" (as with a process can access an already
152 * open()ed file after that file was unlink()ed).
153 */
85struct tomoyo_domain_info { 154struct tomoyo_domain_info {
86 struct list_head list; 155 struct list_head list;
87 struct list_head acl_info_list; 156 struct list_head acl_info_list;
@@ -108,10 +177,18 @@ struct tomoyo_domain_info {
108#define TOMOYO_DOMAIN_FLAGS_TRANSITION_FAILED 2 177#define TOMOYO_DOMAIN_FLAGS_TRANSITION_FAILED 2
109 178
110/* 179/*
111 * Structure for "allow_read/write", "allow_execute", "allow_read", 180 * tomoyo_single_path_acl_record is a structure which is used for holding an
112 * "allow_write", "allow_create", "allow_unlink", "allow_mkdir", "allow_rmdir", 181 * entry with one pathname operation (e.g. open(), mkdir()).
113 * "allow_mkfifo", "allow_mksock", "allow_mkblock", "allow_mkchar", 182 * It has following fields.
114 * "allow_truncate", "allow_symlink" and "allow_rewrite" directive. 183 *
184 * (1) "head" which is a "struct tomoyo_acl_info".
185 * (2) "perm" which is a bitmask of permitted operations.
186 * (3) "filename" is the pathname.
187 *
188 * Directives held by this structure are "allow_read/write", "allow_execute",
189 * "allow_read", "allow_write", "allow_create", "allow_unlink", "allow_mkdir",
190 * "allow_rmdir", "allow_mkfifo", "allow_mksock", "allow_mkblock",
191 * "allow_mkchar", "allow_truncate", "allow_symlink" and "allow_rewrite".
115 */ 192 */
116struct tomoyo_single_path_acl_record { 193struct tomoyo_single_path_acl_record {
117 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_SINGLE_PATH_ACL */ 194 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_SINGLE_PATH_ACL */
@@ -120,7 +197,18 @@ struct tomoyo_single_path_acl_record {
120 const struct tomoyo_path_info *filename; 197 const struct tomoyo_path_info *filename;
121}; 198};
122 199
123/* Structure for "allow_rename" and "allow_link" directive. */ 200/*
201 * tomoyo_double_path_acl_record is a structure which is used for holding an
202 * entry with two pathnames operation (i.e. link() and rename()).
203 * It has following fields.
204 *
205 * (1) "head" which is a "struct tomoyo_acl_info".
206 * (2) "perm" which is a bitmask of permitted operations.
207 * (3) "filename1" is the source/old pathname.
208 * (4) "filename2" is the destination/new pathname.
209 *
210 * Directives held by this structure are "allow_rename" and "allow_link".
211 */
124struct tomoyo_double_path_acl_record { 212struct tomoyo_double_path_acl_record {
125 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_DOUBLE_PATH_ACL */ 213 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_DOUBLE_PATH_ACL */
126 u8 perm; 214 u8 perm;
@@ -153,7 +241,29 @@ struct tomoyo_double_path_acl_record {
153#define TOMOYO_VERBOSE 2 241#define TOMOYO_VERBOSE 2
154#define TOMOYO_MAX_CONTROL_INDEX 3 242#define TOMOYO_MAX_CONTROL_INDEX 3
155 243
156/* Structure for reading/writing policy via securityfs interfaces. */ 244/*
245 * tomoyo_io_buffer is a structure which is used for reading and modifying
246 * configuration via /sys/kernel/security/tomoyo/ interface.
247 * It has many fields. ->read_var1 , ->read_var2 , ->write_var1 are used as
248 * cursors.
249 *
250 * Since the content of /sys/kernel/security/tomoyo/domain_policy is a list of
251 * "struct tomoyo_domain_info" entries and each "struct tomoyo_domain_info"
252 * entry has a list of "struct tomoyo_acl_info", we need two cursors when
253 * reading (one is for traversing tomoyo_domain_list and the other is for
254 * traversing "struct tomoyo_acl_info"->acl_info_list ).
255 *
256 * If a line written to /sys/kernel/security/tomoyo/domain_policy starts with
257 * "select ", TOMOYO seeks the cursor ->read_var1 and ->write_var1 to the
258 * domain with the domainname specified by the rest of that line (NULL is set
259 * if seek failed).
260 * If a line written to /sys/kernel/security/tomoyo/domain_policy starts with
261 * "delete ", TOMOYO deletes an entry or a domain specified by the rest of that
262 * line (->write_var1 is set to NULL if a domain was deleted).
263 * If a line written to /sys/kernel/security/tomoyo/domain_policy starts with
264 * neither "select " nor "delete ", an entry or a domain specified by that line
265 * is appended.
266 */
157struct tomoyo_io_buffer { 267struct tomoyo_io_buffer {
158 int (*read) (struct tomoyo_io_buffer *); 268 int (*read) (struct tomoyo_io_buffer *);
159 int (*write) (struct tomoyo_io_buffer *); 269 int (*write) (struct tomoyo_io_buffer *);
diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c
index 2d6748741a26..1d8b16960576 100644
--- a/security/tomoyo/domain.c
+++ b/security/tomoyo/domain.c
@@ -19,11 +19,63 @@
19/* The initial domain. */ 19/* The initial domain. */
20struct tomoyo_domain_info tomoyo_kernel_domain; 20struct tomoyo_domain_info tomoyo_kernel_domain;
21 21
22/* The list for "struct tomoyo_domain_info". */ 22/*
23 * tomoyo_domain_list is used for holding list of domains.
24 * The ->acl_info_list of "struct tomoyo_domain_info" is used for holding
25 * permissions (e.g. "allow_read /lib/libc-2.5.so") given to each domain.
26 *
27 * An entry is added by
28 *
29 * # ( echo "<kernel>"; echo "allow_execute /sbin/init" ) > \
30 * /sys/kernel/security/tomoyo/domain_policy
31 *
32 * and is deleted by
33 *
34 * # ( echo "<kernel>"; echo "delete allow_execute /sbin/init" ) > \
35 * /sys/kernel/security/tomoyo/domain_policy
36 *
37 * and all entries are retrieved by
38 *
39 * # cat /sys/kernel/security/tomoyo/domain_policy
40 *
41 * A domain is added by
42 *
43 * # echo "<kernel>" > /sys/kernel/security/tomoyo/domain_policy
44 *
45 * and is deleted by
46 *
47 * # echo "delete <kernel>" > /sys/kernel/security/tomoyo/domain_policy
48 *
49 * and all domains are retrieved by
50 *
51 * # grep '^<kernel>' /sys/kernel/security/tomoyo/domain_policy
52 *
53 * Normally, a domainname is monotonically getting longer because a domainname
54 * which the process will belong to if an execve() operation succeeds is
55 * defined as a concatenation of "current domainname" + "pathname passed to
56 * execve()".
57 * See tomoyo_domain_initializer_list and tomoyo_domain_keeper_list for
58 * exceptions.
59 */
23LIST_HEAD(tomoyo_domain_list); 60LIST_HEAD(tomoyo_domain_list);
24DECLARE_RWSEM(tomoyo_domain_list_lock); 61DECLARE_RWSEM(tomoyo_domain_list_lock);
25 62
26/* Structure for "initialize_domain" and "no_initialize_domain" keyword. */ 63/*
64 * tomoyo_domain_initializer_entry is a structure which is used for holding
65 * "initialize_domain" and "no_initialize_domain" entries.
66 * It has following fields.
67 *
68 * (1) "list" which is linked to tomoyo_domain_initializer_list .
69 * (2) "domainname" which is "a domainname" or "the last component of a
70 * domainname". This field is NULL if "from" clause is not specified.
71 * (3) "program" which is a program's pathname.
72 * (4) "is_deleted" is a bool which is true if marked as deleted, false
73 * otherwise.
74 * (5) "is_not" is a bool which is true if "no_initialize_domain", false
75 * otherwise.
76 * (6) "is_last_name" is a bool which is true if "domainname" is "the last
77 * component of a domainname", false otherwise.
78 */
27struct tomoyo_domain_initializer_entry { 79struct tomoyo_domain_initializer_entry {
28 struct list_head list; 80 struct list_head list;
29 const struct tomoyo_path_info *domainname; /* This may be NULL */ 81 const struct tomoyo_path_info *domainname; /* This may be NULL */
@@ -34,7 +86,23 @@ struct tomoyo_domain_initializer_entry {
34 bool is_last_name; 86 bool is_last_name;
35}; 87};
36 88
37/* Structure for "keep_domain" and "no_keep_domain" keyword. */ 89/*
90 * tomoyo_domain_keeper_entry is a structure which is used for holding
91 * "keep_domain" and "no_keep_domain" entries.
92 * It has following fields.
93 *
94 * (1) "list" which is linked to tomoyo_domain_keeper_list .
95 * (2) "domainname" which is "a domainname" or "the last component of a
96 * domainname".
97 * (3) "program" which is a program's pathname.
98 * This field is NULL if "from" clause is not specified.
99 * (4) "is_deleted" is a bool which is true if marked as deleted, false
100 * otherwise.
101 * (5) "is_not" is a bool which is true if "no_initialize_domain", false
102 * otherwise.
103 * (6) "is_last_name" is a bool which is true if "domainname" is "the last
104 * component of a domainname", false otherwise.
105 */
38struct tomoyo_domain_keeper_entry { 106struct tomoyo_domain_keeper_entry {
39 struct list_head list; 107 struct list_head list;
40 const struct tomoyo_path_info *domainname; 108 const struct tomoyo_path_info *domainname;
@@ -45,7 +113,16 @@ struct tomoyo_domain_keeper_entry {
45 bool is_last_name; 113 bool is_last_name;
46}; 114};
47 115
48/* Structure for "alias" keyword. */ 116/*
117 * tomoyo_alias_entry is a structure which is used for holding "alias" entries.
118 * It has following fields.
119 *
120 * (1) "list" which is linked to tomoyo_alias_list .
121 * (2) "original_name" which is a dereferenced pathname.
122 * (3) "aliased_name" which is a symlink's pathname.
123 * (4) "is_deleted" is a bool which is true if marked as deleted, false
124 * otherwise.
125 */
49struct tomoyo_alias_entry { 126struct tomoyo_alias_entry {
50 struct list_head list; 127 struct list_head list;
51 const struct tomoyo_path_info *original_name; 128 const struct tomoyo_path_info *original_name;
@@ -67,14 +144,12 @@ void tomoyo_set_domain_flag(struct tomoyo_domain_info *domain,
67{ 144{
68 /* We need to serialize because this is bitfield operation. */ 145 /* We need to serialize because this is bitfield operation. */
69 static DEFINE_SPINLOCK(lock); 146 static DEFINE_SPINLOCK(lock);
70 /***** CRITICAL SECTION START *****/
71 spin_lock(&lock); 147 spin_lock(&lock);
72 if (!is_delete) 148 if (!is_delete)
73 domain->flags |= flags; 149 domain->flags |= flags;
74 else 150 else
75 domain->flags &= ~flags; 151 domain->flags &= ~flags;
76 spin_unlock(&lock); 152 spin_unlock(&lock);
77 /***** CRITICAL SECTION END *****/
78} 153}
79 154
80/** 155/**
@@ -94,7 +169,42 @@ const char *tomoyo_get_last_name(const struct tomoyo_domain_info *domain)
94 return cp0; 169 return cp0;
95} 170}
96 171
97/* The list for "struct tomoyo_domain_initializer_entry". */ 172/*
173 * tomoyo_domain_initializer_list is used for holding list of programs which
174 * triggers reinitialization of domainname. Normally, a domainname is
175 * monotonically getting longer. But sometimes, we restart daemon programs.
176 * It would be convenient for us that "a daemon started upon system boot" and
177 * "the daemon restarted from console" belong to the same domain. Thus, TOMOYO
178 * provides a way to shorten domainnames.
179 *
180 * An entry is added by
181 *
182 * # echo 'initialize_domain /usr/sbin/httpd' > \
183 * /sys/kernel/security/tomoyo/exception_policy
184 *
185 * and is deleted by
186 *
187 * # echo 'delete initialize_domain /usr/sbin/httpd' > \
188 * /sys/kernel/security/tomoyo/exception_policy
189 *
190 * and all entries are retrieved by
191 *
192 * # grep ^initialize_domain /sys/kernel/security/tomoyo/exception_policy
193 *
194 * In the example above, /usr/sbin/httpd will belong to
195 * "<kernel> /usr/sbin/httpd" domain.
196 *
197 * You may specify a domainname using "from" keyword.
198 * "initialize_domain /usr/sbin/httpd from <kernel> /etc/rc.d/init.d/httpd"
199 * will cause "/usr/sbin/httpd" executed from "<kernel> /etc/rc.d/init.d/httpd"
200 * domain to belong to "<kernel> /usr/sbin/httpd" domain.
201 *
202 * You may add "no_" prefix to "initialize_domain".
203 * "initialize_domain /usr/sbin/httpd" and
204 * "no_initialize_domain /usr/sbin/httpd from <kernel> /etc/rc.d/init.d/httpd"
205 * will cause "/usr/sbin/httpd" to belong to "<kernel> /usr/sbin/httpd" domain
206 * unless executed from "<kernel> /etc/rc.d/init.d/httpd" domain.
207 */
98static LIST_HEAD(tomoyo_domain_initializer_list); 208static LIST_HEAD(tomoyo_domain_initializer_list);
99static DECLARE_RWSEM(tomoyo_domain_initializer_list_lock); 209static DECLARE_RWSEM(tomoyo_domain_initializer_list_lock);
100 210
@@ -135,7 +245,6 @@ static int tomoyo_update_domain_initializer_entry(const char *domainname,
135 saved_program = tomoyo_save_name(program); 245 saved_program = tomoyo_save_name(program);
136 if (!saved_program) 246 if (!saved_program)
137 return -ENOMEM; 247 return -ENOMEM;
138 /***** EXCLUSIVE SECTION START *****/
139 down_write(&tomoyo_domain_initializer_list_lock); 248 down_write(&tomoyo_domain_initializer_list_lock);
140 list_for_each_entry(ptr, &tomoyo_domain_initializer_list, list) { 249 list_for_each_entry(ptr, &tomoyo_domain_initializer_list, list) {
141 if (ptr->is_not != is_not || 250 if (ptr->is_not != is_not ||
@@ -161,7 +270,6 @@ static int tomoyo_update_domain_initializer_entry(const char *domainname,
161 error = 0; 270 error = 0;
162 out: 271 out:
163 up_write(&tomoyo_domain_initializer_list_lock); 272 up_write(&tomoyo_domain_initializer_list_lock);
164 /***** EXCLUSIVE SECTION END *****/
165 return error; 273 return error;
166} 274}
167 275
@@ -193,13 +301,12 @@ bool tomoyo_read_domain_initializer_policy(struct tomoyo_io_buffer *head)
193 from = " from "; 301 from = " from ";
194 domain = ptr->domainname->name; 302 domain = ptr->domainname->name;
195 } 303 }
196 if (!tomoyo_io_printf(head, 304 done = tomoyo_io_printf(head,
197 "%s" TOMOYO_KEYWORD_INITIALIZE_DOMAIN 305 "%s" TOMOYO_KEYWORD_INITIALIZE_DOMAIN
198 "%s%s%s\n", no, ptr->program->name, from, 306 "%s%s%s\n", no, ptr->program->name,
199 domain)) { 307 from, domain);
200 done = false; 308 if (!done)
201 break; 309 break;
202 }
203 } 310 }
204 up_read(&tomoyo_domain_initializer_list_lock); 311 up_read(&tomoyo_domain_initializer_list_lock);
205 return done; 312 return done;
@@ -273,7 +380,44 @@ static bool tomoyo_is_domain_initializer(const struct tomoyo_path_info *
273 return flag; 380 return flag;
274} 381}
275 382
276/* The list for "struct tomoyo_domain_keeper_entry". */ 383/*
384 * tomoyo_domain_keeper_list is used for holding list of domainnames which
385 * suppresses domain transition. Normally, a domainname is monotonically
386 * getting longer. But sometimes, we want to suppress domain transition.
387 * It would be convenient for us that programs executed from a login session
388 * belong to the same domain. Thus, TOMOYO provides a way to suppress domain
389 * transition.
390 *
391 * An entry is added by
392 *
393 * # echo 'keep_domain <kernel> /usr/sbin/sshd /bin/bash' > \
394 * /sys/kernel/security/tomoyo/exception_policy
395 *
396 * and is deleted by
397 *
398 * # echo 'delete keep_domain <kernel> /usr/sbin/sshd /bin/bash' > \
399 * /sys/kernel/security/tomoyo/exception_policy
400 *
401 * and all entries are retrieved by
402 *
403 * # grep ^keep_domain /sys/kernel/security/tomoyo/exception_policy
404 *
405 * In the example above, any process which belongs to
406 * "<kernel> /usr/sbin/sshd /bin/bash" domain will remain in that domain,
407 * unless explicitly specified by "initialize_domain" or "no_keep_domain".
408 *
409 * You may specify a program using "from" keyword.
410 * "keep_domain /bin/pwd from <kernel> /usr/sbin/sshd /bin/bash"
411 * will cause "/bin/pwd" executed from "<kernel> /usr/sbin/sshd /bin/bash"
412 * domain to remain in "<kernel> /usr/sbin/sshd /bin/bash" domain.
413 *
414 * You may add "no_" prefix to "keep_domain".
415 * "keep_domain <kernel> /usr/sbin/sshd /bin/bash" and
416 * "no_keep_domain /usr/bin/passwd from <kernel> /usr/sbin/sshd /bin/bash" will
417 * cause "/usr/bin/passwd" to belong to
418 * "<kernel> /usr/sbin/sshd /bin/bash /usr/bin/passwd" domain, unless
419 * explicitly specified by "initialize_domain".
420 */
277static LIST_HEAD(tomoyo_domain_keeper_list); 421static LIST_HEAD(tomoyo_domain_keeper_list);
278static DECLARE_RWSEM(tomoyo_domain_keeper_list_lock); 422static DECLARE_RWSEM(tomoyo_domain_keeper_list_lock);
279 423
@@ -296,7 +440,6 @@ static int tomoyo_update_domain_keeper_entry(const char *domainname,
296 struct tomoyo_domain_keeper_entry *ptr; 440 struct tomoyo_domain_keeper_entry *ptr;
297 const struct tomoyo_path_info *saved_domainname; 441 const struct tomoyo_path_info *saved_domainname;
298 const struct tomoyo_path_info *saved_program = NULL; 442 const struct tomoyo_path_info *saved_program = NULL;
299 static DEFINE_MUTEX(lock);
300 int error = -ENOMEM; 443 int error = -ENOMEM;
301 bool is_last_name = false; 444 bool is_last_name = false;
302 445
@@ -315,7 +458,6 @@ static int tomoyo_update_domain_keeper_entry(const char *domainname,
315 saved_domainname = tomoyo_save_name(domainname); 458 saved_domainname = tomoyo_save_name(domainname);
316 if (!saved_domainname) 459 if (!saved_domainname)
317 return -ENOMEM; 460 return -ENOMEM;
318 /***** EXCLUSIVE SECTION START *****/
319 down_write(&tomoyo_domain_keeper_list_lock); 461 down_write(&tomoyo_domain_keeper_list_lock);
320 list_for_each_entry(ptr, &tomoyo_domain_keeper_list, list) { 462 list_for_each_entry(ptr, &tomoyo_domain_keeper_list, list) {
321 if (ptr->is_not != is_not || 463 if (ptr->is_not != is_not ||
@@ -341,7 +483,6 @@ static int tomoyo_update_domain_keeper_entry(const char *domainname,
341 error = 0; 483 error = 0;
342 out: 484 out:
343 up_write(&tomoyo_domain_keeper_list_lock); 485 up_write(&tomoyo_domain_keeper_list_lock);
344 /***** EXCLUSIVE SECTION END *****/
345 return error; 486 return error;
346} 487}
347 488
@@ -394,13 +535,12 @@ bool tomoyo_read_domain_keeper_policy(struct tomoyo_io_buffer *head)
394 from = " from "; 535 from = " from ";
395 program = ptr->program->name; 536 program = ptr->program->name;
396 } 537 }
397 if (!tomoyo_io_printf(head, 538 done = tomoyo_io_printf(head,
398 "%s" TOMOYO_KEYWORD_KEEP_DOMAIN 539 "%s" TOMOYO_KEYWORD_KEEP_DOMAIN
399 "%s%s%s\n", no, program, from, 540 "%s%s%s\n", no, program, from,
400 ptr->domainname->name)) { 541 ptr->domainname->name);
401 done = false; 542 if (!done)
402 break; 543 break;
403 }
404 } 544 }
405 up_read(&tomoyo_domain_keeper_list_lock); 545 up_read(&tomoyo_domain_keeper_list_lock);
406 return done; 546 return done;
@@ -446,7 +586,36 @@ static bool tomoyo_is_domain_keeper(const struct tomoyo_path_info *domainname,
446 return flag; 586 return flag;
447} 587}
448 588
449/* The list for "struct tomoyo_alias_entry". */ 589/*
590 * tomoyo_alias_list is used for holding list of symlink's pathnames which are
591 * allowed to be passed to an execve() request. Normally, the domainname which
592 * the current process will belong to after execve() succeeds is calculated
593 * using dereferenced pathnames. But some programs behave differently depending
594 * on the name passed to argv[0]. For busybox, calculating domainname using
595 * dereferenced pathnames will cause all programs in the busybox to belong to
596 * the same domain. Thus, TOMOYO provides a way to allow use of symlink's
597 * pathname for checking execve()'s permission and calculating domainname which
598 * the current process will belong to after execve() succeeds.
599 *
600 * An entry is added by
601 *
602 * # echo 'alias /bin/busybox /bin/cat' > \
603 * /sys/kernel/security/tomoyo/exception_policy
604 *
605 * and is deleted by
606 *
607 * # echo 'delete alias /bin/busybox /bin/cat' > \
608 * /sys/kernel/security/tomoyo/exception_policy
609 *
610 * and all entries are retrieved by
611 *
612 * # grep ^alias /sys/kernel/security/tomoyo/exception_policy
613 *
614 * In the example above, if /bin/cat is a symlink to /bin/busybox and execution
615 * of /bin/cat is requested, permission is checked for /bin/cat rather than
616 * /bin/busybox and domainname which the current process will belong to after
617 * execve() succeeds is calculated using /bin/cat rather than /bin/busybox .
618 */
450static LIST_HEAD(tomoyo_alias_list); 619static LIST_HEAD(tomoyo_alias_list);
451static DECLARE_RWSEM(tomoyo_alias_list_lock); 620static DECLARE_RWSEM(tomoyo_alias_list_lock);
452 621
@@ -476,7 +645,6 @@ static int tomoyo_update_alias_entry(const char *original_name,
476 saved_aliased_name = tomoyo_save_name(aliased_name); 645 saved_aliased_name = tomoyo_save_name(aliased_name);
477 if (!saved_original_name || !saved_aliased_name) 646 if (!saved_original_name || !saved_aliased_name)
478 return -ENOMEM; 647 return -ENOMEM;
479 /***** EXCLUSIVE SECTION START *****/
480 down_write(&tomoyo_alias_list_lock); 648 down_write(&tomoyo_alias_list_lock);
481 list_for_each_entry(ptr, &tomoyo_alias_list, list) { 649 list_for_each_entry(ptr, &tomoyo_alias_list, list) {
482 if (ptr->original_name != saved_original_name || 650 if (ptr->original_name != saved_original_name ||
@@ -499,7 +667,6 @@ static int tomoyo_update_alias_entry(const char *original_name,
499 error = 0; 667 error = 0;
500 out: 668 out:
501 up_write(&tomoyo_alias_list_lock); 669 up_write(&tomoyo_alias_list_lock);
502 /***** EXCLUSIVE SECTION END *****/
503 return error; 670 return error;
504} 671}
505 672
@@ -522,12 +689,11 @@ bool tomoyo_read_alias_policy(struct tomoyo_io_buffer *head)
522 ptr = list_entry(pos, struct tomoyo_alias_entry, list); 689 ptr = list_entry(pos, struct tomoyo_alias_entry, list);
523 if (ptr->is_deleted) 690 if (ptr->is_deleted)
524 continue; 691 continue;
525 if (!tomoyo_io_printf(head, TOMOYO_KEYWORD_ALIAS "%s %s\n", 692 done = tomoyo_io_printf(head, TOMOYO_KEYWORD_ALIAS "%s %s\n",
526 ptr->original_name->name, 693 ptr->original_name->name,
527 ptr->aliased_name->name)) { 694 ptr->aliased_name->name);
528 done = false; 695 if (!done)
529 break; 696 break;
530 }
531 } 697 }
532 up_read(&tomoyo_alias_list_lock); 698 up_read(&tomoyo_alias_list_lock);
533 return done; 699 return done;
@@ -567,7 +733,6 @@ int tomoyo_delete_domain(char *domainname)
567 733
568 name.name = domainname; 734 name.name = domainname;
569 tomoyo_fill_path_info(&name); 735 tomoyo_fill_path_info(&name);
570 /***** EXCLUSIVE SECTION START *****/
571 down_write(&tomoyo_domain_list_lock); 736 down_write(&tomoyo_domain_list_lock);
572 /* Is there an active domain? */ 737 /* Is there an active domain? */
573 list_for_each_entry(domain, &tomoyo_domain_list, list) { 738 list_for_each_entry(domain, &tomoyo_domain_list, list) {
@@ -581,7 +746,6 @@ int tomoyo_delete_domain(char *domainname)
581 break; 746 break;
582 } 747 }
583 up_write(&tomoyo_domain_list_lock); 748 up_write(&tomoyo_domain_list_lock);
584 /***** EXCLUSIVE SECTION END *****/
585 return 0; 749 return 0;
586} 750}
587 751
@@ -600,7 +764,6 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
600 struct tomoyo_domain_info *domain = NULL; 764 struct tomoyo_domain_info *domain = NULL;
601 const struct tomoyo_path_info *saved_domainname; 765 const struct tomoyo_path_info *saved_domainname;
602 766
603 /***** EXCLUSIVE SECTION START *****/
604 down_write(&tomoyo_domain_list_lock); 767 down_write(&tomoyo_domain_list_lock);
605 domain = tomoyo_find_domain(domainname); 768 domain = tomoyo_find_domain(domainname);
606 if (domain) 769 if (domain)
@@ -619,7 +782,6 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
619 domain->domainname != saved_domainname) 782 domain->domainname != saved_domainname)
620 continue; 783 continue;
621 flag = false; 784 flag = false;
622 /***** CRITICAL SECTION START *****/
623 read_lock(&tasklist_lock); 785 read_lock(&tasklist_lock);
624 for_each_process(p) { 786 for_each_process(p) {
625 if (tomoyo_real_domain(p) != domain) 787 if (tomoyo_real_domain(p) != domain)
@@ -628,7 +790,6 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
628 break; 790 break;
629 } 791 }
630 read_unlock(&tasklist_lock); 792 read_unlock(&tasklist_lock);
631 /***** CRITICAL SECTION END *****/
632 if (flag) 793 if (flag)
633 continue; 794 continue;
634 list_for_each_entry(ptr, &domain->acl_info_list, list) { 795 list_for_each_entry(ptr, &domain->acl_info_list, list) {
@@ -651,7 +812,6 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
651 } 812 }
652 out: 813 out:
653 up_write(&tomoyo_domain_list_lock); 814 up_write(&tomoyo_domain_list_lock);
654 /***** EXCLUSIVE SECTION END *****/
655 return domain; 815 return domain;
656} 816}
657 817
@@ -739,7 +899,7 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm,
739 } 899 }
740 900
741 /* Check execute permission. */ 901 /* Check execute permission. */
742 retval = tomoyo_check_exec_perm(old_domain, &r, tmp); 902 retval = tomoyo_check_exec_perm(old_domain, &r);
743 if (retval < 0) 903 if (retval < 0)
744 goto out; 904 goto out;
745 905
diff --git a/security/tomoyo/file.c b/security/tomoyo/file.c
index 2316da8ec5bc..5ae3a571559f 100644
--- a/security/tomoyo/file.c
+++ b/security/tomoyo/file.c
@@ -14,21 +14,50 @@
14#include "realpath.h" 14#include "realpath.h"
15#define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE]) 15#define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE])
16 16
17/* Structure for "allow_read" keyword. */ 17/*
18 * tomoyo_globally_readable_file_entry is a structure which is used for holding
19 * "allow_read" entries.
20 * It has following fields.
21 *
22 * (1) "list" which is linked to tomoyo_globally_readable_list .
23 * (2) "filename" is a pathname which is allowed to open(O_RDONLY).
24 * (3) "is_deleted" is a bool which is true if marked as deleted, false
25 * otherwise.
26 */
18struct tomoyo_globally_readable_file_entry { 27struct tomoyo_globally_readable_file_entry {
19 struct list_head list; 28 struct list_head list;
20 const struct tomoyo_path_info *filename; 29 const struct tomoyo_path_info *filename;
21 bool is_deleted; 30 bool is_deleted;
22}; 31};
23 32
24/* Structure for "file_pattern" keyword. */ 33/*
34 * tomoyo_pattern_entry is a structure which is used for holding
35 * "tomoyo_pattern_list" entries.
36 * It has following fields.
37 *
38 * (1) "list" which is linked to tomoyo_pattern_list .
39 * (2) "pattern" is a pathname pattern which is used for converting pathnames
40 * to pathname patterns during learning mode.
41 * (3) "is_deleted" is a bool which is true if marked as deleted, false
42 * otherwise.
43 */
25struct tomoyo_pattern_entry { 44struct tomoyo_pattern_entry {
26 struct list_head list; 45 struct list_head list;
27 const struct tomoyo_path_info *pattern; 46 const struct tomoyo_path_info *pattern;
28 bool is_deleted; 47 bool is_deleted;
29}; 48};
30 49
31/* Structure for "deny_rewrite" keyword. */ 50/*
51 * tomoyo_no_rewrite_entry is a structure which is used for holding
52 * "deny_rewrite" entries.
53 * It has following fields.
54 *
55 * (1) "list" which is linked to tomoyo_no_rewrite_list .
56 * (2) "pattern" is a pathname which is by default not permitted to modify
57 * already existing content.
58 * (3) "is_deleted" is a bool which is true if marked as deleted, false
59 * otherwise.
60 */
32struct tomoyo_no_rewrite_entry { 61struct tomoyo_no_rewrite_entry {
33 struct list_head list; 62 struct list_head list;
34 const struct tomoyo_path_info *pattern; 63 const struct tomoyo_path_info *pattern;
@@ -141,7 +170,31 @@ static int tomoyo_update_single_path_acl(const u8 type, const char *filename,
141 struct tomoyo_domain_info * 170 struct tomoyo_domain_info *
142 const domain, const bool is_delete); 171 const domain, const bool is_delete);
143 172
144/* The list for "struct tomoyo_globally_readable_file_entry". */ 173/*
174 * tomoyo_globally_readable_list is used for holding list of pathnames which
175 * are by default allowed to be open()ed for reading by any process.
176 *
177 * An entry is added by
178 *
179 * # echo 'allow_read /lib/libc-2.5.so' > \
180 * /sys/kernel/security/tomoyo/exception_policy
181 *
182 * and is deleted by
183 *
184 * # echo 'delete allow_read /lib/libc-2.5.so' > \
185 * /sys/kernel/security/tomoyo/exception_policy
186 *
187 * and all entries are retrieved by
188 *
189 * # grep ^allow_read /sys/kernel/security/tomoyo/exception_policy
190 *
191 * In the example above, any process is allowed to
192 * open("/lib/libc-2.5.so", O_RDONLY).
193 * One exception is, if the domain which current process belongs to is marked
194 * as "ignore_global_allow_read", current process can't do so unless explicitly
195 * given "allow_read /lib/libc-2.5.so" to the domain which current process
196 * belongs to.
197 */
145static LIST_HEAD(tomoyo_globally_readable_list); 198static LIST_HEAD(tomoyo_globally_readable_list);
146static DECLARE_RWSEM(tomoyo_globally_readable_list_lock); 199static DECLARE_RWSEM(tomoyo_globally_readable_list_lock);
147 200
@@ -166,7 +219,6 @@ static int tomoyo_update_globally_readable_entry(const char *filename,
166 saved_filename = tomoyo_save_name(filename); 219 saved_filename = tomoyo_save_name(filename);
167 if (!saved_filename) 220 if (!saved_filename)
168 return -ENOMEM; 221 return -ENOMEM;
169 /***** EXCLUSIVE SECTION START *****/
170 down_write(&tomoyo_globally_readable_list_lock); 222 down_write(&tomoyo_globally_readable_list_lock);
171 list_for_each_entry(ptr, &tomoyo_globally_readable_list, list) { 223 list_for_each_entry(ptr, &tomoyo_globally_readable_list, list) {
172 if (ptr->filename != saved_filename) 224 if (ptr->filename != saved_filename)
@@ -187,7 +239,6 @@ static int tomoyo_update_globally_readable_entry(const char *filename,
187 error = 0; 239 error = 0;
188 out: 240 out:
189 up_write(&tomoyo_globally_readable_list_lock); 241 up_write(&tomoyo_globally_readable_list_lock);
190 /***** EXCLUSIVE SECTION END *****/
191 return error; 242 return error;
192} 243}
193 244
@@ -249,17 +300,44 @@ bool tomoyo_read_globally_readable_policy(struct tomoyo_io_buffer *head)
249 list); 300 list);
250 if (ptr->is_deleted) 301 if (ptr->is_deleted)
251 continue; 302 continue;
252 if (!tomoyo_io_printf(head, TOMOYO_KEYWORD_ALLOW_READ "%s\n", 303 done = tomoyo_io_printf(head, TOMOYO_KEYWORD_ALLOW_READ "%s\n",
253 ptr->filename->name)) { 304 ptr->filename->name);
254 done = false; 305 if (!done)
255 break; 306 break;
256 }
257 } 307 }
258 up_read(&tomoyo_globally_readable_list_lock); 308 up_read(&tomoyo_globally_readable_list_lock);
259 return done; 309 return done;
260} 310}
261 311
262/* The list for "struct tomoyo_pattern_entry". */ 312/* tomoyo_pattern_list is used for holding list of pathnames which are used for
313 * converting pathnames to pathname patterns during learning mode.
314 *
315 * An entry is added by
316 *
317 * # echo 'file_pattern /proc/\$/mounts' > \
318 * /sys/kernel/security/tomoyo/exception_policy
319 *
320 * and is deleted by
321 *
322 * # echo 'delete file_pattern /proc/\$/mounts' > \
323 * /sys/kernel/security/tomoyo/exception_policy
324 *
325 * and all entries are retrieved by
326 *
327 * # grep ^file_pattern /sys/kernel/security/tomoyo/exception_policy
328 *
329 * In the example above, if a process which belongs to a domain which is in
330 * learning mode requested open("/proc/1/mounts", O_RDONLY),
331 * "allow_read /proc/\$/mounts" is automatically added to the domain which that
332 * process belongs to.
333 *
334 * It is not a desirable behavior that we have to use /proc/\$/ instead of
335 * /proc/self/ when current process needs to access only current process's
336 * information. As of now, LSM version of TOMOYO is using __d_path() for
337 * calculating pathname. Non LSM version of TOMOYO is using its own function
338 * which pretends as if /proc/self/ is not a symlink; so that we can forbid
339 * current process from accessing other process's information.
340 */
263static LIST_HEAD(tomoyo_pattern_list); 341static LIST_HEAD(tomoyo_pattern_list);
264static DECLARE_RWSEM(tomoyo_pattern_list_lock); 342static DECLARE_RWSEM(tomoyo_pattern_list_lock);
265 343
@@ -284,7 +362,6 @@ static int tomoyo_update_file_pattern_entry(const char *pattern,
284 saved_pattern = tomoyo_save_name(pattern); 362 saved_pattern = tomoyo_save_name(pattern);
285 if (!saved_pattern) 363 if (!saved_pattern)
286 return -ENOMEM; 364 return -ENOMEM;
287 /***** EXCLUSIVE SECTION START *****/
288 down_write(&tomoyo_pattern_list_lock); 365 down_write(&tomoyo_pattern_list_lock);
289 list_for_each_entry(ptr, &tomoyo_pattern_list, list) { 366 list_for_each_entry(ptr, &tomoyo_pattern_list, list) {
290 if (saved_pattern != ptr->pattern) 367 if (saved_pattern != ptr->pattern)
@@ -305,7 +382,6 @@ static int tomoyo_update_file_pattern_entry(const char *pattern,
305 error = 0; 382 error = 0;
306 out: 383 out:
307 up_write(&tomoyo_pattern_list_lock); 384 up_write(&tomoyo_pattern_list_lock);
308 /***** EXCLUSIVE SECTION END *****/
309 return error; 385 return error;
310} 386}
311 387
@@ -373,17 +449,44 @@ bool tomoyo_read_file_pattern(struct tomoyo_io_buffer *head)
373 ptr = list_entry(pos, struct tomoyo_pattern_entry, list); 449 ptr = list_entry(pos, struct tomoyo_pattern_entry, list);
374 if (ptr->is_deleted) 450 if (ptr->is_deleted)
375 continue; 451 continue;
376 if (!tomoyo_io_printf(head, TOMOYO_KEYWORD_FILE_PATTERN "%s\n", 452 done = tomoyo_io_printf(head, TOMOYO_KEYWORD_FILE_PATTERN
377 ptr->pattern->name)) { 453 "%s\n", ptr->pattern->name);
378 done = false; 454 if (!done)
379 break; 455 break;
380 }
381 } 456 }
382 up_read(&tomoyo_pattern_list_lock); 457 up_read(&tomoyo_pattern_list_lock);
383 return done; 458 return done;
384} 459}
385 460
386/* The list for "struct tomoyo_no_rewrite_entry". */ 461/*
462 * tomoyo_no_rewrite_list is used for holding list of pathnames which are by
463 * default forbidden to modify already written content of a file.
464 *
465 * An entry is added by
466 *
467 * # echo 'deny_rewrite /var/log/messages' > \
468 * /sys/kernel/security/tomoyo/exception_policy
469 *
470 * and is deleted by
471 *
472 * # echo 'delete deny_rewrite /var/log/messages' > \
473 * /sys/kernel/security/tomoyo/exception_policy
474 *
475 * and all entries are retrieved by
476 *
477 * # grep ^deny_rewrite /sys/kernel/security/tomoyo/exception_policy
478 *
479 * In the example above, if a process requested to rewrite /var/log/messages ,
480 * the process can't rewrite unless the domain which that process belongs to
481 * has "allow_rewrite /var/log/messages" entry.
482 *
483 * It is not a desirable behavior that we have to add "\040(deleted)" suffix
484 * when we want to allow rewriting already unlink()ed file. As of now,
485 * LSM version of TOMOYO is using __d_path() for calculating pathname.
486 * Non LSM version of TOMOYO is using its own function which doesn't append
487 * " (deleted)" suffix if the file is already unlink()ed; so that we don't
488 * need to worry whether the file is already unlink()ed or not.
489 */
387static LIST_HEAD(tomoyo_no_rewrite_list); 490static LIST_HEAD(tomoyo_no_rewrite_list);
388static DECLARE_RWSEM(tomoyo_no_rewrite_list_lock); 491static DECLARE_RWSEM(tomoyo_no_rewrite_list_lock);
389 492
@@ -407,7 +510,6 @@ static int tomoyo_update_no_rewrite_entry(const char *pattern,
407 saved_pattern = tomoyo_save_name(pattern); 510 saved_pattern = tomoyo_save_name(pattern);
408 if (!saved_pattern) 511 if (!saved_pattern)
409 return -ENOMEM; 512 return -ENOMEM;
410 /***** EXCLUSIVE SECTION START *****/
411 down_write(&tomoyo_no_rewrite_list_lock); 513 down_write(&tomoyo_no_rewrite_list_lock);
412 list_for_each_entry(ptr, &tomoyo_no_rewrite_list, list) { 514 list_for_each_entry(ptr, &tomoyo_no_rewrite_list, list) {
413 if (ptr->pattern != saved_pattern) 515 if (ptr->pattern != saved_pattern)
@@ -428,7 +530,6 @@ static int tomoyo_update_no_rewrite_entry(const char *pattern,
428 error = 0; 530 error = 0;
429 out: 531 out:
430 up_write(&tomoyo_no_rewrite_list_lock); 532 up_write(&tomoyo_no_rewrite_list_lock);
431 /***** EXCLUSIVE SECTION END *****/
432 return error; 533 return error;
433} 534}
434 535
@@ -489,11 +590,10 @@ bool tomoyo_read_no_rewrite_policy(struct tomoyo_io_buffer *head)
489 ptr = list_entry(pos, struct tomoyo_no_rewrite_entry, list); 590 ptr = list_entry(pos, struct tomoyo_no_rewrite_entry, list);
490 if (ptr->is_deleted) 591 if (ptr->is_deleted)
491 continue; 592 continue;
492 if (!tomoyo_io_printf(head, TOMOYO_KEYWORD_DENY_REWRITE "%s\n", 593 done = tomoyo_io_printf(head, TOMOYO_KEYWORD_DENY_REWRITE
493 ptr->pattern->name)) { 594 "%s\n", ptr->pattern->name);
494 done = false; 595 if (!done)
495 break; 596 break;
496 }
497 } 597 }
498 up_read(&tomoyo_no_rewrite_list_lock); 598 up_read(&tomoyo_no_rewrite_list_lock);
499 return done; 599 return done;
@@ -745,7 +845,6 @@ static int tomoyo_update_single_path_acl(const u8 type, const char *filename,
745 saved_filename = tomoyo_save_name(filename); 845 saved_filename = tomoyo_save_name(filename);
746 if (!saved_filename) 846 if (!saved_filename)
747 return -ENOMEM; 847 return -ENOMEM;
748 /***** EXCLUSIVE SECTION START *****/
749 down_write(&tomoyo_domain_acl_info_list_lock); 848 down_write(&tomoyo_domain_acl_info_list_lock);
750 if (is_delete) 849 if (is_delete)
751 goto delete; 850 goto delete;
@@ -800,7 +899,6 @@ static int tomoyo_update_single_path_acl(const u8 type, const char *filename,
800 } 899 }
801 out: 900 out:
802 up_write(&tomoyo_domain_acl_info_list_lock); 901 up_write(&tomoyo_domain_acl_info_list_lock);
803 /***** EXCLUSIVE SECTION END *****/
804 return error; 902 return error;
805} 903}
806 904
@@ -836,7 +934,6 @@ static int tomoyo_update_double_path_acl(const u8 type, const char *filename1,
836 saved_filename2 = tomoyo_save_name(filename2); 934 saved_filename2 = tomoyo_save_name(filename2);
837 if (!saved_filename1 || !saved_filename2) 935 if (!saved_filename1 || !saved_filename2)
838 return -ENOMEM; 936 return -ENOMEM;
839 /***** EXCLUSIVE SECTION START *****/
840 down_write(&tomoyo_domain_acl_info_list_lock); 937 down_write(&tomoyo_domain_acl_info_list_lock);
841 if (is_delete) 938 if (is_delete)
842 goto delete; 939 goto delete;
@@ -884,7 +981,6 @@ static int tomoyo_update_double_path_acl(const u8 type, const char *filename1,
884 } 981 }
885 out: 982 out:
886 up_write(&tomoyo_domain_acl_info_list_lock); 983 up_write(&tomoyo_domain_acl_info_list_lock);
887 /***** EXCLUSIVE SECTION END *****/
888 return error; 984 return error;
889} 985}
890 986
@@ -1025,13 +1121,11 @@ int tomoyo_check_file_perm(struct tomoyo_domain_info *domain,
1025 * 1121 *
1026 * @domain: Pointer to "struct tomoyo_domain_info". 1122 * @domain: Pointer to "struct tomoyo_domain_info".
1027 * @filename: Check permission for "execute". 1123 * @filename: Check permission for "execute".
1028 * @tmp: Buffer for temporary use.
1029 * 1124 *
1030 * Returns 0 on success, negativevalue otherwise. 1125 * Returns 0 on success, negativevalue otherwise.
1031 */ 1126 */
1032int tomoyo_check_exec_perm(struct tomoyo_domain_info *domain, 1127int tomoyo_check_exec_perm(struct tomoyo_domain_info *domain,
1033 const struct tomoyo_path_info *filename, 1128 const struct tomoyo_path_info *filename)
1034 struct tomoyo_page_buffer *tmp)
1035{ 1129{
1036 const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE); 1130 const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE);
1037 1131
diff --git a/security/tomoyo/realpath.c b/security/tomoyo/realpath.c
index 40927a84cb6e..5f2e33263371 100644
--- a/security/tomoyo/realpath.c
+++ b/security/tomoyo/realpath.c
@@ -220,7 +220,6 @@ void *tomoyo_alloc_element(const unsigned int size)
220 = roundup(size, max(sizeof(void *), sizeof(long))); 220 = roundup(size, max(sizeof(void *), sizeof(long)));
221 if (word_aligned_size > PATH_MAX) 221 if (word_aligned_size > PATH_MAX)
222 return NULL; 222 return NULL;
223 /***** EXCLUSIVE SECTION START *****/
224 mutex_lock(&lock); 223 mutex_lock(&lock);
225 if (buf_used_len + word_aligned_size > PATH_MAX) { 224 if (buf_used_len + word_aligned_size > PATH_MAX) {
226 if (!tomoyo_quota_for_elements || 225 if (!tomoyo_quota_for_elements ||
@@ -251,7 +250,6 @@ void *tomoyo_alloc_element(const unsigned int size)
251 } 250 }
252 } 251 }
253 mutex_unlock(&lock); 252 mutex_unlock(&lock);
254 /***** EXCLUSIVE SECTION END *****/
255 return ptr; 253 return ptr;
256} 254}
257 255
@@ -267,7 +265,16 @@ static unsigned int tomoyo_quota_for_savename;
267 */ 265 */
268#define TOMOYO_MAX_HASH 256 266#define TOMOYO_MAX_HASH 256
269 267
270/* Structure for string data. */ 268/*
269 * tomoyo_name_entry is a structure which is used for linking
270 * "struct tomoyo_path_info" into tomoyo_name_list .
271 *
272 * Since tomoyo_name_list manages a list of strings which are shared by
273 * multiple processes (whereas "struct tomoyo_path_info" inside
274 * "struct tomoyo_path_info_with_data" is not shared), a reference counter will
275 * be added to "struct tomoyo_name_entry" rather than "struct tomoyo_path_info"
276 * when TOMOYO starts supporting garbage collector.
277 */
271struct tomoyo_name_entry { 278struct tomoyo_name_entry {
272 struct list_head list; 279 struct list_head list;
273 struct tomoyo_path_info entry; 280 struct tomoyo_path_info entry;
@@ -281,10 +288,10 @@ struct tomoyo_free_memory_block_list {
281}; 288};
282 289
283/* 290/*
284 * The list for "struct tomoyo_name_entry". 291 * tomoyo_name_list is used for holding string data used by TOMOYO.
285 * 292 * Since same string data is likely used for multiple times (e.g.
286 * This list is updated only inside tomoyo_save_name(), thus 293 * "/lib/libc-2.5.so"), TOMOYO shares string data in the form of
287 * no global mutex exists. 294 * "const struct tomoyo_path_info *".
288 */ 295 */
289static struct list_head tomoyo_name_list[TOMOYO_MAX_HASH]; 296static struct list_head tomoyo_name_list[TOMOYO_MAX_HASH];
290 297
@@ -318,7 +325,6 @@ const struct tomoyo_path_info *tomoyo_save_name(const char *name)
318 return NULL; 325 return NULL;
319 } 326 }
320 hash = full_name_hash((const unsigned char *) name, len - 1); 327 hash = full_name_hash((const unsigned char *) name, len - 1);
321 /***** EXCLUSIVE SECTION START *****/
322 mutex_lock(&lock); 328 mutex_lock(&lock);
323 list_for_each_entry(ptr, &tomoyo_name_list[hash % TOMOYO_MAX_HASH], 329 list_for_each_entry(ptr, &tomoyo_name_list[hash % TOMOYO_MAX_HASH],
324 list) { 330 list) {
@@ -366,7 +372,6 @@ const struct tomoyo_path_info *tomoyo_save_name(const char *name)
366 } 372 }
367 out: 373 out:
368 mutex_unlock(&lock); 374 mutex_unlock(&lock);
369 /***** EXCLUSIVE SECTION END *****/
370 return ptr ? &ptr->entry : NULL; 375 return ptr ? &ptr->entry : NULL;
371} 376}
372 377
diff --git a/security/tomoyo/tomoyo.c b/security/tomoyo/tomoyo.c
index e42be5c4f055..3194d09fe0f4 100644
--- a/security/tomoyo/tomoyo.c
+++ b/security/tomoyo/tomoyo.c
@@ -262,6 +262,10 @@ static int tomoyo_dentry_open(struct file *f, const struct cred *cred)
262 return tomoyo_check_open_permission(tomoyo_domain(), &f->f_path, flags); 262 return tomoyo_check_open_permission(tomoyo_domain(), &f->f_path, flags);
263} 263}
264 264
265/*
266 * tomoyo_security_ops is a "struct security_operations" which is used for
267 * registering TOMOYO.
268 */
265static struct security_operations tomoyo_security_ops = { 269static struct security_operations tomoyo_security_ops = {
266 .name = "tomoyo", 270 .name = "tomoyo",
267 .cred_prepare = tomoyo_cred_prepare, 271 .cred_prepare = tomoyo_cred_prepare,
diff --git a/security/tomoyo/tomoyo.h b/security/tomoyo/tomoyo.h
index 41c6ebafb9c5..0fd588a629cf 100644
--- a/security/tomoyo/tomoyo.h
+++ b/security/tomoyo/tomoyo.h
@@ -17,13 +17,11 @@ struct path;
17struct inode; 17struct inode;
18struct linux_binprm; 18struct linux_binprm;
19struct pt_regs; 19struct pt_regs;
20struct tomoyo_page_buffer;
21 20
22int tomoyo_check_file_perm(struct tomoyo_domain_info *domain, 21int tomoyo_check_file_perm(struct tomoyo_domain_info *domain,
23 const char *filename, const u8 perm); 22 const char *filename, const u8 perm);
24int tomoyo_check_exec_perm(struct tomoyo_domain_info *domain, 23int tomoyo_check_exec_perm(struct tomoyo_domain_info *domain,
25 const struct tomoyo_path_info *filename, 24 const struct tomoyo_path_info *filename);
26 struct tomoyo_page_buffer *buf);
27int tomoyo_check_open_permission(struct tomoyo_domain_info *domain, 25int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
28 struct path *path, const int flag); 26 struct path *path, const int flag);
29int tomoyo_check_1path_perm(struct tomoyo_domain_info *domain, 27int tomoyo_check_1path_perm(struct tomoyo_domain_info *domain,
@@ -90,17 +88,10 @@ static inline struct tomoyo_domain_info *tomoyo_domain(void)
90 return current_cred()->security; 88 return current_cred()->security;
91} 89}
92 90
93/* Caller holds tasklist_lock spinlock. */
94static inline struct tomoyo_domain_info *tomoyo_real_domain(struct task_struct 91static inline struct tomoyo_domain_info *tomoyo_real_domain(struct task_struct
95 *task) 92 *task)
96{ 93{
97 /***** CRITICAL SECTION START *****/ 94 return task_cred_xxx(task, security);
98 const struct cred *cred = get_task_cred(task);
99 struct tomoyo_domain_info *domain = cred->security;
100
101 put_cred(cred);
102 return domain;
103 /***** CRITICAL SECTION END *****/
104} 95}
105 96
106#endif /* !defined(_SECURITY_TOMOYO_TOMOYO_H) */ 97#endif /* !defined(_SECURITY_TOMOYO_TOMOYO_H) */