~mathiaz/apparmor/ubuntu-mathiaz

« back to all changes in this revision

Viewing changes to module/apparmor/lsm.c

  • Committer: Mathias Gug
  • Date: 2008-02-04 18:57:00 UTC
  • mfrom: (885.1.5 apparmor)
  • Revision ID: mathiaz@ubuntu.com-20080204185700-wwlyq0ksssxclv8w
Merge  ubuntu branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 *      Copyright (C) 2002-2005 Novell/SUSE
3
 
 *
4
 
 *      This program is free software; you can redistribute it and/or
5
 
 *      modify it under the terms of the GNU General Public License as
6
 
 *      published by the Free Software Foundation, version 2 of the
7
 
 *      License.
8
 
 *
9
 
 *      http://forge.novell.com/modules/xfmod/project/?apparmor
10
 
 *
11
 
 *      Immunix AppArmor LSM interface
12
 
 */
13
 
 
14
 
#include <linux/security.h>
15
 
#include <linux/module.h>
16
 
#include <linux/mm.h>
17
 
#include <linux/mman.h>
18
 
 
19
 
#include "apparmor.h"
20
 
#include "inline.h"
21
 
 
22
 
/* struct subdomain write update lock (read side is RCU). */
23
 
spinlock_t sd_lock = SPIN_LOCK_UNLOCKED;
24
 
 
25
 
/* point to the apparmor module */
26
 
struct module *aa_module = NULL;
27
 
 
28
 
/* secondary ops if apparmor is stacked */
29
 
static struct security_operations *aa_secondary_ops = NULL;
30
 
static DEFINE_MUTEX(aa_secondary_lock);
31
 
 
32
 
#if 0
33
 
#define AA_SECONDARY(ERROR, FN, ARGS...) \
34
 
        ({ \
35
 
         struct security_operations *__f1; \
36
 
         rcu_read_lock(); \
37
 
         __f1 = rcu_dereference(aa_secondary_ops); \
38
 
         rcu_read_unlock(); \
39
 
         (!(ERROR) && unlikely(__f1) && __f1->FN) ? __f1->FN(ARGS) : (ERROR); \
40
 
         })
41
 
#endif
42
 
#define AA_SECONDARY(ERROR, FN, ARGS...) \
43
 
        ({ \
44
 
         struct security_operations *__f1; \
45
 
         if (!ERROR) { \
46
 
                rcu_read_lock(); \
47
 
                __f1 = rcu_dereference(aa_secondary_ops); \
48
 
                if (unlikely(__f1) && __f1->FN) \
49
 
                        (ERROR) = __f1->FN(ARGS); \
50
 
                rcu_read_unlock(); \
51
 
         } \
52
 
         (ERROR); \
53
 
         })
54
 
 
55
 
 
56
 
/* Flag values, also controllable via apparmorfs/control.
57
 
 * We explicitly do not allow these to be modifiable when exported via
58
 
 * /sys/modules/parameters, as we want to do additional mediation and
59
 
 * don't want to add special path code. */
60
 
 
61
 
/* Complain mode -- in complain mode access failures result in auditing only
62
 
 * and task is allowed access.  audit events are processed by userspace to
63
 
 * generate policy.  Default is 'enforce' (0).
64
 
 * Value is also togglable per profile and referenced when global value is
65
 
 * enforce.
66
 
 */
67
 
int apparmor_complain = 0;
68
 
module_param_named(complain, apparmor_complain, int, S_IRUSR);
69
 
MODULE_PARM_DESC(apparmor_complain, "Toggle AppArmor complain mode");
70
 
 
71
 
/* Debug mode */
72
 
int apparmor_debug = 0;
73
 
module_param_named(debug, apparmor_debug, int, S_IRUSR);
74
 
MODULE_PARM_DESC(apparmor_debug, "Toggle AppArmor debug mode");
75
 
 
76
 
/* Audit mode */
77
 
int apparmor_audit = 0;
78
 
module_param_named(audit, apparmor_audit, int, S_IRUSR);
79
 
MODULE_PARM_DESC(apparmor_audit, "Toggle AppArmor audit mode");
80
 
 
81
 
/* Syscall logging mode */
82
 
int apparmor_logsyscall = 0;
83
 
module_param_named(logsyscall, apparmor_logsyscall, int, S_IRUSR);
84
 
MODULE_PARM_DESC(apparmor_logsyscall, "Toggle AppArmor logsyscall mode");
85
 
 
86
 
#ifndef MODULE
87
 
static int __init aa_getopt_complain(char *str)
88
 
{
89
 
        get_option(&str, &apparmor_complain);
90
 
        return 1;
91
 
}
92
 
__setup("apparmor_complain=", aa_getopt_complain);
93
 
 
94
 
static int __init aa_getopt_debug(char *str)
95
 
{
96
 
        get_option(&str, &apparmor_debug);
97
 
        return 1;
98
 
}
99
 
