aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/Makefile3
-rw-r--r--security/inode.c11
-rw-r--r--security/integrity/ima/ima.h6
-rw-r--r--security/integrity/ima/ima_api.c4
-rw-r--r--security/integrity/ima/ima_iint.c85
-rw-r--r--security/integrity/ima/ima_main.c309
-rw-r--r--security/integrity/ima/ima_policy.c9
-rw-r--r--security/keys/gc.c3
-rw-r--r--security/keys/keyctl.c12
-rw-r--r--security/keys/keyring.c4
-rw-r--r--security/min_addr.c2
-rw-r--r--security/security.c2
-rw-r--r--security/selinux/hooks.c2
-rw-r--r--security/selinux/netlabel.c2
-rw-r--r--security/selinux/ss/ebitmap.c2
-rw-r--r--security/selinux/ss/services.c2
-rw-r--r--security/tomoyo/file.c1
-rw-r--r--security/tomoyo/tomoyo.c7
18 files changed, 187 insertions, 279 deletions
diff --git a/security/Makefile b/security/Makefile
index bb44e350c618..da20a193c8dd 100644
--- a/security/Makefile
+++ b/security/Makefile
@@ -8,7 +8,8 @@ subdir-$(CONFIG_SECURITY_SMACK) += smack
8subdir-$(CONFIG_SECURITY_TOMOYO) += tomoyo 8subdir-$(CONFIG_SECURITY_TOMOYO) += tomoyo
9 9
10# always enable default capabilities 10# always enable default capabilities
11obj-y += commoncap.o min_addr.o 11obj-y += commoncap.o
12obj-$(CONFIG_MMU) += min_addr.o
12 13
13# Object file lists 14# Object file lists
14obj-$(CONFIG_SECURITY) += security.o capability.o 15obj-$(CONFIG_SECURITY) += security.o capability.o
diff --git a/security/inode.c b/security/inode.c
index f7496c6a022b..c3a793881d04 100644
--- a/security/inode.c
+++ b/security/inode.c
@@ -156,15 +156,8 @@ static int create_by_name(const char *name, mode_t mode,
156 * block. A pointer to that is in the struct vfsmount that we 156 * block. A pointer to that is in the struct vfsmount that we
157 * have around. 157 * have around.
158 */ 158 */
159 if (!parent ) { 159 if (!parent)
160 if (mount && mount->mnt_sb) { 160 parent = mount->mnt_sb->s_root;
161 parent = mount->mnt_sb->s_root;
162 }
163 }
164 if (!parent) {
165 pr_debug("securityfs: Ah! can not find a parent!\n");
166 return -EFAULT;
167 }
168 161
169 mutex_lock(&parent->d_inode->i_mutex); 162 mutex_lock(&parent->d_inode->i_mutex);
170 *dentry = lookup_one_len(name, parent, strlen(name)); 163 *dentry = lookup_one_len(name, parent, strlen(name));
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 165eb5397ea5..47fb65d1fcbd 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -65,7 +65,6 @@ void integrity_audit_msg(int audit_msgno, struct inode *inode,
65 const char *cause, int result, int info); 65 const char *cause, int result, int info);
66 66
67/* Internal IMA function definitions */ 67/* Internal IMA function definitions */
68void ima_iintcache_init(void);
69int ima_init(void); 68int ima_init(void);
70void ima_cleanup(void); 69void ima_cleanup(void);
71int ima_fs_init(void); 70int ima_fs_init(void);
@@ -97,7 +96,6 @@ static inline unsigned long ima_hash_key(u8 *digest)
97 96
98/* iint cache flags */ 97/* iint cache flags */
99#define IMA_MEASURED 1 98#define IMA_MEASURED 1
100#define IMA_IINT_DUMP_STACK 512
101 99
102/* integrity data associated with an inode */ 100/* integrity data associated with an inode */
103struct ima_iint_cache { 101struct ima_iint_cache {
@@ -128,13 +126,11 @@ void ima_template_show(struct seq_file *m, void *e,
128 */ 126 */
129struct ima_iint_cache *ima_iint_insert(struct inode *inode); 127struct ima_iint_cache *ima_iint_insert(struct inode *inode);
130struct ima_iint_cache *ima_iint_find_get(struct inode *inode); 128struct ima_iint_cache *ima_iint_find_get(struct inode *inode);
131struct ima_iint_cache *ima_iint_find_insert_get(struct inode *inode);
132void ima_iint_delete(struct inode *inode);
133void iint_free(struct kref *kref); 129void iint_free(struct kref *kref);
134void iint_rcu_free(struct rcu_head *rcu); 130void iint_rcu_free(struct rcu_head *rcu);
135 131
136/* IMA policy related functions */ 132/* IMA policy related functions */
137enum ima_hooks { PATH_CHECK = 1, FILE_MMAP, BPRM_CHECK }; 133enum ima_hooks { FILE_CHECK = 1, FILE_MMAP, BPRM_CHECK };
138 134
139int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask); 135int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask);
140void ima_init_policy(void); 136void ima_init_policy(void);
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index 3cd58b60afd2..2a5e0bcf3887 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -95,12 +95,12 @@ err_out:
95 * ima_must_measure - measure decision based on policy. 95 * ima_must_measure - measure decision based on policy.
96 * @inode: pointer to inode to measure 96 * @inode: pointer to inode to measure
97 * @mask: contains the permission mask (MAY_READ, MAY_WRITE, MAY_EXECUTE) 97 * @mask: contains the permission mask (MAY_READ, MAY_WRITE, MAY_EXECUTE)
98 * @function: calling function (PATH_CHECK, BPRM_CHECK, FILE_MMAP) 98 * @function: calling function (FILE_CHECK, BPRM_CHECK, FILE_MMAP)
99 * 99 *
100 * The policy is defined in terms of keypairs: 100 * The policy is defined in terms of keypairs:
101 * subj=, obj=, type=, func=, mask=, fsmagic= 101 * subj=, obj=, type=, func=, mask=, fsmagic=
102 * subj,obj, and type: are LSM specific. 102 * subj,obj, and type: are LSM specific.
103 * func: PATH_CHECK | BPRM_CHECK | FILE_MMAP 103 * func: FILE_CHECK | BPRM_CHECK | FILE_MMAP
104 * mask: contains the permission mask 104 * mask: contains the permission mask
105 * fsmagic: hex value 105 * fsmagic: hex value
106 * 106 *
diff --git a/security/integrity/ima/ima_iint.c b/security/integrity/ima/ima_iint.c
index a4e2b1dac943..2d4d05d92fda 100644
--- a/security/integrity/ima/ima_iint.c
+++ b/security/integrity/ima/ima_iint.c
@@ -19,8 +19,6 @@
19#include <linux/radix-tree.h> 19#include <linux/radix-tree.h>
20#include "ima.h" 20#include "ima.h"
21 21
22#define ima_iint_delete ima_inode_free
23
24RADIX_TREE(ima_iint_store, GFP_ATOMIC); 22RADIX_TREE(ima_iint_store, GFP_ATOMIC);
25DEFINE_SPINLOCK(ima_iint_lock); 23DEFINE_SPINLOCK(ima_iint_lock);
26 24
@@ -45,22 +43,18 @@ out:
45 return iint; 43 return iint;
46} 44}
47 45
48/* Allocate memory for the iint associated with the inode 46/**
49 * from the iint_cache slab, initialize the iint, and 47 * ima_inode_alloc - allocate an iint associated with an inode
50 * insert it into the radix tree. 48 * @inode: pointer to the inode
51 *
52 * On success return a pointer to the iint; on failure return NULL.
53 */ 49 */
54struct ima_iint_cache *ima_iint_insert(struct inode *inode) 50int ima_inode_alloc(struct inode *inode)
55{ 51{
56 struct ima_iint_cache *iint = NULL; 52 struct ima_iint_cache *iint = NULL;
57 int rc = 0; 53 int rc = 0;
58 54
59 if (!ima_initialized)
60 return iint;
61 iint = kmem_cache_alloc(iint_cache, GFP_NOFS); 55 iint = kmem_cache_alloc(iint_cache, GFP_NOFS);
62 if (!iint) 56 if (!iint)
63 return iint; 57 return -ENOMEM;
64 58
65 rc = radix_tree_preload(GFP_NOFS); 59 rc = radix_tree_preload(GFP_NOFS);
66 if (rc < 0) 60 if (rc < 0)
@@ -69,67 +63,14 @@ struct ima_iint_cache *ima_iint_insert(struct inode *inode)
69 spin_lock(&ima_iint_lock); 63 spin_lock(&ima_iint_lock);
70 rc = radix_tree_insert(&ima_iint_store, (unsigned long)inode, iint); 64 rc = radix_tree_insert(&ima_iint_store, (unsigned long)inode, iint);
71 spin_unlock(&ima_iint_lock); 65 spin_unlock(&ima_iint_lock);
66 radix_tree_preload_end();
72out: 67out:
73 if (rc < 0) { 68 if (rc < 0)
74 kmem_cache_free(iint_cache, iint); 69 kmem_cache_free(iint_cache, iint);
75 if (rc == -EEXIST) {
76 spin_lock(&ima_iint_lock);
77 iint = radix_tree_lookup(&ima_iint_store,
78 (unsigned long)inode);
79 spin_unlock(&ima_iint_lock);
80 } else
81 iint = NULL;
82 }
83 radix_tree_preload_end();
84 return iint;
85}
86 70
87/** 71 return rc;
88 * ima_inode_alloc - allocate an iint associated with an inode
89 * @inode: pointer to the inode
90 *
91 * Return 0 on success, 1 on failure.
92 */
93int ima_inode_alloc(struct inode *inode)
94{
95 struct ima_iint_cache *iint;
96
97 if (!ima_initialized)
98 return 0;
99
100 iint = ima_iint_insert(inode);
101 if (!iint)
102 return 1;
103 return 0;
104} 72}
105 73
106/* ima_iint_find_insert_get - get the iint associated with an inode
107 *
108 * Most insertions are done at inode_alloc, except those allocated
109 * before late_initcall. When the iint does not exist, allocate it,
110 * initialize and insert it, and increment the iint refcount.
111 *
112 * (Can't initialize at security_initcall before any inodes are
113 * allocated, got to wait at least until proc_init.)
114 *
115 * Return the iint.
116 */
117struct ima_iint_cache *ima_iint_find_insert_get(struct inode *inode)
118{
119 struct ima_iint_cache *iint = NULL;
120
121 iint = ima_iint_find_get(inode);
122 if (iint)
123 return iint;
124
125 iint = ima_iint_insert(inode);
126 if (iint)
127 kref_get(&iint->refcount);
128
129 return iint;
130}
131EXPORT_SYMBOL_GPL(ima_iint_find_insert_get);
132
133/* iint_free - called when the iint refcount goes to zero */ 74/* iint_free - called when the iint refcount goes to zero */
134void iint_free(struct kref *kref) 75void iint_free(struct kref *kref)
135{ 76{
@@ -164,17 +105,15 @@ void iint_rcu_free(struct rcu_head *rcu_head)
164} 105}
165 106
166/** 107/**
167 * ima_iint_delete - called on integrity_inode_free 108 * ima_inode_free - called on security_inode_free
168 * @inode: pointer to the inode 109 * @inode: pointer to the inode
169 * 110 *
170 * Free the integrity information(iint) associated with an inode. 111 * Free the integrity information(iint) associated with an inode.
171 */ 112 */
172void ima_iint_delete(struct inode *inode) 113void ima_inode_free(struct inode *inode)
173{ 114{
174 struct ima_iint_cache *iint; 115 struct ima_iint_cache *iint;
175 116
176 if (!ima_initialized)
177 return;
178 spin_lock(&ima_iint_lock); 117 spin_lock(&ima_iint_lock);
179 iint = radix_tree_delete(&ima_iint_store, (unsigned long)inode); 118 iint = radix_tree_delete(&ima_iint_store, (unsigned long)inode);
180 spin_unlock(&ima_iint_lock); 119 spin_unlock(&ima_iint_lock);
@@ -196,9 +135,11 @@ static void init_once(void *foo)
196 kref_set(&iint->refcount, 1); 135 kref_set(&iint->refcount, 1);
197} 136}
198 137
199void __init ima_iintcache_init(void) 138static int __init ima_iintcache_init(void)
200{ 139{
201 iint_cache = 140 iint_cache =
202 kmem_cache_create("iint_cache", sizeof(struct ima_iint_cache), 0, 141 kmem_cache_create("iint_cache", sizeof(struct ima_iint_cache), 0,
203 SLAB_PANIC, init_once); 142 SLAB_PANIC, init_once);
143 return 0;
204} 144}
145security_initcall(ima_iintcache_init);
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index b85e61bcf246..294b005d6520 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -13,8 +13,8 @@
13 * License. 13 * License.
14 * 14 *
15 * File: ima_main.c 15 * File: ima_main.c
16 * implements the IMA hooks: ima_bprm_check, ima_file_mmap, 16 * implements the IMA hooks: ima_bprm_check, ima_file_mmap,
17 * and ima_path_check. 17 * and ima_file_check.
18 */ 18 */
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/file.h> 20#include <linux/file.h>
@@ -35,50 +35,53 @@ static int __init hash_setup(char *str)
35} 35}
36__setup("ima_hash=", hash_setup); 36__setup("ima_hash=", hash_setup);
37 37
38/** 38struct ima_imbalance {
39 * ima_file_free - called on __fput() 39 struct hlist_node node;
40 * @file: pointer to file structure being freed 40 unsigned long fsmagic;
41};
42
43/*
44 * ima_limit_imbalance - emit one imbalance message per filesystem type
41 * 45 *
42 * Flag files that changed, based on i_version; 46 * Maintain list of filesystem types that do not measure files properly.
43 * and decrement the iint readcount/writecount. 47 * Return false if unknown, true if known.
44 */ 48 */
45void ima_file_free(struct file *file) 49static bool ima_limit_imbalance(struct file *file)
46{ 50{
47 struct inode *inode = file->f_dentry->d_inode; 51 static DEFINE_SPINLOCK(ima_imbalance_lock);
48 struct ima_iint_cache *iint; 52 static HLIST_HEAD(ima_imbalance_list);
49 53
50 if (!ima_initialized || !S_ISREG(inode->i_mode)) 54 struct super_block *sb = file->f_dentry->d_sb;
51 return; 55 struct ima_imbalance *entry;
52 iint = ima_iint_find_get(inode); 56 struct hlist_node *node;
53 if (!iint) 57 bool found = false;
54 return; 58
55 59 rcu_read_lock();
56 mutex_lock(&iint->mutex); 60 hlist_for_each_entry_rcu(entry, node, &ima_imbalance_list, node) {
57 if (iint->opencount <= 0) { 61 if (entry->fsmagic == sb->s_magic) {
58 printk(KERN_INFO 62 found = true;
59 "%s: %s open/free imbalance (r:%ld w:%ld o:%ld f:%ld)\n", 63 break;
60 __FUNCTION__, file->f_dentry->d_name.name,
61 iint->readcount, iint->writecount,
62 iint->opencount, atomic_long_read(&file->f_count));
63 if (!(iint->flags & IMA_IINT_DUMP_STACK)) {
64 dump_stack();
65 iint->flags |= IMA_IINT_DUMP_STACK;
66 } 64 }
67 } 65 }
68 iint->opencount--; 66 rcu_read_unlock();
69 67 if (found)
70 if ((file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) 68 goto out;
71 iint->readcount--;
72 69
73 if (file->f_mode & FMODE_WRITE) { 70 entry = kmalloc(sizeof(*entry), GFP_NOFS);
74 iint->writecount--; 71 if (!entry)
75 if (iint->writecount == 0) { 72 goto out;
76 if (iint->version != inode->i_version) 73 entry->fsmagic = sb->s_magic;
77 iint->flags &= ~IMA_MEASURED; 74 spin_lock(&ima_imbalance_lock);
78 } 75 /*
79 } 76 * we could have raced and something else might have added this fs
80 mutex_unlock(&iint->mutex); 77 * to the list, but we don't really care
81 kref_put(&iint->refcount, iint_free); 78 */
79 hlist_add_head_rcu(&entry->node, &ima_imbalance_list);
80 spin_unlock(&ima_imbalance_lock);
81 printk(KERN_INFO "IMA: unmeasured files on fsmagic: %lX\n",
82 entry->fsmagic);
83out:
84 return found;
82} 85}
83 86
84/* ima_read_write_check - reflect possible reading/writing errors in the PCR. 87/* ima_read_write_check - reflect possible reading/writing errors in the PCR.
@@ -111,196 +114,142 @@ static void ima_read_write_check(enum iint_pcr_error error,
111 } 114 }
112} 115}
113 116
114static int get_path_measurement(struct ima_iint_cache *iint, struct file *file, 117/*
115 const unsigned char *filename) 118 * Update the counts given an fmode_t
119 */
120static void ima_inc_counts(struct ima_iint_cache *iint, fmode_t mode)
116{ 121{
117 int rc = 0; 122 BUG_ON(!mutex_is_locked(&iint->mutex));
118
119 iint->opencount++;
120 iint->readcount++;
121
122 rc = ima_collect_measurement(iint, file);
123 if (!rc)
124 ima_store_measurement(iint, file, filename);
125 return rc;
126}
127 123
128static void ima_update_counts(struct ima_iint_cache *iint, int mask)
129{
130 iint->opencount++; 124 iint->opencount++;
131 if ((mask & MAY_WRITE) || (mask == 0)) 125 if ((mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
132 iint->writecount++;
133 else if (mask & (MAY_READ | MAY_EXEC))
134 iint->readcount++; 126 iint->readcount++;
127 if (mode & FMODE_WRITE)
128 iint->writecount++;
135} 129}
136 130
137/** 131/*
138 * ima_path_check - based on policy, collect/store measurement. 132 * ima_counts_get - increment file counts
139 * @path: contains a pointer to the path to be measured
140 * @mask: contains MAY_READ, MAY_WRITE or MAY_EXECUTE
141 *
142 * Measure the file being open for readonly, based on the
143 * ima_must_measure() policy decision.
144 * 133 *
145 * Keep read/write counters for all files, but only 134 * Maintain read/write counters for all files, but only
146 * invalidate the PCR for measured files: 135 * invalidate the PCR for measured files:
147 * - Opening a file for write when already open for read, 136 * - Opening a file for write when already open for read,
148 * results in a time of measure, time of use (ToMToU) error. 137 * results in a time of measure, time of use (ToMToU) error.
149 * - Opening a file for read when already open for write, 138 * - Opening a file for read when already open for write,
150 * could result in a file measurement error. 139 * could result in a file measurement error.
151 * 140 *
152 * Always return 0 and audit dentry_open failures.
153 * (Return code will be based upon measurement appraisal.)
154 */ 141 */
155int ima_path_check(struct path *path, int mask, int update_counts) 142void ima_counts_get(struct file *file)
156{ 143{
157 struct inode *inode = path->dentry->d_inode; 144 struct dentry *dentry = file->f_path.dentry;
145 struct inode *inode = dentry->d_inode;
146 fmode_t mode = file->f_mode;
158 struct ima_iint_cache *iint; 147 struct ima_iint_cache *iint;
159 struct file *file = NULL;
160 int rc; 148 int rc;
161 149
162 if (!ima_initialized || !S_ISREG(inode->i_mode)) 150 if (!ima_initialized || !S_ISREG(inode->i_mode))
163 return 0; 151 return;
164 iint = ima_iint_find_insert_get(inode); 152 iint = ima_iint_find_get(inode);
165 if (!iint) 153 if (!iint)
166 return 0; 154 return;
167
168 mutex_lock(&iint->mutex); 155 mutex_lock(&iint->mutex);
169 if (update_counts) 156 rc = ima_must_measure(iint, inode, MAY_READ, FILE_CHECK);
170 ima_update_counts(iint, mask);
171
172 rc = ima_must_measure(iint, inode, MAY_READ, PATH_CHECK);
173 if (rc < 0) 157 if (rc < 0)
174 goto out; 158 goto out;
175 159
176 if ((mask & MAY_WRITE) || (mask == 0)) 160 if (mode & FMODE_WRITE) {
177 ima_read_write_check(TOMTOU, iint, inode, 161 ima_read_write_check(TOMTOU, iint, inode, dentry->d_name.name);
178 path->dentry->d_name.name);
179
180 if ((mask & (MAY_WRITE | MAY_READ | MAY_EXEC)) != MAY_READ)
181 goto out; 162 goto out;
182
183 ima_read_write_check(OPEN_WRITERS, iint, inode,
184 path->dentry->d_name.name);
185 if (!(iint->flags & IMA_MEASURED)) {
186 struct dentry *dentry = dget(path->dentry);
187 struct vfsmount *mnt = mntget(path->mnt);
188
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 }
202 rc = get_path_measurement(iint, file, dentry->d_name.name);
203 } 163 }
164 ima_read_write_check(OPEN_WRITERS, iint, inode, dentry->d_name.name);
204out: 165out:
166 ima_inc_counts(iint, file->f_mode);
205 mutex_unlock(&iint->mutex); 167 mutex_unlock(&iint->mutex);
206 if (file) 168
207 fput(file);
208 kref_put(&iint->refcount, iint_free); 169 kref_put(&iint->refcount, iint_free);
209 return 0;
210} 170}
211EXPORT_SYMBOL_GPL(ima_path_check);
212 171
213static int process_measurement(struct file *file, const unsigned char *filename, 172/*
214 int mask, int function) 173 * Decrement ima counts
174 */
175static void ima_dec_counts(struct ima_iint_cache *iint, struct inode *inode,
176 struct file *file)
215{ 177{
216 struct inode *inode = file->f_dentry->d_inode; 178 mode_t mode = file->f_mode;
217 struct ima_iint_cache *iint; 179 BUG_ON(!mutex_is_locked(&iint->mutex));
218 int rc;
219 180
220 if (!ima_initialized || !S_ISREG(inode->i_mode)) 181 iint->opencount--;
221 return 0; 182 if ((mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
222 iint = ima_iint_find_insert_get(inode); 183 iint->readcount--;
223 if (!iint) 184 if (mode & FMODE_WRITE) {
224 return -ENOMEM; 185 iint->writecount--;
225 186 if (iint->writecount == 0) {
226 mutex_lock(&iint->mutex); 187 if (iint->version != inode->i_version)
227 rc = ima_must_measure(iint, inode, mask, function); 188 iint->flags &= ~IMA_MEASURED;
228 if (rc != 0) 189 }
229 goto out; 190 }
230 191
231 rc = ima_collect_measurement(iint, file); 192 if (((iint->opencount < 0) ||
232 if (!rc) 193 (iint->readcount < 0) ||
233 ima_store_measurement(iint, file, filename); 194 (iint->writecount < 0)) &&
234out: 195 !ima_limit_imbalance(file)) {
235 mutex_unlock(&iint->mutex); 196 printk(KERN_INFO "%s: open/free imbalance (r:%ld w:%ld o:%ld)\n",
236 kref_put(&iint->refcount, iint_free); 197 __FUNCTION__, iint->readcount, iint->writecount,
237 return rc; 198 iint->opencount);
199 dump_stack();
200 }
238} 201}
239 202
240/* 203/**
241 * ima_counts_put - decrement file counts 204 * ima_file_free - called on __fput()
205 * @file: pointer to file structure being freed
242 * 206 *
243 * File counts are incremented in ima_path_check. On file open 207 * Flag files that changed, based on i_version;
244 * error, such as ETXTBSY, decrement the counts to prevent 208 * and decrement the iint readcount/writecount.
245 * unnecessary imbalance messages.
246 */ 209 */
247void ima_counts_put(struct path *path, int mask) 210void ima_file_free(struct file *file)
248{ 211{
249 struct inode *inode = path->dentry->d_inode; 212 struct inode *inode = file->f_dentry->d_inode;
250 struct ima_iint_cache *iint; 213 struct ima_iint_cache *iint;
251 214
252 /* The inode may already have been freed, freeing the iint 215 if (!ima_initialized || !S_ISREG(inode->i_mode))
253 * with it. Verify the inode is not NULL before dereferencing
254 * it.
255 */
256 if (!ima_initialized || !inode || !S_ISREG(inode->i_mode))
257 return; 216 return;
258 iint = ima_iint_find_insert_get(inode); 217 iint = ima_iint_find_get(inode);
259 if (!iint) 218 if (!iint)
260 return; 219 return;
261 220
262 mutex_lock(&iint->mutex); 221 mutex_lock(&iint->mutex);
263 iint->opencount--; 222 ima_dec_counts(iint, inode, file);
264 if ((mask & MAY_WRITE) || (mask == 0))
265 iint->writecount--;
266 else if (mask & (MAY_READ | MAY_EXEC))
267 iint->readcount--;
268 mutex_unlock(&iint->mutex); 223 mutex_unlock(&iint->mutex);
269
270 kref_put(&iint->refcount, iint_free); 224 kref_put(&iint->refcount, iint_free);
271} 225}
272 226
273/* 227static int process_measurement(struct file *file, const unsigned char *filename,
274 * ima_counts_get - increment file counts 228 int mask, int function)
275 *
276 * - for IPC shm and shmat file.
277 * - for nfsd exported files.
278 *
279 * Increment the counts for these files to prevent unnecessary
280 * imbalance messages.
281 */
282void ima_counts_get(struct file *file)
283{ 229{
284 struct inode *inode = file->f_dentry->d_inode; 230 struct inode *inode = file->f_dentry->d_inode;
285 struct ima_iint_cache *iint; 231 struct ima_iint_cache *iint;
232 int rc;
286 233
287 if (!ima_initialized || !S_ISREG(inode->i_mode)) 234 if (!ima_initialized || !S_ISREG(inode->i_mode))
288 return; 235 return 0;
289 iint = ima_iint_find_insert_get(inode); 236 iint = ima_iint_find_get(inode);
290 if (!iint) 237 if (!iint)
291 return; 238 return -ENOMEM;
239
292 mutex_lock(&iint->mutex); 240 mutex_lock(&iint->mutex);
293 iint->opencount++; 241 rc = ima_must_measure(iint, inode, mask, function);
294 if ((file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) 242 if (rc != 0)
295 iint->readcount++; 243 goto out;
296 244
297 if (file->f_mode & FMODE_WRITE) 245 rc = ima_collect_measurement(iint, file);
298 iint->writecount++; 246 if (!rc)
247 ima_store_measurement(iint, file, filename);
248out:
299 mutex_unlock(&iint->mutex); 249 mutex_unlock(&iint->mutex);
300
301 kref_put(&iint->refcount, iint_free); 250 kref_put(&iint->refcount, iint_free);
251 return rc;
302} 252}
303EXPORT_SYMBOL_GPL(ima_counts_get);
304 253
305/** 254/**
306 * ima_file_mmap - based on policy, collect/store measurement. 255 * ima_file_mmap - based on policy, collect/store measurement.
@@ -347,11 +296,31 @@ int ima_bprm_check(struct linux_binprm *bprm)
347 return 0; 296 return 0;
348} 297}
349 298
299/**
300 * ima_path_check - based on policy, collect/store measurement.
301 * @file: pointer to the file to be measured
302 * @mask: contains MAY_READ, MAY_WRITE or MAY_EXECUTE
303 *
304 * Measure files based on the ima_must_measure() policy decision.
305 *
306 * Always return 0 and audit dentry_open failures.
307 * (Return code will be based upon measurement appraisal.)
308 */
309int ima_file_check(struct file *file, int mask)
310{
311 int rc;
312
313 rc = process_measurement(file, file->f_dentry->d_name.name,
314 mask & (MAY_READ | MAY_WRITE | MAY_EXEC),
315 FILE_CHECK);
316 return 0;
317}
318EXPORT_SYMBOL_GPL(ima_file_check);
319
350static int __init init_ima(void) 320static int __init init_ima(void)
351{ 321{
352 int error; 322 int error;
353 323
354 ima_iintcache_init();
355 error = ima_init(); 324 error = ima_init();
356 ima_initialized = 1; 325 ima_initialized = 1;
357 return error; 326 return error;
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index e1278399b345..4759d0f99335 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -67,7 +67,7 @@ static struct ima_measure_rule_entry default_rules[] = {
67 .flags = IMA_FUNC | IMA_MASK}, 67 .flags = IMA_FUNC | IMA_MASK},
68 {.action = MEASURE,.func = BPRM_CHECK,.mask = MAY_EXEC, 68 {.action = MEASURE,.func = BPRM_CHECK,.mask = MAY_EXEC,
69 .flags = IMA_FUNC | IMA_MASK}, 69 .flags = IMA_FUNC | IMA_MASK},
70 {.action = MEASURE,.func = PATH_CHECK,.mask = MAY_READ,.uid = 0, 70 {.action = MEASURE,.func = FILE_CHECK,.mask = MAY_READ,.uid = 0,
71 .flags = IMA_FUNC | IMA_MASK | IMA_UID}, 71 .flags = IMA_FUNC | IMA_MASK | IMA_UID},
72}; 72};
73 73
@@ -282,8 +282,11 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry)
282 break; 282 break;
283 case Opt_func: 283 case Opt_func:
284 audit_log_format(ab, "func=%s ", args[0].from); 284 audit_log_format(ab, "func=%s ", args[0].from);
285 if (strcmp(args[0].from, "PATH_CHECK") == 0) 285 if (strcmp(args[0].from, "FILE_CHECK") == 0)
286 entry->func = PATH_CHECK; 286 entry->func = FILE_CHECK;
287 /* PATH_CHECK is for backwards compat */
288 else if (strcmp(args[0].from, "PATH_CHECK") == 0)
289 entry->func = FILE_CHECK;
287 else if (strcmp(args[0].from, "FILE_MMAP") == 0) 290 else if (strcmp(args[0].from, "FILE_MMAP") == 0)
288 entry->func = FILE_MMAP; 291 entry->func = FILE_MMAP;
289 else if (strcmp(args[0].from, "BPRM_CHECK") == 0) 292 else if (strcmp(args[0].from, "BPRM_CHECK") == 0)
diff --git a/security/keys/gc.c b/security/keys/gc.c
index 4770be375ffe..19902319d097 100644
--- a/security/keys/gc.c
+++ b/security/keys/gc.c
@@ -77,7 +77,8 @@ static bool key_gc_keyring(struct key *keyring, time_t limit)
77 goto dont_gc; 77 goto dont_gc;
78 78
79 /* scan the keyring looking for dead keys */ 79 /* scan the keyring looking for dead keys */
80 klist = rcu_dereference(keyring->payload.subscriptions); 80 klist = rcu_dereference_check(keyring->payload.subscriptions,
81 lockdep_is_held(&key_serial_lock));
81 if (!klist) 82 if (!klist)
82 goto dont_gc; 83 goto dont_gc;
83 84
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index 06ec722897be..e9c2e7c584d9 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -1194,7 +1194,7 @@ long keyctl_get_security(key_serial_t keyid,
1194 * have the authorisation token handy */ 1194 * have the authorisation token handy */
1195 instkey = key_get_instantiation_authkey(keyid); 1195 instkey = key_get_instantiation_authkey(keyid);
1196 if (IS_ERR(instkey)) 1196 if (IS_ERR(instkey))
1197 return PTR_ERR(key_ref); 1197 return PTR_ERR(instkey);
1198 key_put(instkey); 1198 key_put(instkey);
1199 1199
1200 key_ref = lookup_user_key(keyid, KEY_LOOKUP_PARTIAL, 0); 1200 key_ref = lookup_user_key(keyid, KEY_LOOKUP_PARTIAL, 0);
@@ -1236,6 +1236,7 @@ long keyctl_get_security(key_serial_t keyid,
1236 */ 1236 */
1237long keyctl_session_to_parent(void) 1237long keyctl_session_to_parent(void)
1238{ 1238{
1239#ifdef TIF_NOTIFY_RESUME
1239 struct task_struct *me, *parent; 1240 struct task_struct *me, *parent;
1240 const struct cred *mycred, *pcred; 1241 const struct cred *mycred, *pcred;
1241 struct cred *cred, *oldcred; 1242 struct cred *cred, *oldcred;
@@ -1326,6 +1327,15 @@ not_permitted:
1326error_keyring: 1327error_keyring:
1327 key_ref_put(keyring_r); 1328 key_ref_put(keyring_r);
1328 return ret; 1329 return ret;
1330
1331#else /* !TIF_NOTIFY_RESUME */
1332 /*
1333 * To be removed when TIF_NOTIFY_RESUME has been implemented on
1334 * m68k/xtensa
1335 */
1336#warning TIF_NOTIFY_RESUME not implemented
1337 return -EOPNOTSUPP;
1338#endif /* !TIF_NOTIFY_RESUME */
1329} 1339}
1330 1340
1331/*****************************************************************************/ 1341/*****************************************************************************/
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index 8ec02746ca99..e814d2109f8e 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -151,7 +151,9 @@ static void keyring_destroy(struct key *keyring)
151 write_unlock(&keyring_name_lock); 151 write_unlock(&keyring_name_lock);
152 } 152 }
153 153
154 klist = rcu_dereference(keyring->payload.subscriptions); 154 klist = rcu_dereference_check(keyring->payload.subscriptions,
155 rcu_read_lock_held() ||
156 atomic_read(&keyring->usage) == 0);
155 if (klist) { 157 if (klist) {
156 for (loop = klist->nkeys - 1; loop >= 0; loop--) 158 for (loop = klist->nkeys - 1; loop >= 0; loop--)
157 key_put(klist->keys[loop]); 159 key_put(klist->keys[loop]);
diff --git a/security/min_addr.c b/security/min_addr.c
index fc43c9d37084..e86f297522bf 100644
--- a/security/min_addr.c
+++ b/security/min_addr.c
@@ -43,7 +43,7 @@ int mmap_min_addr_handler(struct ctl_table *table, int write,
43 return ret; 43 return ret;
44} 44}
45 45
46int __init init_mmap_min_addr(void) 46static int __init init_mmap_min_addr(void)
47{ 47{
48 update_mmap_min_addr(); 48 update_mmap_min_addr();
49 49
diff --git a/security/security.c b/security/security.c
index 24e060be9fa5..122b748d0f4c 100644
--- a/security/security.c
+++ b/security/security.c
@@ -666,8 +666,6 @@ int security_file_alloc(struct file *file)
666void security_file_free(struct file *file) 666void security_file_free(struct file *file)
667{ 667{
668 security_ops->file_free_security(file); 668 security_ops->file_free_security(file);
669 if (file->f_dentry)
670 ima_file_free(file);
671} 669}
672 670
673int security_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 671int security_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 7a374c2eb043..9a2ee845e9d4 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2365,7 +2365,7 @@ static void selinux_bprm_committing_creds(struct linux_binprm *bprm)
2365 initrlim = init_task.signal->rlim + i; 2365 initrlim = init_task.signal->rlim + i;
2366 rlim->rlim_cur = min(rlim->rlim_max, initrlim->rlim_cur); 2366 rlim->rlim_cur = min(rlim->rlim_max, initrlim->rlim_cur);
2367 } 2367 }
2368 update_rlimit_cpu(rlim->rlim_cur); 2368 update_rlimit_cpu(current->signal->rlim[RLIMIT_CPU].rlim_cur);
2369 } 2369 }
2370} 2370}
2371 2371
diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c
index e68823741ad5..2534400317c5 100644
--- a/security/selinux/netlabel.c
+++ b/security/selinux/netlabel.c
@@ -204,7 +204,7 @@ int selinux_netlbl_skbuff_getsid(struct sk_buff *skb,
204 * 204 *
205 * Description 205 * Description
206 * Call the NetLabel mechanism to set the label of a packet using @sid. 206 * Call the NetLabel mechanism to set the label of a packet using @sid.
207 * Returns zero on auccess, negative values on failure. 207 * Returns zero on success, negative values on failure.
208 * 208 *
209 */ 209 */
210int selinux_netlbl_skbuff_setsid(struct sk_buff *skb, 210int selinux_netlbl_skbuff_setsid(struct sk_buff *skb,
diff --git a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c
index 68c7348d1acc..04b6145d767f 100644
--- a/security/selinux/ss/ebitmap.c
+++ b/security/selinux/ss/ebitmap.c
@@ -128,7 +128,7 @@ int ebitmap_netlbl_export(struct ebitmap *ebmap,
128 cmap_idx = delta / NETLBL_CATMAP_MAPSIZE; 128 cmap_idx = delta / NETLBL_CATMAP_MAPSIZE;
129 cmap_sft = delta % NETLBL_CATMAP_MAPSIZE; 129 cmap_sft = delta % NETLBL_CATMAP_MAPSIZE;
130 c_iter->bitmap[cmap_idx] 130 c_iter->bitmap[cmap_idx]
131 |= e_iter->maps[cmap_idx] << cmap_sft; 131 |= e_iter->maps[i] << cmap_sft;
132 } 132 }
133 e_iter = e_iter->next; 133 e_iter = e_iter->next;
134 } 134 }
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index d6bb20cbad62..b3efae204ac7 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -836,7 +836,7 @@ int security_bounded_transition(u32 old_sid, u32 new_sid)
836 goto out; 836 goto out;
837 } 837 }
838 838
839 /* type/domain unchaned */ 839 /* type/domain unchanged */
840 if (old_context->type == new_context->type) { 840 if (old_context->type == new_context->type) {
841 rc = 0; 841 rc = 0;
842 goto out; 842 goto out;
diff --git a/security/tomoyo/file.c b/security/tomoyo/file.c
index 8346938809b1..9a6c58881c0a 100644
--- a/security/tomoyo/file.c
+++ b/security/tomoyo/file.c
@@ -12,7 +12,6 @@
12#include "common.h" 12#include "common.h"
13#include "tomoyo.h" 13#include "tomoyo.h"
14#include "realpath.h" 14#include "realpath.h"
15#define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE])
16 15
17/* 16/*
18 * tomoyo_globally_readable_file_entry is a structure which is used for holding 17 * tomoyo_globally_readable_file_entry is a structure which is used for holding
diff --git a/security/tomoyo/tomoyo.c b/security/tomoyo/tomoyo.c
index 8a00ade85166..2aceebf5f354 100644
--- a/security/tomoyo/tomoyo.c
+++ b/security/tomoyo/tomoyo.c
@@ -80,9 +80,8 @@ static int tomoyo_bprm_check_security(struct linux_binprm *bprm)
80 return tomoyo_find_next_domain(bprm); 80 return tomoyo_find_next_domain(bprm);
81 /* 81 /*
82 * Read permission is checked against interpreters using next domain. 82 * Read permission is checked against interpreters using next domain.
83 * '1' is the result of open_to_namei_flags(O_RDONLY).
84 */ 83 */
85 return tomoyo_check_open_permission(domain, &bprm->file->f_path, 1); 84 return tomoyo_check_open_permission(domain, &bprm->file->f_path, O_RDONLY);
86} 85}
87 86
88static int tomoyo_path_truncate(struct path *path, loff_t length, 87static int tomoyo_path_truncate(struct path *path, loff_t length,
@@ -184,10 +183,6 @@ static int tomoyo_file_fcntl(struct file *file, unsigned int cmd,
184static int tomoyo_dentry_open(struct file *f, const struct cred *cred) 183static int tomoyo_dentry_open(struct file *f, const struct cred *cred)
185{ 184{
186 int flags = f->f_flags; 185 int flags = f->f_flags;
187
188 if ((flags + 1) & O_ACCMODE)
189 flags++;
190 flags |= f->f_flags & (O_APPEND | O_TRUNC);
191 /* Don't check read permission here if called from do_execve(). */ 186 /* Don't check read permission here if called from do_execve(). */
192 if (current->in_execve) 187 if (current->in_execve)
193 return 0; 188 return 0;