1
2
3
4
5
6
7
8
9
10
11#include <linux/tty.h>
12#include <linux/fdtable.h>
13#include <linux/file.h>
14#include <linux/fs.h>
15#include <linux/mount.h>
16
17#include "include/apparmor.h"
18#include "include/audit.h"
19#include "include/cred.h"
20#include "include/file.h"
21#include "include/match.h"
22#include "include/net.h"
23#include "include/path.h"
24#include "include/policy.h"
25#include "include/label.h"
26
27static u32 map_mask_to_chr_mask(u32 mask)
28{
29 u32 m = mask & PERMS_CHRS_MASK;
30
31 if (mask & AA_MAY_GETATTR)
32 m |= MAY_READ;
33 if (mask & (AA_MAY_SETATTR | AA_MAY_CHMOD | AA_MAY_CHOWN))
34 m |= MAY_WRITE;
35
36 return m;
37}
38
39
40
41
42
43
44static void file_audit_cb(struct audit_buffer *ab, void *va)
45{
46 struct common_audit_data *sa = va;
47 kuid_t fsuid = current_fsuid();
48 char str[10];
49
50 if (aad(sa)->request & AA_AUDIT_FILE_MASK) {
51 aa_perm_mask_to_str(str, sizeof(str), aa_file_perm_chrs,
52 map_mask_to_chr_mask(aad(sa)->request));
53 audit_log_format(ab, " requested_mask=\"%s\"", str);
54 }
55 if (aad(sa)->denied & AA_AUDIT_FILE_MASK) {
56 aa_perm_mask_to_str(str, sizeof(str), aa_file_perm_chrs,
57 map_mask_to_chr_mask(aad(sa)->denied));
58 audit_log_format(ab, " denied_mask=\"%s\"", str);
59 }
60 if (aad(sa)->request & AA_AUDIT_FILE_MASK) {
61 audit_log_format(ab, " fsuid=%d",
62 from_kuid(&init_user_ns, fsuid));
63 audit_log_format(ab, " ouid=%d",
64 from_kuid(&init_user_ns, aad(sa)->fs.ouid));
65 }
66
67 if (aad(sa)->peer) {
68 audit_log_format(ab, " target=");
69 aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer,
70 FLAG_VIEW_SUBNS, GFP_KERNEL);
71 } else if (aad(sa)->fs.target) {
72 audit_log_format(ab, " target=");
73 audit_log_untrustedstring(ab, aad(sa)->fs.target);
74 }
75}
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92int aa_audit_file(struct aa_profile *profile, struct aa_perms *perms,
93 const char *op, u32 request, const char *name,
94 const char *target, struct aa_label *tlabel,
95 kuid_t ouid, const char *info, int error)
96{
97 int type = AUDIT_APPARMOR_AUTO;
98 DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_TASK, op);
99
100 sa.u.tsk = NULL;
101 aad(&sa)->request = request;
102 aad(&sa)->name = name;
103 aad(&sa)->fs.target = target;
104 aad(&sa)->peer = tlabel;
105 aad(&sa)->fs.ouid = ouid;
106 aad(&sa)->info = info;
107 aad(&sa)->error = error;
108 sa.u.tsk = NULL;
109
110 if (likely(!aad(&sa)->error)) {
111 u32 mask = perms->audit;
112
113 if (unlikely(AUDIT_MODE(profile) == AUDIT_ALL))
114 mask = 0xffff;
115
116
117 aad(&sa)->request &= mask;
118
119 if (likely(!aad(&sa)->request))
120 return 0;
121 type = AUDIT_APPARMOR_AUDIT;
122 } else {
123
124 aad(&sa)->request = aad(&sa)->request & ~perms->allow;
125 AA_BUG(!aad(&sa)->request);
126
127 if (aad(&sa)->request & perms->kill)
128 type = AUDIT_APPARMOR_KILL;
129
130
131 if ((aad(&sa)->request & perms->quiet) &&
132 AUDIT_MODE(profile) != AUDIT_NOQUIET &&
133 AUDIT_MODE(profile) != AUDIT_ALL)
134 aad(&sa)->request &= ~perms->quiet;
135
136 if (!aad(&sa)->request)
137 return aad(&sa)->error;
138 }
139
140 aad(&sa)->denied = aad(&sa)->request & ~perms->allow;
141 return aa_audit(type, profile, &sa, file_audit_cb);
142}
143
144
145
146
147
148
149
150static inline bool is_deleted(struct dentry *dentry)
151{
152 if (d_unlinked(dentry) && d_backing_inode(dentry)->i_nlink == 0)
153 return true;
154 return false;
155}
156
157static int path_name(const char *op, struct aa_label *label,
158 const struct path *path, int flags, char *buffer,
159 const char **name, struct path_cond *cond, u32 request)
160{
161 struct aa_profile *profile;
162 const char *info = NULL;
163 int error;
164
165 error = aa_path_name(path, flags, buffer, name, &info,
166 labels_profile(label)->disconnected);
167 if (error) {
168 fn_for_each_confined(label, profile,
169 aa_audit_file(profile, &nullperms, op, request, *name,
170 NULL, NULL, cond->uid, info, error));
171 return error;
172 }
173
174 return 0;
175}
176
177
178
179
180
181
182
183static u32 map_old_perms(u32 old)
184{
185 u32 new = old & 0xf;
186 if (old & MAY_READ)
187 new |= AA_MAY_GETATTR | AA_MAY_OPEN;
188 if (old & MAY_WRITE)
189 new |= AA_MAY_SETATTR | AA_MAY_CREATE | AA_MAY_DELETE |
190 AA_MAY_CHMOD | AA_MAY_CHOWN | AA_MAY_OPEN;
191 if (old & 0x10)
192 new |= AA_MAY_LINK;
193
194
195
196 if (old & 0x20)
197 new |= AA_MAY_LOCK | AA_LINK_SUBSET;
198 if (old & 0x40)
199 new |= AA_EXEC_MMAP;
200
201 return new;
202}
203
204
205
206
207
208
209
210
211
212
213
214
215struct aa_perms aa_compute_fperms(struct aa_dfa *dfa, unsigned int state,
216 struct path_cond *cond)
217{
218
219
220
221
222
223 struct aa_perms perms = { };
224
225 if (uid_eq(current_fsuid(), cond->uid)) {
226 perms.allow = map_old_perms(dfa_user_allow(dfa, state));
227 perms.audit = map_old_perms(dfa_user_audit(dfa, state));
228 perms.quiet = map_old_perms(dfa_user_quiet(dfa, state));
229 perms.xindex = dfa_user_xindex(dfa, state);
230 } else {
231 perms.allow = map_old_perms(dfa_other_allow(dfa, state));
232 perms.audit = map_old_perms(dfa_other_audit(dfa, state));
233 perms.quiet = map_old_perms(dfa_other_quiet(dfa, state));
234 perms.xindex = dfa_other_xindex(dfa, state);
235 }
236 perms.allow |= AA_MAY_GETATTR;
237
238
239 if (ACCEPT_TABLE(dfa)[state] & 0x80000000)
240 perms.allow |= AA_MAY_CHANGE_PROFILE;
241 if (ACCEPT_TABLE(dfa)[state] & 0x40000000)
242 perms.allow |= AA_MAY_ONEXEC;
243
244 return perms;
245}
246
247
248
249
250
251
252
253
254
255
256
257unsigned int aa_str_perms(struct aa_dfa *dfa, unsigned int start,
258 const char *name, struct path_cond *cond,
259 struct aa_perms *perms)
260{
261 unsigned int state;
262 state = aa_dfa_match(dfa, start, name);
263 *perms = aa_compute_fperms(dfa, state, cond);
264
265 return state;
266}
267
268int __aa_path_perm(const char *op, struct aa_profile *profile, const char *name,
269 u32 request, struct path_cond *cond, int flags,
270 struct aa_perms *perms)
271{
272 int e = 0;
273
274 if (profile_unconfined(profile))
275 return 0;
276 aa_str_perms(profile->file.dfa, profile->file.start, name, cond, perms);
277 if (request & ~perms->allow)
278 e = -EACCES;
279 return aa_audit_file(profile, perms, op, request, name, NULL, NULL,
280 cond->uid, NULL, e);
281}
282
283
284static int profile_path_perm(const char *op, struct aa_profile *profile,
285 const struct path *path, char *buffer, u32 request,
286 struct path_cond *cond, int flags,
287 struct aa_perms *perms)
288{
289 const char *name;
290 int error;
291
292 if (profile_unconfined(profile))
293 return 0;
294
295 error = path_name(op, &profile->label, path,
296 flags | profile->path_flags, buffer, &name, cond,
297 request);
298 if (error)
299 return error;
300 return __aa_path_perm(op, profile, name, request, cond, flags,
301 perms);
302}
303
304
305
306
307
308
309
310
311
312
313
314
315int aa_path_perm(const char *op, struct aa_label *label,
316 const struct path *path, int flags, u32 request,
317 struct path_cond *cond)
318{
319 struct aa_perms perms = {};
320 struct aa_profile *profile;
321 char *buffer = NULL;
322 int error;
323
324 flags |= PATH_DELEGATE_DELETED | (S_ISDIR(cond->mode) ? PATH_IS_DIR :
325 0);
326 buffer = aa_get_buffer(false);
327 if (!buffer)
328 return -ENOMEM;
329 error = fn_for_each_confined(label, profile,
330 profile_path_perm(op, profile, path, buffer, request,
331 cond, flags, &perms));
332
333 aa_put_buffer(buffer);
334
335 return error;
336}
337
338
339
340
341
342
343
344
345
346
347
348
349static inline bool xindex_is_subset(u32 link, u32 target)
350{
351 if (((link & ~AA_X_UNSAFE) != (target & ~AA_X_UNSAFE)) ||
352 ((link & AA_X_UNSAFE) && !(target & AA_X_UNSAFE)))
353 return false;
354
355 return true;
356}
357
358static int profile_path_link(struct aa_profile *profile,
359 const struct path *link, char *buffer,
360 const struct path *target, char *buffer2,
361 struct path_cond *cond)
362{
363 const char *lname, *tname = NULL;
364 struct aa_perms lperms = {}, perms;
365 const char *info = NULL;
366 u32 request = AA_MAY_LINK;
367 unsigned int state;
368 int error;
369
370 error = path_name(OP_LINK, &profile->label, link, profile->path_flags,
371 buffer, &lname, cond, AA_MAY_LINK);
372 if (error)
373 goto audit;
374
375
376 error = path_name(OP_LINK, &profile->label, target, profile->path_flags,
377 buffer2, &tname, cond, AA_MAY_LINK);
378 if (error)
379 goto audit;
380
381 error = -EACCES;
382
383 state = aa_str_perms(profile->file.dfa, profile->file.start, lname,
384 cond, &lperms);
385
386 if (!(lperms.allow & AA_MAY_LINK))
387 goto audit;
388
389
390 state = aa_dfa_null_transition(profile->file.dfa, state);
391 aa_str_perms(profile->file.dfa, state, tname, cond, &perms);
392
393
394
395
396 lperms.audit = perms.audit;
397 lperms.quiet = perms.quiet;
398 lperms.kill = perms.kill;
399
400 if (!(perms.allow & AA_MAY_LINK)) {
401 info = "target restricted";
402 lperms = perms;
403 goto audit;
404 }
405
406
407 if (!(perms.allow & AA_LINK_SUBSET))
408 goto done_tests;
409
410
411
412
413 aa_str_perms(profile->file.dfa, profile->file.start, tname, cond,
414 &perms);
415
416
417 request = lperms.allow & ~AA_MAY_LINK;
418 lperms.allow &= perms.allow | AA_MAY_LINK;
419
420 request |= AA_AUDIT_FILE_MASK & (lperms.allow & ~perms.allow);
421 if (request & ~lperms.allow) {
422 goto audit;
423 } else if ((lperms.allow & MAY_EXEC) &&
424 !xindex_is_subset(lperms.xindex, perms.xindex)) {
425 lperms.allow &= ~MAY_EXEC;
426 request |= MAY_EXEC;
427 info = "link not subset of target";
428 goto audit;
429 }
430
431done_tests:
432 error = 0;
433
434audit:
435 return aa_audit_file(profile, &lperms, OP_LINK, request, lname, tname,
436 NULL, cond->uid, info, error);
437}
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457int aa_path_link(struct aa_label *label, struct dentry *old_dentry,
458 const struct path *new_dir, struct dentry *new_dentry)
459{
460 struct path link = { .mnt = new_dir->mnt, .dentry = new_dentry };
461 struct path target = { .mnt = new_dir->mnt, .dentry = old_dentry };
462 struct path_cond cond = {
463 d_backing_inode(old_dentry)->i_uid,
464 d_backing_inode(old_dentry)->i_mode
465 };
466 char *buffer = NULL, *buffer2 = NULL;
467 struct aa_profile *profile;
468 int error;
469
470
471 buffer = aa_get_buffer(false);
472 buffer2 = aa_get_buffer(false);
473 error = -ENOMEM;
474 if (!buffer || !buffer2)
475 goto out;
476
477 error = fn_for_each_confined(label, profile,
478 profile_path_link(profile, &link, buffer, &target,
479 buffer2, &cond));
480out:
481 aa_put_buffer(buffer);
482 aa_put_buffer(buffer2);
483 return error;
484}
485
486static void update_file_ctx(struct aa_file_ctx *fctx, struct aa_label *label,
487 u32 request)
488{
489 struct aa_label *l, *old;
490
491
492 spin_lock(&fctx->lock);
493 old = rcu_dereference_protected(fctx->label,
494 lockdep_is_held(&fctx->lock));
495 l = aa_label_merge(old, label, GFP_ATOMIC);
496 if (l) {
497 if (l != old) {
498 rcu_assign_pointer(fctx->label, l);
499 aa_put_label(old);
500 } else
501 aa_put_label(l);
502 fctx->allow |= request;
503 }
504 spin_unlock(&fctx->lock);
505}
506
507static int __file_path_perm(const char *op, struct aa_label *label,
508 struct aa_label *flabel, struct file *file,
509 u32 request, u32 denied, bool in_atomic)
510{
511 struct aa_profile *profile;
512 struct aa_perms perms = {};
513 struct path_cond cond = {
514 .uid = i_uid_into_mnt(file_mnt_user_ns(file), file_inode(file)),
515 .mode = file_inode(file)->i_mode
516 };
517 char *buffer;
518 int flags, error;
519
520
521 if (!denied && aa_label_is_subset(flabel, label))
522
523 return 0;
524
525 flags = PATH_DELEGATE_DELETED | (S_ISDIR(cond.mode) ? PATH_IS_DIR : 0);
526 buffer = aa_get_buffer(in_atomic);
527 if (!buffer)
528 return -ENOMEM;
529
530
531 error = fn_for_each_not_in_set(flabel, label, profile,
532 profile_path_perm(op, profile, &file->f_path, buffer,
533 request, &cond, flags, &perms));
534 if (denied && !error) {
535
536
537
538
539
540
541
542
543 if (label == flabel)
544 error = fn_for_each(label, profile,
545 profile_path_perm(op, profile, &file->f_path,
546 buffer, request, &cond, flags,
547 &perms));
548 else
549 error = fn_for_each_not_in_set(label, flabel, profile,
550 profile_path_perm(op, profile, &file->f_path,
551 buffer, request, &cond, flags,
552 &perms));
553 }
554 if (!error)
555 update_file_ctx(file_ctx(file), label, request);
556
557 aa_put_buffer(buffer);
558
559 return error;
560}
561
562static int __file_sock_perm(const char *op, struct aa_label *label,
563 struct aa_label *flabel, struct file *file,
564 u32 request, u32 denied)
565{
566 struct socket *sock = (struct socket *) file->private_data;
567 int error;
568
569 AA_BUG(!sock);
570
571
572 if (!denied && aa_label_is_subset(flabel, label))
573 return 0;
574
575
576 error = aa_sock_file_perm(label, op, request, sock);
577 if (denied) {
578
579
580 last_error(error, aa_sock_file_perm(flabel, op, request, sock));
581 }
582 if (!error)
583 update_file_ctx(file_ctx(file), label, request);
584
585 return error;
586}
587
588
589
590
591
592
593
594
595
596
597
598int aa_file_perm(const char *op, struct aa_label *label, struct file *file,
599 u32 request, bool in_atomic)
600{
601 struct aa_file_ctx *fctx;
602 struct aa_label *flabel;
603 u32 denied;
604 int error = 0;
605
606 AA_BUG(!label);
607 AA_BUG(!file);
608
609 fctx = file_ctx(file);
610
611 rcu_read_lock();
612 flabel = rcu_dereference(fctx->label);
613 AA_BUG(!flabel);
614
615
616
617
618
619
620
621
622 denied = request & ~fctx->allow;
623 if (unconfined(label) || unconfined(flabel) ||
624 (!denied && aa_label_is_subset(flabel, label))) {
625 rcu_read_unlock();
626 goto done;
627 }
628
629 flabel = aa_get_newest_label(flabel);
630 rcu_read_unlock();
631
632
633 if (file->f_path.mnt && path_mediated_fs(file->f_path.dentry))
634 error = __file_path_perm(op, label, flabel, file, request,
635 denied, in_atomic);
636
637 else if (S_ISSOCK(file_inode(file)->i_mode))
638 error = __file_sock_perm(op, label, flabel, file, request,
639 denied);
640 aa_put_label(flabel);
641
642done:
643 return error;
644}
645
646static void revalidate_tty(struct aa_label *label)
647{
648 struct tty_struct *tty;
649 int drop_tty = 0;
650
651 tty = get_current_tty();
652 if (!tty)
653 return;
654
655 spin_lock(&tty->files_lock);
656 if (!list_empty(&tty->tty_files)) {
657 struct tty_file_private *file_priv;
658 struct file *file;
659
660 file_priv = list_first_entry(&tty->tty_files,
661 struct tty_file_private, list);
662 file = file_priv->file;
663
664 if (aa_file_perm(OP_INHERIT, label, file, MAY_READ | MAY_WRITE,
665 IN_ATOMIC))
666 drop_tty = 1;
667 }
668 spin_unlock(&tty->files_lock);
669 tty_kref_put(tty);
670
671 if (drop_tty)
672 no_tty();
673}
674
675static int match_file(const void *p, struct file *file, unsigned int fd)
676{
677 struct aa_label *label = (struct aa_label *)p;
678
679 if (aa_file_perm(OP_INHERIT, label, file, aa_map_file_to_perms(file),
680 IN_ATOMIC))
681 return fd + 1;
682 return 0;
683}
684
685
686
687void aa_inherit_files(const struct cred *cred, struct files_struct *files)
688{
689 struct aa_label *label = aa_get_newest_cred_label(cred);
690 struct file *devnull = NULL;
691 unsigned int n;
692
693 revalidate_tty(label);
694
695
696 n = iterate_fd(files, 0, match_file, label);
697 if (!n)
698 goto out;
699
700 devnull = dentry_open(&aa_null, O_RDWR, cred);
701 if (IS_ERR(devnull))
702 devnull = NULL;
703
704 do {
705 replace_fd(n - 1, devnull, 0);
706 } while ((n = iterate_fd(files, n, match_file, label)) != 0);
707 if (devnull)
708 fput(devnull);
709out:
710 aa_put_label(label);
711}
712