__setup("apparmor_debug=", aa_getopt_debug);
100
 
 
101
 
static int __init aa_getopt_audit(char *str)
102
 
{
103
 
        get_option(&str, &apparmor_audit);
104
 
        return 1;
105
 
}
106
 
__setup("apparmor_audit=", aa_getopt_audit);
107
 
 
108
 
static int __init aa_getopt_logsyscall(char *str)
109
 
{
110
 
        get_option(&str, &apparmor_logsyscall);
111
 
        return 1;
112
 
}
113
 
__setup("apparmor_logsyscall=", aa_getopt_logsyscall);
114
 
#endif
115
 
 
116
 
static int apparmor_ptrace(struct task_struct *parent,
117
 
                            struct task_struct *child)
118
 
{
119
 
        int error;
120
 
        struct aaprofile *active;
121
 
 
122
 
        error = cap_ptrace(parent, child);
123
 
 
124
 
        active = get_task_active_aaprofile(parent);
125
 
 
126
 
        if (!error && active)
127
 
                error = aa_audit_syscallreject(active, GFP_ATOMIC,
128
 
                                               AA_SYSCALL_PTRACE);
129
 
 
130
 
        put_aaprofile(active);
131
 
 
132
 
        return error;
133
 
}
134
 
 
135
 
static int apparmor_capget(struct task_struct *target,
136
 
                            kernel_cap_t *effective,
137
 
                            kernel_cap_t *inheritable,
138
 
                            kernel_cap_t *permitted)
139
 
{
140
 
        return cap_capget(target, effective, inheritable, permitted);
141
 
}
142
 
 
143
 
static int apparmor_capset_check(struct task_struct *target,
144
 
                                  kernel_cap_t *effective,
145
 
                                  kernel_cap_t *inheritable,
146
 
                                  kernel_cap_t *permitted)
147
 
{
148
 
        return cap_capset_check(target, effective, inheritable, permitted);
149
 
}
150
 
 
151
 
static void apparmor_capset_set(struct task_struct *target,
152
 
                                 kernel_cap_t *effective,
153
 
                                 kernel_cap_t *inheritable,
154
 
                                 kernel_cap_t *permitted)
155
 
{
156
 
        cap_capset_set(target, effective, inheritable, permitted);
157
 
        return;
158
 
}
159
 
 
160
 
static int apparmor_capable(struct task_struct *tsk, int cap)
161
 
{
162
 
        int error;
163
 
 
164
 
        /* cap_capable returns 0 on success, else -EPERM */
165
 
        error = cap_capable(tsk, cap);
166
 
 
167
 
        if (error == 0) {
168
 
                struct aaprofile *active;
169
 
 
170
 
                active = get_task_active_aaprofile(tsk);
171
 
 
172
 
                if (active)
173
 
                        error = aa_capability(active, cap);
174
 
 
175
 
                put_aaprofile(active);
176
 
        }
177
 
 
178
 
        return error;
179
 
}
180
 
 
181
 
static int apparmor_sysctl(struct ctl_table *table, int op)
182
 
{
183
 
        int error = 0;
184
 
        struct aaprofile *active;
185
 
 
186
 
        active = get_active_aaprofile();
187
 
 
188
 
        if ((op & 002) && active && !capable(CAP_SYS_ADMIN))
189
 
                error = aa_audit_syscallreject(active, GFP_ATOMIC,
190
 
                                               AA_SYSCALL_SYSCTL_WRITE);
191
 
 
192
 
        put_aaprofile(active);
193
 
 
194
 
        return error;
195
 
}
196
 
 
197
 
static int apparmor_syslog(int type)
198
 
{
199
 
        return cap_syslog(type);
200
 
}
201
 
 
202
 
static int apparmor_netlink_send(struct sock *sk, struct sk_buff *skb)
203
 
{
204
 
        return cap_netlink_send(sk, skb);
205
 
}
206
 
 
207
 
static int apparmor_netlink_recv(struct sk_buff *skb, int cap)
208
 
{
209
 
        return cap_netlink_recv(skb, cap);
210
 
}
211
 
 
212
 
static void apparmor_bprm_apply_creds(struct linux_binprm *bprm, int unsafe)
213
 
{
214
 
        cap_bprm_apply_creds(bprm, unsafe);
215
 
        return;
216
 
}
217
 
 
218
 
static int apparmor_bprm_set_security(struct linux_binprm *bprm)
219
 
{
220
 
        /* handle capability bits with setuid, etc */
221
 
        cap_bprm_set_security(bprm);
222
 
        /* already set based on script name */
223
 
        if (bprm->sh_bang)
224
 
                return 0;
225
 
        return aa_register(bprm);
226
 
}
227
 
 
228
 
static int apparmor_bprm_secureexec(struct linux_binprm *bprm)
229
 
