aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorJarkko Sakkinen <jarkko.sakkinen@intel.com>2011-09-08 03:12:01 -0400
committerCasey Schaufler <cschaufler@cschaufler-intel.(none)>2011-10-12 17:21:32 -0400
commit828716c28fe4aa232ea280ea8ed6fb103eefb6ac (patch)
treef75377cf3e770a9a67feb64fb8bef867735a975b /security
parent545a7260343bbaf11c7f1a4b8c3d9660bb9266e5 (diff)
Smack: check permissions from user space (v2)
Adds a new file into SmackFS called 'access'. Wanted Smack permission is written into /smack/access. After that result can be read from the opened file. If access applies result contains 1 and otherwise 0. File access is protected from race conditions by using simple_transaction_get()/set() API. Fixes from the previous version: - Removed smack.h changes, refactoring left-over from previous version. - Removed #include <linux/smack.h>, refactoring left-over from previous version. Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@intel.com> Signed-off-by: Casey Schaufler <cschaufler@cschaufler-intel.(none)>
Diffstat (limited to 'security')
-rw-r--r--security/smack/smackfs.c180
1 files changed, 117 insertions, 63 deletions
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index f93460156dce..f4c28eeba1b1 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -44,6 +44,7 @@ enum smk_inos {
44 SMK_ONLYCAP = 9, /* the only "capable" label */ 44 SMK_ONLYCAP = 9, /* the only "capable" label */
45 SMK_LOGGING = 10, /* logging */ 45 SMK_LOGGING = 10, /* logging */
46 SMK_LOAD_SELF = 11, /* task specific rules */ 46 SMK_LOAD_SELF = 11, /* task specific rules */
47 SMK_ACCESSES = 12, /* access policy */
47}; 48};
48 49
49/* 50/*
@@ -176,71 +177,19 @@ static int smk_set_access(struct smack_rule *srp, struct list_head *rule_list,
176} 177}
177 178
178/** 179/**
179 * smk_write_load_list - write() for any /smack/load 180 * smk_parse_rule - parse subject, object and access type
180 * @file: file pointer, not actually used 181 * @data: string to be parsed whose size is SMK_LOADLEN
181 * @buf: where to get the data from 182 * @rule: parsed entities are stored in here
182 * @count: bytes sent
183 * @ppos: where to start - must be 0
184 * @rule_list: the list of rules to write to
185 * @rule_lock: lock for the rule list
186 *
187 * Get one smack access rule from above.
188 * The format is exactly:
189 * char subject[SMK_LABELLEN]
190 * char object[SMK_LABELLEN]
191 * char access[SMK_ACCESSLEN]
192 *
193 * writes must be SMK_LABELLEN+SMK_LABELLEN+SMK_ACCESSLEN bytes.
194 */ 183 */
195static ssize_t smk_write_load_list(struct file *file, const char __user *buf, 184static int smk_parse_rule(const char *data, struct smack_rule *rule)
196 size_t count, loff_t *ppos,
197 struct list_head *rule_list,
198 struct mutex *rule_lock)
199{ 185{
200 struct smack_rule *rule;
201 char *data;
202 int rc = -EINVAL;
203
204 /*
205 * No partial writes.
206 * Enough data must be present.
207 */
208 if (*ppos != 0)
209 return -EINVAL;
210 /*
211 * Minor hack for backward compatibility
212 */
213 if (count < (SMK_OLOADLEN) || count > SMK_LOADLEN)
214 return -EINVAL;
215
216 data = kzalloc(SMK_LOADLEN, GFP_KERNEL);
217 if (data == NULL)
218 return -ENOMEM;
219
220 if (copy_from_user(data, buf, count) != 0) {
221 rc = -EFAULT;
222 goto out;
223 }
224
225 /*
226 * More on the minor hack for backward compatibility
227 */
228 if (count == (SMK_OLOADLEN))
229 data[SMK_OLOADLEN] = '-';
230
231 rule = kzalloc(sizeof(*rule), GFP_KERNEL);
232 if (rule == NULL) {
233 rc = -ENOMEM;
234 goto out;
235 }
236
237 rule->smk_subject = smk_import(data, 0); 186 rule->smk_subject = smk_import(data, 0);
238 if (rule->smk_subject == NULL) 187 if (rule->smk_subject == NULL)
239 goto out_free_rule; 188 return -1;
240 189
241 rule->smk_object = smk_import(data + SMK_LABELLEN, 0); 190 rule->smk_object = smk_import(data + SMK_LABELLEN, 0);
242 if (rule->smk_object == NULL) 191 if (rule->smk_object == NULL)
243 goto out_free_rule; 192 return -1;
244 193
245 rule->smk_access = 0; 194 rule->smk_access = 0;
246 195
@@ -252,7 +201,7 @@ static ssize_t smk_write_load_list(struct file *file, const char __user *buf,
252 rule->smk_access |= MAY_READ; 201 rule->smk_access |= MAY_READ;
253 break; 202 break;
254 default: 203 default:
255 goto out_free_rule; 204 return -1;
256 } 205 }
257 206
258 switch (data[SMK_LABELLEN + SMK_LABELLEN + 1]) { 207 switch (data[SMK_LABELLEN + SMK_LABELLEN + 1]) {
@@ -263,7 +212,7 @@ static ssize_t smk_write_load_list(struct file *file, const char __user *buf,
263 rule->smk_access |= MAY_WRITE; 212 rule->smk_access |= MAY_WRITE;
264 break; 213 break;
265 default: 214 default:
266 goto out_free_rule; 215 return -1;
267 } 216 }
268 217
269 switch (data[SMK_LABELLEN + SMK_LABELLEN + 2]) { 218 switch (data[SMK_LABELLEN + SMK_LABELLEN + 2]) {
@@ -274,7 +223,7 @@ static ssize_t smk_write_load_list(struct file *file, const char __user *buf,
274 rule->smk_access |= MAY_EXEC; 223 rule->smk_access |= MAY_EXEC;
275 break; 224 break;
276 default: 225 default:
277 goto out_free_rule; 226 return -1;
278 } 227 }
279 228
280 switch (data[SMK_LABELLEN + SMK_LABELLEN + 3]) { 229 switch (data[SMK_LABELLEN + SMK_LABELLEN + 3]) {
@@ -285,7 +234,7 @@ static ssize_t smk_write_load_list(struct file *file, const char __user *buf,
285 rule->smk_access |= MAY_APPEND; 234 rule->smk_access |= MAY_APPEND;
286 break; 235 break;
287 default: 236 default:
288 goto out_free_rule; 237 return -1;
289 } 238 }
290 239
291 switch (data[SMK_LABELLEN + SMK_LABELLEN + 4]) { 240 switch (data[SMK_LABELLEN + SMK_LABELLEN + 4]) {
@@ -296,9 +245,74 @@ static ssize_t smk_write_load_list(struct file *file, const char __user *buf,
296 rule->smk_access |= MAY_TRANSMUTE; 245 rule->smk_access |= MAY_TRANSMUTE;
297 break; 246 break;
298 default: 247 default:
299 goto out_free_rule; 248 return -1;
300 } 249 }
301 250
251 return 0;
252}
253
254/**
255 * smk_write_load_list - write() for any /smack/load
256 * @file: file pointer, not actually used
257 * @buf: where to get the data from
258 * @count: bytes sent
259 * @ppos: where to start - must be 0
260 * @rule_list: the list of rules to write to
261 * @rule_lock: lock for the rule list
262 *
263 * Get one smack access rule from above.
264 * The format is exactly:
265 * char subject[SMK_LABELLEN]
266 * char object[SMK_LABELLEN]
267 * char access[SMK_ACCESSLEN]
268 *
269 * writes must be SMK_LABELLEN+SMK_LABELLEN+SMK_ACCESSLEN bytes.
270 */
271static ssize_t smk_write_load_list(struct file *file, const char __user *buf,
272 size_t count, loff_t *ppos,
273 struct list_head *rule_list,
274 struct mutex *rule_lock)
275{
276 struct smack_rule *rule;
277 char *data;
278 int rc = -EINVAL;
279
280 /*
281 * No partial writes.
282 * Enough data must be present.
283 */
284 if (*ppos != 0)
285 return -EINVAL;
286 /*
287 * Minor hack for backward compatibility
288 */
289 if (count < (SMK_OLOADLEN) || count > SMK_LOADLEN)
290 return -EINVAL;
291
292 data = kzalloc(SMK_LOADLEN, GFP_KERNEL);
293 if (data == NULL)
294 return -ENOMEM;
295
296 if (copy_from_user(data, buf, count) != 0) {
297