{
230
 
        int ret = cap_bprm_secureexec(bprm);
231
 
 
232
 
        if (ret == 0 &&
233
 
            (unsigned long)bprm->security & AA_SECURE_EXEC_NEEDED) {
234
 
                AA_DEBUG("%s: secureexec required for %s\n",
235
 
                         __FUNCTION__, bprm->filename);
236
 
                ret = 1;
237
 
        }
238
 
 
239
 
        return ret;
240
 
}
241
 
 
242
 
static int apparmor_sb_mount(char *dev_name, struct nameidata *nd, char *type,
243
 
                              unsigned long flags, void *data)
244
 
{
245
 
        int error = 0;
246
 
        struct aaprofile *active;
247
 
 
248
 
        active = get_active_aaprofile();
249
 
 
250
 
        if (active)
251
 
                error = aa_audit_syscallreject(active, GFP_ATOMIC,
252
 
                                               AA_SYSCALL_MOUNT);
253
 
 
254
 
        put_aaprofile(active);
255
 
 
256
 
        return error;
257
 
}
258
 
 
259
 
static int apparmor_umount(struct vfsmount *mnt, int flags)
260
 
{
261
 
        int error = 0;
262
 
        struct aaprofile *active;
263
 
 
264
 
        active = get_active_aaprofile();
265
 
 
266
 
        if (active)
267
 
                error = aa_audit_syscallreject(active, GFP_ATOMIC,
268
 
                                               AA_SYSCALL_UMOUNT);
269
 
 
270
 
        put_aaprofile(active);
271
 
 
272
 
        return error;
273
 
}
274
 
 
275
 
static int apparmor_inode_mkdir(struct inode *inode, struct dentry *dentry,
276
 
                                 int mask)
277
 
{
278
 
        struct aaprofile *active;
279
 
        int error = 0;
280
 
 
281
 
        active = get_active_aaprofile();
282
 
 
283
 
        if (active)
284
 
                error = aa_perm_dir(active, dentry, aa_dir_mkdir);
285
 
 
286
 
        put_aaprofile(active);
287
 
 
288
 
        return error;
289
 
}
290
 
 
291
 
static int apparmor_inode_rmdir(struct inode *inode, struct dentry *dentry)
292
 
{
293
 
        struct aaprofile *active;
294
 
        int error = 0;
295
 
 
296
 
        active = get_active_aaprofile();
297
 
 
298
 
        if (active)
299
 
                error = aa_perm_dir(active, dentry, aa_dir_rmdir);
300
 
 
301
 
        put_aaprofile(active);
302
 
 
303
 
        return error;
304
 
}
305
 
 
306
 
static int apparmor_inode_create(struct inode *inode, struct dentry *dentry,
307
 
                                  int mask)
308
 
{
309
 
        struct aaprofile *active;
310
 
        int error = 0;
311
 
 
312
 
        active = get_active_aaprofile();
313
 
 
314
 
        /* At a minimum, need write perm to create */
315
 
        if (active)
316
 
                error = aa_perm_dentry(active, dentry, MAY_WRITE);
317
 
 
318
 
        put_aaprofile(active);
319
 
 
320
 
        return error;
321
 
}
322
 
 
323
 
static int apparmor_inode_link(struct dentry *old_dentry, struct inode *inode,
324
 
                                struct dentry *new_dentry)
325
 
{
326
 
        int error = 0;
327
 
        struct aaprofile *active;
328
 
 
329
 
        active = get_active_aaprofile();
330
 
 
331
 
        if (active)
332
 
                error = aa_link(active, new_dentry, old_dentry);
333
 
 
334
 
        put_aaprofile(active);
335
 
 
336
 
        return error;
337
 
}
338
 
 
339
 
static int apparmor_inode_unlink(struct inode *inode, struct dentry *dentry)
340
 
{
341
 
        struct aaprofile *active;
342
 
        int error = 0;
343
 
 
344
 
        active = get_active_aaprofile();
345
 
 
346
 
        if (active)
347
 
                error = aa_perm_dentry(active, dentry, MAY_WRITE);
348
 
 
349
 
        put_aaprofile(active);
350
 
 
351
 
        return error;
352
 
}
353
 
 
354
 
static int apparmor_inode_symlink(struct inode *dir, struct dentry *dentry,
355
 
                                  const char *old_name)
356
 
{
357
 
        struct aaprofile *active;
358
 
        int error = 0;
359
 
 
360
 
        active = get_active_aaprofile();
361
 
 
362
 
        if (active)
363
 
                error = aa_perm_dentry(active, dentry, MAY_WRITE);
364
 
 
365
 
        put_aaprofile(active);
366
 
 
367
 
        return error;
368
 
}
369
 
 
370
 
static int apparmor_inode_mknod(struct inode *inode, struct dentry *dentry,
371
 
                                 int mode, dev_t dev)
372
 
{
373
 
        struct aaprofile *active;
374
 
        int error = 0;
375
 
 
376
 
        active = get_active_aaprofile();
377
 
 
378
 
        if (active)
379
 
                error = aa_perm_dentry(active, dentry, MAY_WRITE);
380
 
 
381
 
        put_aaprofile(active);
382
 
 
383
 
        return error;
384
 
}
385
 
 
386
 
static int apparmor_inode_rename(struct inode *old_inode,
387
 
                                  struct dentry *old_dentry,
388
 
                                  struct inode *new_inode,
389
 
                                  struct dentry *new_dentry)
390
 
{
391
 
        struct aaprofile *active;
392
 
        int error = 0;
393
 
 
394
 
        active = get_active_aaprofile();
395
 
 
396
 
        if (active) {
397
 
                error = aa_perm_dentry(active, old_dentry, MAY_READ |
398
 
                                       MAY_WRITE);
399
 
 
400
 
                if (!error)
401
 
                        error = aa_perm_dentry(active, new_dentry,
402
 
                                               MAY_WRITE);
403
 
        }
404
 
 
405
 
        put_aaprofile(active);
406
 
 
407
 
        return error;
408
 
}
409
 
 
410
 
static int apparmor_inode_permission(struct inode *inode, int mask,
411
 
                                      struct nameidata *nd)
412
 
{
413
 
        int error = 0;
414
 
 
415
 
        /* Do not perform check on pipes or sockets
416
 
         * Same as apparmor_file_permission
417
 
         */
418
 
        if (mediated_filesystem(inode)) {
419
 
                struct aaprofile *active;
420
 
 
421
 
                active = get_active_aaprofile();
422
 
                if (active)
423
 
                        error = aa_perm_nameidata(active, nd, mask);
424
 
                put_aaprofile(active);
425
 
        }
426
 
 
427
 
        error = AA_SECONDARY(error, inode_permission, inode, mask, nd);
428
 
 
429
 
        return error;
430
 
}
431
 
 
432
 
static int apparmor_inode_setattr(struct dentry *dentry, struct iattr *iattr)
433
 
{
434
 
        int error = 0;
435
 
 
436
 
        if (mediated_filesystem(dentry->d_inode)) {
437
 
                struct aaprofile *active;
438
 
 
439
 
                active = get_active_aaprofile();
440
 
                /*
441
 
                 * Mediate any attempt to change attributes of a file
442
 
                 * (chmod, chown, chgrp, etc)
443
 
                 */
444
 
                if (active)
445
 
                        error = aa_attr(active, dentry, iattr);
446
 
 
447
 
                put_aaprofile(active);
448
 
        }
449
 
 
450
 
        return error;
451
 
}
452
 
 
453
 
static int apparmor_inode_setxattr(struct dentry *dentry, char *name,
454
 
                                    void *value, size_t size, int flags)
455
 
{
456
 
        int error = 0;
457
 
 
458
 
        if (mediated_filesystem(dentry->d_inode)) {
459
 
                struct aaprofile *active;
460
 
 
461
 
                active = get_active_aaprofile();
462
 
                if (active)
463
 
                        error = aa_xattr(active, dentry, name, aa_xattr_set);
464
 
                put_aaprofile(active);
465
 
        }
466
 
 
467
 
        return error;
468
 
}
469
 
 
470
 
static int apparmor_inode_getxattr(struct dentry *dentry, char *name)
471
 
{
472
 
        int error = 0;
473
 
 
474
 
        if (mediated_filesystem(dentry->d_inode)) {
475
 
                struct aaprofile *active;
476
 
 
477
 
                active = get_active_aaprofile();
478
 
                if (active)
479
 
                        error = aa_xattr(active, dentry, name, aa_xattr_get);
480
 
                put_aaprofile(active);
481
 
        }
482
 
 
483
 
        return error;
484
 
}
485
 
static int apparmor_inode_listxattr(struct dentry *dentry)
486
 
{
487
 
        int error = 0;
488
 
 
489
 
        if (mediated_filesystem(dentry->d_inode)) {
490
 
                struct aaprofile *active;
491
 
 
492
 
                active = get_active_aaprofile();
493
 
                if (active)
494
 
                        error = aa_xattr(active, dentry, NULL, aa_xattr_list);
495
 
                put_aaprofile(active);
496
 
        }
497
 
 
498
 
        return error;
499
 
}
500
 
 
501
 
static int apparmor_inode_removexattr(struct dentry *dentry, char *name)
502
 
{
503
 
        int error = 0;
504
 
 
505
 
        if (mediated_filesystem(dentry->d_inode)) {
506
 
                struct aaprofile *active;
507
 
 
508
 
                active = get_active_aaprofile();
509
 
                if (active)
510
 
                        error = aa_xattr(active, dentry, name,
511
 
                                         aa_xattr_remove);
512
 
                put_aaprofile(active);
513
 
        }
514
 
 
515
 
        return error;
516
 
}
517
 
 
518
 
static int apparmor_file_permission(struct file *file, int mask)
519
 
{
520
 
        struct aaprofile *active;
521
 
        struct aafile *aaf;
522
 
        int error = 0;
523
 
 
524
 
        aaf = (struct aafile *)file->f_security;
525
 
        /* bail out early if this isn't a mediated file */
526
 
        if (!aaf || !mediated_filesystem(file->f_dentry->d_inode))
527
 
                goto out;
528
 
 
529
 
        active = get_active_aaprofile();
530
 
        if (active && aaf->profile != active)
531
 
                error = aa_perm(active, file->f_dentry, file->f_vfsmnt,
532
 
                                mask & (MAY_EXEC | MAY_WRITE | MAY_READ), 1);
533
 
        put_aaprofile(active);
534
 
 
535
 
out:
536
 
        return error;
537
 
}
538
 
 
539
 
static int apparmor_file_alloc_security(struct file *file)
540
 
{
541
 
        struct aaprofile *active;
542
 
        int error = 0;
543
 
 
544
 
        active = get_active_aaprofile();
545
 
        if (active) {
546
 
                struct aafile *aaf;
547
 
                aaf = kmalloc(sizeof(struct aafile), GFP_KERNEL);
548
 
 
549
 
                if (aaf) {
550
 
                        aaf->type = aa_file_default;
551
 
                        aaf->profile = get_aaprofile(active);
552
 
                } else {
553
 
                        error = -ENOMEM;
554
 
                }
555
 
                file->f_security = aaf;
556
 
        }
557
 
        put_aaprofile(active);
558
 
 
559
 
        return error;
560
 
}
561
 
 
562
 
static void apparmor_file_free_security(struct file *file)
563
 
{
564
 
        struct aafile *aaf = (struct aafile *)file->f_security;
565
 
 
566
 
        if (aaf) {
567
 
                put_aaprofile(aaf->profile);
568
 
                kfree(aaf);
569
 
        }
570
 
}
571
 
 
572
 
static inline int aa_mmap(struct file *file, unsigned long prot,
573
 
                          unsigned long flags)
574
 
{
575
 
        int error = 0, mask = 0;
576
 
        struct aaprofile *active;
577
 
        struct aafile *aaf;
578
 
 
579
 
        active = get_active_aaprofile();
580
 
        if (!active || !file ||
581
 
            !(aaf = (struct aafile *)file->f_security) ||
582
 
            aaf->type == aa_file_shmem)
583
 
                goto out;
584
 
 
585
 
        if (prot & PROT_READ)
586
 
                mask |= MAY_READ;
587
 
 
588
 
        /* Private mappings don't require write perms since they don't
589
 
         * write back to the files */
590
 
        if (prot & PROT_WRITE && !(flags & MAP_PRIVATE))
591
 
                mask |= MAY_WRITE;
592
 
        if (prot & PROT_EXEC)
593
 
                mask |= AA_EXEC_MMAP;
594
 
 
595
 
        AA_DEBUG("%s: 0x%x\n", __FUNCTION__, mask);
596
 
 
597
 
        if (mask)
598
 
                error = aa_perm(active, file->f_dentry, file->f_vfsmnt, mask,
599
 
                                1);
600
 
 
601
 
        put_aaprofile(active);
602
 
 
603
 
out:
604
 
        return error;
605
 
}
606
 
 
607
 
static int apparmor_file_mmap(struct file *file, unsigned long reqprot,
608
 
                               unsigned long prot, unsigned long flags)
609
 
{
610
 
        return aa_mmap(file, prot, flags);
611
 
}
612
 
 
613
 
static int apparmor_file_mprotect(struct vm_area_struct *vma,
614
 
                                  unsigned long reqprot, unsigned long prot)
615
 
{
616
 
        return aa_mmap(vma->vm_file, prot,
617
 
                       !(vma->vm_flags & VM_SHARED) ? MAP_PRIVATE : 0);
618
 
}
619
 
 
620
 
static int apparmor_task_alloc_security(struct task_struct *p)
621
 
{
622
 
        return aa_fork(p);
623
 
}
624
 
 
625
 
static void apparmor_task_free_security(struct task_struct *p)
626
 
{
627
 
        aa_release(p);
628
 
}
629
 
 
630
 
static int apparmor_task_post_setuid(uid_t id0, uid_t id1, uid_t id2,
631
 
                                     int flags)
632
 
{
633
 
        return cap_task_post_setuid(id0, id1, id2, flags);
634
 
}
635
 
 
636
 
static void apparmor_task_reparent_to_init(struct task_struct *p)
637
 
{
638
 
        cap_task_reparent_to_init(p);
639
 
        return;
640
 
}
641
 
 
642
 
static int apparmor_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr,
643
 
                              int shmflg)
644
 
{
645
 
        struct aafile *aaf = (struct aafile *)shp->shm_file->f_security;
646
 
 
647
 
        if (aaf)
648
 
                aaf->type = aa_file_shmem;
649
 
 
650
 
        return 0;
651
 
}
652
 
 
653
 
static int apparmor_getprocattr(struct task_struct *p, char *name, char **value)
654
 
{
655
 
        size_t len;
656
 
        int error;
657
 
        struct aaprofile *active;
658
 
 
659
 
        /* AppArmor only supports the "current" process attribute */
660
 
        if (strcmp(name, "current") != 0) {
661
 
                error = -EINVAL;
662
 
                goto out;
663
 
        }
664
 
 
665
 
        /* must be task querying itself or admin */
666
 
        if (current != p && !capable(CAP_SYS_ADMIN)) {
667
 
                error = -EPERM;
668
 
                goto out;
669
 
        }
670
 
 
671
 
        active = get_task_active_aaprofile(p);
672
 
        error = aa_getprocattr(active, value, &len);
673
 
        put_aaprofile(active);
674
 
        if (!error)
675
 
                error = len;
676
 
 
677
 
out:
678
 
        return error;
679
 
}
680
 
 
681
 
static int apparmor_setprocattr(struct task_struct *p, char *name, void *value,
682
 
                                 size_t size)
683
 
{
684
 
        const char *cmd_changehat = "changehat ",
685
 
                   *cmd_setprofile = "setprofile ";
686
 
 
687
 
        int error = -EACCES;    /* default to a perm denied */
688
 
        char *cmd = (char *)value;
689
 
 
690
 
        /* only support messages to current */
691
 
        if (strcmp(name, "current") != 0) {
692
 
                error = -EINVAL;
693
 
                goto out;
694
 
        }
695
 
 
696
 
        if (!size) {
697
 
                error = -ERANGE;
698
 
                goto out;
699
 
        }
700
 
 
701
 
        /* CHANGE HAT -- switch task into a subhat (subprofile) if defined */
702
 
        if (size > strlen(cmd_changehat) &&
703
 
            strncmp(cmd, cmd_changehat, strlen(cmd_changehat)) == 0) {
704
 
                char *hatinfo = cmd + strlen(cmd_changehat);
705
 
                size_t infosize = size - strlen(cmd_changehat);
706
 
 
707
 
                /* Only the current process may change it's hat */
708
 
                if (current != p) {
709
 
                        AA_WARN("%s: Attempt by foreign task %s(%d) "
710
 
                                "[user %d] to changehat of task %s(%d)\n",
711
 
                                __FUNCTION__,
712
 
                                current->comm,
713
 
                                current->pid,
714
 
                                current->uid,
715
 
                                p->comm,
716
 
                                p->pid);
717
 
 
718
 
                        error = -EACCES;
719
 
                        goto out;
720
 
                }
721
 
 
722
 
                error = aa_setprocattr_changehat(hatinfo, infosize);
723
 
                if (error == 0)
724
 
                        /* success, set return to #bytes in orig request */
725
 
                        error = size;
726
 
 
727
 
        /* SET NEW PROFILE */
728
 
        } else if (size > strlen(cmd_setprofile) &&
729
 
                   strncmp(cmd, cmd_setprofile, strlen(cmd_setprofile)) == 0) {
730
 
                struct aaprofile *active;
731
 
 
732
 
                /* only an unconfined process with admin capabilities
733
 
                 * may change the profile of another task
734
 
                 */
735
 
 
736
 
                if (!capable(CAP_SYS_ADMIN)) {
737
 
                        AA_WARN("%s: Unprivileged attempt by task %s(%d) "
738
 
                                "[user %d] to assign profile to task %s(%d)\n",
739
 
                                __FUNCTION__,
740
 
                                current->comm,
741
 
                                current->pid,
742
 
                                current->uid,
743
 
                                p->comm,
744
 
                                p->pid);
745
 
                        error = -EACCES;
746
 
                        goto out;
747
 
                }
748
 
 
749
 
                active = get_active_aaprofile();
750
 
                if (!active) {
751
 
                        char *profile = cmd + strlen(cmd_setprofile);
752
 
                        size_t profilesize = size - strlen(cmd_setprofile);
753
 
 
754
 
                        error = aa_setprocattr_setprofile(p, profile, profilesize);
755
 
                        if (error == 0)
756
 
                                /* success,
757
 
                                 * set return to #bytes in orig request
758
 
                                 */
759
 
                                error = size;
760
 
                } else {
761
 
                        AA_WARN("%s: Attempt by confined task %s(%d) "
762
 
                                "[user %d] to assign profile to task %s(%d)\n",
763
 
                                __FUNCTION__,
764
 
                                current->comm,
765
 
                                current->pid,
766
 
                                current->uid,
767
 
                                p->comm,
768
 
                                p->pid);
769
 
 
770
 
                        error = -EACCES;
771
 
                }
772
 
                put_aaprofile(active);
773
 
        } else {
774
 
                /* unknown operation */
775
 
                AA_WARN("%s: Unknown setprocattr command '%.*s' by task %s(%d) "
776
 
                        "[user %d] for task %s(%d)\n",
777
 
                        __FUNCTION__,
778
 
                        size < 16 ? (int)size : 16,
779
 
                        cmd,
780
 
                        current->comm,
781
 
                        current->pid,
782
 
                        current->uid,
783
 
                        p->comm,
784
 
                        p->pid);
785
 
 
786
 
                error = -EINVAL;
787
 
        }
788
 
 
789
 
out:
790
 
        return error;
791
 
}
792
 
 
793
 
int apparmor_register_subsecurity(const char *name,
794
 
                                  struct security_operations *ops)
795
 
{
796
 
        int error = 0;
797
 
 
798
 
        if (mutex_lock_interruptible(&aa_secondary_lock))
799
 
                return -ERESTARTSYS;
800
 
 
801
 
        /* allow dazuko and capability to stack.  The stacking with
802
 
         * capability is fake however in that non of capabilities hooks
803
 
         * get called, since apparmor already composes capability using
804
 
         * common cap.
805
 
         */
806
 
        if (!aa_secondary_ops && (strcmp(name, "dazuko") == 0 ||
807
 
                                  strcmp(name, "capability") == 0)){
808
 
                /* The apparmor module needs to be pinned while a secondary is
809
 
                 * registered
810
 
                 */
811
 
                if (try_module_get(aa_module)) {
812
 
                        aa_secondary_ops = ops;
813
 
                        AA_INFO("Registered secondary security module: %s.\n",
814
 
                                name);
815
 
                } else {
816
 
                        error = -EINVAL;
817
 
                }
818
 
        } else {
819
 
                AA_WARN("Unable to register %s as a secondary security "
820
 
                        "module\n", name);
821
 
                error = -EPERM;
822
 
        }
823
 
        mutex_unlock(&aa_secondary_lock);
824
 
        return error;
825
 
}
826
 
 
827
 
int apparmor_unregister_subsecurity(const char *name,
828
 
                                    struct security_operations *ops)
829
 
{
830
 
        int error = 0;
831
 
 
832
 
        if (mutex_lock_interruptible(&aa_secondary_lock))
833
 
                return -ERESTARTSYS;
834
 
 
835
 
        if (aa_secondary_ops && aa_secondary_ops == ops) {
836
 
                rcu_assign_pointer(aa_secondary_ops, NULL);
837
 
                synchronize_rcu();
838
 
                module_put(aa_module);
839
 
                AA_INFO("Unregistered secondary security module: %s\n", name);
840
 
        } else {
841
 
                AA_WARN("Unable to unregister secondary security module %s\n",
842
 
                        name);
843
 
                error = -EPERM;
844
 
        }
845
 
        mutex_unlock(&aa_secondary_lock);
846
 
        return error;
847
 
}
848
 
 
849
 
struct security_operations apparmor_ops = {
850
 
        .ptrace =                       apparmor_ptrace,
851
 
        .capget =                       apparmor_capget,
852
 
        .capset_check =                 apparmor_capset_check,
853
 
        .capset_set =                   apparmor_capset_set,
854
 
        .sysctl =                       apparmor_sysctl,
855
 
        .capable =                      apparmor_capable,
856
 
        .syslog =                       apparmor_syslog,
857
 
 
858
 
        .netlink_send =                 apparmor_netlink_send,
859
 
        .netlink_recv =                 apparmor_netlink_recv,
860
 
 
861
 
        .bprm_apply_creds =             apparmor_bprm_apply_creds,
862
 
        .bprm_set_security =            apparmor_bprm_set_security,
863
 
        .bprm_secureexec =              apparmor_bprm_secureexec,
864
 
 
865
 
        .sb_mount =                     apparmor_sb_mount,
866
 
        .sb_umount =                    apparmor_umount,
867
 
 
868
 
        .inode_mkdir =                  apparmor_inode_mkdir,
869
 
        .inode_rmdir =                  apparmor_inode_rmdir,
870
 
        .inode_create =                 apparmor_inode_create,
871
 
        .inode_link =                   apparmor_inode_link,
872
 
        .inode_unlink =                 apparmor_inode_unlink,
873
 
        .inode_symlink =                apparmor_inode_symlink,
874
 
        .inode_mknod =                  apparmor_inode_mknod,
875
 
        .inode_rename =                 apparmor_inode_rename,
876
 
        .inode_permission =             apparmor_inode_permission,
877
 
        .inode_setattr =                apparmor_inode_setattr,
878
 
        .inode_setxattr =               apparmor_inode_setxattr,
879
 
        .inode_getxattr =               apparmor_inode_getxattr,
880
 
        .inode_listxattr =              apparmor_inode_listxattr,
881
 
        .inode_removexattr =            apparmor_inode_removexattr,
882
 
        .file_permission =              apparmor_file_permission,
883
 
        .file_alloc_security =          apparmor_file_alloc_security,
884
 
        .file_free_security =           apparmor_file_free_security,
885
 
        .file_mmap =                    apparmor_file_mmap,
886
 
        .file_mprotect =                apparmor_file_mprotect,
887
 
 
888
 
        .task_alloc_security =          apparmor_task_alloc_security,
889
 
        .task_free_security =           apparmor_task_free_security,
890
 
        .task_post_setuid =             apparmor_task_post_setuid,
891
 
        .task_reparent_to_init =        apparmor_task_reparent_to_init,
892
 
 
893
 
        .shm_shmat =                    apparmor_shm_shmat,
894
 
 
895
 
        .getprocattr =                  apparmor_getprocattr,
896
 
        .setprocattr =                  apparmor_setprocattr,
897
 
 
898
 
        .register_security =            apparmor_register_subsecurity,
899
 
        .unregister_security =          apparmor_unregister_subsecurity,
900
 
};
901
 
 
902
 
static int __init apparmor_init(void)
903
 
{
904
 
        int error;
905
 
        const char *complainmsg = ": complainmode enabled";
906
 
 
907
 
        if ((error = create_apparmorfs())) {
908
 
                AA_ERROR("Unable to activate AppArmor filesystem\n");
909
 
                goto createfs_out;
910
 
        }
911
 
 
912
 
        if ((error = alloc_null_complain_profile())){
913
 
                AA_ERROR("Unable to allocate null complain profile\n");
914
 
                goto alloc_out;
915
 
        }
916
 
 
917
 
        if ((error = register_security(&apparmor_ops))) {
918
 
                AA_ERROR("Unable to load AppArmor\n");
919
 
                goto register_security_out;
920
 
        }
921
 
 
922
 
        AA_INFO("AppArmor initialized%s\n",
923
 
                apparmor_complain ? complainmsg : "");
924
 
        aa_audit_message(NULL, GFP_KERNEL, 0,
925
 
                "AppArmor initialized%s\n",
926
 
                apparmor_complain ? complainmsg : "");
927
 
 
928
 
        aa_module = THIS_MODULE;
929
 
 
930
 
        return error;
931
 
 
932
 
register_security_out:
933
 
        free_null_complain_profile();
934
 
 
935
 
alloc_out:
936
 
        (void)destroy_apparmorfs();
937
 
 
938
 
createfs_out:
939
 
        return error;
940
 
 
941
 
}
942
 
 
943
 
static int apparmor_exit_removeall_iter(struct subdomain *sd, void *cookie)
944
 
{
945
 
        /* spin_lock(&sd_lock) held here */
946
 
 
947
 
        if (__aa_is_confined(sd)) {
948
 
                AA_DEBUG("%s: Dropping profiles %s(%d) "
949
 
                         "profile %s(%p) active %s(%p)\n",
950
 
                         __FUNCTION__,
951
 
                         sd->task->comm, sd->task->pid,
952
 
                         BASE_PROFILE(sd->active)->name,
953
 
                         BASE_PROFILE(sd->active),
954
 
                         sd->active->name, sd->active);
955
 
                aa_switch_unconfined(sd);
956
 
        }
957
 
 
958
 
        return 0;
959
 
}
960
 
 
961
 
static void __exit apparmor_exit(void)
962
 
{
963
 
        unsigned long flags;
964
 
 
965
 
        /* Remove profiles from the global profile list.
966
 
         * This is just for tidyness as there is no way to reference this
967
 
         * list once the AppArmor lsm hooks are detached (below)
968
 
         */
969
 
        aa_profilelist_release();
970
 
 
971
 
        /* Remove profiles from active tasks
972
 
         * If this is not done,  if module is reloaded after being removed,
973
 
         * old profiles (still refcounted in memory) will become 'magically'
974
 
         * reattached
975
 
         */
976
 
 
977
 
        spin_lock_irqsave(&sd_lock, flags);
978
 
        aa_subdomainlist_iterate(apparmor_exit_removeall_iter, NULL);
979
 
        spin_unlock_irqrestore(&sd_lock, flags);
980
 
 
981
 
        /* Free up list of active subdomain */
982
 
        aa_subdomainlist_release();
983
 
 
984
 
        free_null_complain_profile();
985
 
 
986
 
        destroy_apparmorfs();
987
 
 
988
 
        if (unregister_security(&apparmor_ops))
989
 
                AA_WARN("Unable to properly unregister AppArmor\n");
990
 
 
991
 
        /* delay for an rcu cycle to make ensure that profiles pending
992
 
         * destruction in the rcu callback are freed.
993
 
         */
994
 
        synchronize_rcu();
995
 
 
996
 
        AA_INFO("AppArmor protection removed\n");
997
 
        aa_audit_message(NULL, GFP_KERNEL, 0,
998
 
                "AppArmor protection removed\n");
999
 
}
1000
 
 
1001
 
module_init(apparmor_init);
1002
 
module_exit(apparmor_exit);
1003
 
 
1004
 
MODULE_VERSION(APPARMOR_VERSION);
1005
 
MODULE_DESCRIPTION("AppArmor process confinement");
1006
 
MODULE_AUTHOR("Tony Jones <tonyj@suse.de>");
1007
 
MODULE_LICENSE("GPL");