blob: 7e101dbea4cb28ffb381869904e0709debce56ee [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * NSA Security-Enhanced Linux (SELinux) security module
3 *
4 * This file contains the SELinux hook function implementations.
5 *
6 * Authors: Stephen Smalley, <sds@epoch.ncsc.mil>
7 * Chris Vance, <cvance@nai.com>
8 * Wayne Salamon, <wsalamon@nai.com>
9 * James Morris <jmorris@redhat.com>
10 *
11 * Copyright (C) 2001,2002 Networks Associates Technology, Inc.
12 * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com>
13 * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
14 * <dgoeddel@trustedcs.com>
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License version 2,
18 * as published by the Free Software Foundation.
19 */
20
Linus Torvalds1da177e2005-04-16 15:20:36 -070021#include <linux/module.h>
22#include <linux/init.h>
23#include <linux/kernel.h>
24#include <linux/ptrace.h>
25#include <linux/errno.h>
26#include <linux/sched.h>
27#include <linux/security.h>
28#include <linux/xattr.h>
29#include <linux/capability.h>
30#include <linux/unistd.h>
31#include <linux/mm.h>
32#include <linux/mman.h>
33#include <linux/slab.h>
34#include <linux/pagemap.h>
35#include <linux/swap.h>
36#include <linux/smp_lock.h>
37#include <linux/spinlock.h>
38#include <linux/syscalls.h>
39#include <linux/file.h>
40#include <linux/namei.h>
41#include <linux/mount.h>
42#include <linux/ext2_fs.h>
43#include <linux/proc_fs.h>
44#include <linux/kd.h>
45#include <linux/netfilter_ipv4.h>
46#include <linux/netfilter_ipv6.h>
47#include <linux/tty.h>
48#include <net/icmp.h>
49#include <net/ip.h> /* for sysctl_local_port_range[] */
50#include <net/tcp.h> /* struct or_callable used in sock_rcv_skb */
51#include <asm/uaccess.h>
52#include <asm/semaphore.h>
53#include <asm/ioctls.h>
54#include <linux/bitops.h>
55#include <linux/interrupt.h>
56#include <linux/netdevice.h> /* for network interface checks */
57#include <linux/netlink.h>
58#include <linux/tcp.h>
59#include <linux/udp.h>
60#include <linux/quota.h>
61#include <linux/un.h> /* for Unix socket types */
62#include <net/af_unix.h> /* for Unix socket types */
63#include <linux/parser.h>
64#include <linux/nfs_mount.h>
65#include <net/ipv6.h>
66#include <linux/hugetlb.h>
67#include <linux/personality.h>
68#include <linux/sysctl.h>
69#include <linux/audit.h>
Eric Paris6931dfc2005-06-30 02:58:51 -070070#include <linux/string.h>
Catherine Zhang877ce7c2006-06-29 12:27:47 -070071#include <linux/selinux.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070072
73#include "avc.h"
74#include "objsec.h"
75#include "netif.h"
Trent Jaegerd28d1e02005-12-13 23:12:40 -080076#include "xfrm.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070077
78#define XATTR_SELINUX_SUFFIX "selinux"
79#define XATTR_NAME_SELINUX XATTR_SECURITY_PREFIX XATTR_SELINUX_SUFFIX
80
81extern unsigned int policydb_loaded_version;
82extern int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm);
James Morris4e5ab4c2006-06-09 00:33:33 -070083extern int selinux_compat_net;
Linus Torvalds1da177e2005-04-16 15:20:36 -070084
85#ifdef CONFIG_SECURITY_SELINUX_DEVELOP
86int selinux_enforcing = 0;
87
88static int __init enforcing_setup(char *str)
89{
90 selinux_enforcing = simple_strtol(str,NULL,0);
91 return 1;
92}
93__setup("enforcing=", enforcing_setup);
94#endif
95
96#ifdef CONFIG_SECURITY_SELINUX_BOOTPARAM
97int selinux_enabled = CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE;
98
99static int __init selinux_enabled_setup(char *str)
100{
101 selinux_enabled = simple_strtol(str, NULL, 0);
102 return 1;
103}
104__setup("selinux=", selinux_enabled_setup);
Stephen Smalley30d55282006-05-03 10:52:36 -0400105#else
106int selinux_enabled = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700107#endif
108
109/* Original (dummy) security module. */
110static struct security_operations *original_ops = NULL;
111
112/* Minimal support for a secondary security module,
113 just to allow the use of the dummy or capability modules.
114 The owlsm module can alternatively be used as a secondary
115 module as long as CONFIG_OWLSM_FD is not enabled. */
116static struct security_operations *secondary_ops = NULL;
117
118/* Lists of inode and superblock security structures initialized
119 before the policy was loaded. */
120static LIST_HEAD(superblock_security_head);
121static DEFINE_SPINLOCK(sb_security_lock);
122
James Morris7cae7e22006-03-22 00:09:22 -0800123static kmem_cache_t *sel_inode_cache;
124
Dustin Kirkland8c8570f2005-11-03 17:15:16 +0000125/* Return security context for a given sid or just the context
126 length if the buffer is null or length is 0 */
127static int selinux_getsecurity(u32 sid, void *buffer, size_t size)
128{
129 char *context;
130 unsigned len;
131 int rc;
132
133 rc = security_sid_to_context(sid, &context, &len);
134 if (rc)
135 return rc;
136
137 if (!buffer || !size)
138 goto getsecurity_exit;
139
140 if (size < len) {
141 len = -ERANGE;
142 goto getsecurity_exit;
143 }
144 memcpy(buffer, context, len);
145
146getsecurity_exit:
147 kfree(context);
148 return len;
149}
150
Linus Torvalds1da177e2005-04-16 15:20:36 -0700151/* Allocate and free functions for each kind of security blob. */
152
153static int task_alloc_security(struct task_struct *task)
154{
155 struct task_security_struct *tsec;
156
James Morris89d155e2005-10-30 14:59:21 -0800157 tsec = kzalloc(sizeof(struct task_security_struct), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700158 if (!tsec)
159 return -ENOMEM;
160
Linus Torvalds1da177e2005-04-16 15:20:36 -0700161 tsec->task = task;
162 tsec->osid = tsec->sid = tsec->ptrace_sid = SECINITSID_UNLABELED;
163 task->security = tsec;
164
165 return 0;
166}
167
168static void task_free_security(struct task_struct *task)
169{
170 struct task_security_struct *tsec = task->security;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700171 task->security = NULL;
172 kfree(tsec);
173}
174
175static int inode_alloc_security(struct inode *inode)
176{
177 struct task_security_struct *tsec = current->security;
178 struct inode_security_struct *isec;
179
James Morris7cae7e22006-03-22 00:09:22 -0800180 isec = kmem_cache_alloc(sel_inode_cache, SLAB_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700181 if (!isec)
182 return -ENOMEM;
183
James Morris7cae7e22006-03-22 00:09:22 -0800184 memset(isec, 0, sizeof(*isec));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700185 init_MUTEX(&isec->sem);
186 INIT_LIST_HEAD(&isec->list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700187 isec->inode = inode;
188 isec->sid = SECINITSID_UNLABELED;
189 isec->sclass = SECCLASS_FILE;
Stephen Smalley9ac49d22006-02-01 03:05:56 -0800190 isec->task_sid = tsec->sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700191 inode->i_security = isec;
192
193 return 0;
194}
195
196static void inode_free_security(struct inode *inode)
197{
198 struct inode_security_struct *isec = inode->i_security;
199 struct superblock_security_struct *sbsec = inode->i_sb->s_security;
200
Linus Torvalds1da177e2005-04-16 15:20:36 -0700201 spin_lock(&sbsec->isec_lock);
202 if (!list_empty(&isec->list))
203 list_del_init(&isec->list);
204 spin_unlock(&sbsec->isec_lock);
205
206 inode->i_security = NULL;
James Morris7cae7e22006-03-22 00:09:22 -0800207 kmem_cache_free(sel_inode_cache, isec);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700208}
209
210static int file_alloc_security(struct file *file)
211{
212 struct task_security_struct *tsec = current->security;
213 struct file_security_struct *fsec;
214
Stephen Smalley26d2a4b2006-02-01 03:05:55 -0800215 fsec = kzalloc(sizeof(struct file_security_struct), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700216 if (!fsec)
217 return -ENOMEM;
218
Linus Torvalds1da177e2005-04-16 15:20:36 -0700219 fsec->file = file;
Stephen Smalley9ac49d22006-02-01 03:05:56 -0800220 fsec->sid = tsec->sid;
221 fsec->fown_sid = tsec->sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700222 file->f_security = fsec;
223
224 return 0;
225}
226
227static void file_free_security(struct file *file)
228{
229 struct file_security_struct *fsec = file->f_security;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700230 file->f_security = NULL;
231 kfree(fsec);
232}
233
234static int superblock_alloc_security(struct super_block *sb)
235{
236 struct superblock_security_struct *sbsec;
237
James Morris89d155e2005-10-30 14:59:21 -0800238 sbsec = kzalloc(sizeof(struct superblock_security_struct), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700239 if (!sbsec)
240 return -ENOMEM;
241
Linus Torvalds1da177e2005-04-16 15:20:36 -0700242 init_MUTEX(&sbsec->sem);
243 INIT_LIST_HEAD(&sbsec->list);
244 INIT_LIST_HEAD(&sbsec->isec_head);
245 spin_lock_init(&sbsec->isec_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700246 sbsec->sb = sb;
247 sbsec->sid = SECINITSID_UNLABELED;
248 sbsec->def_sid = SECINITSID_FILE;
Eric Parisc312feb2006-07-10 04:43:53 -0700249 sbsec->mntpoint_sid = SECINITSID_UNLABELED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700250 sb->s_security = sbsec;
251
252 return 0;
253}
254
255static void superblock_free_security(struct super_block *sb)
256{
257 struct superblock_security_struct *sbsec = sb->s_security;
258
Linus Torvalds1da177e2005-04-16 15:20:36 -0700259 spin_lock(&sb_security_lock);
260 if (!list_empty(&sbsec->list))
261 list_del_init(&sbsec->list);
262 spin_unlock(&sb_security_lock);
263
264 sb->s_security = NULL;
265 kfree(sbsec);
266}
267
Al Viro7d877f32005-10-21 03:20:43 -0400268static int sk_alloc_security(struct sock *sk, int family, gfp_t priority)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700269{
270 struct sk_security_struct *ssec;
271
272 if (family != PF_UNIX)
273 return 0;
274
James Morris89d155e2005-10-30 14:59:21 -0800275 ssec = kzalloc(sizeof(*ssec), priority);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700276 if (!ssec)
277 return -ENOMEM;
278
Linus Torvalds1da177e2005-04-16 15:20:36 -0700279 ssec->sk = sk;
280 ssec->peer_sid = SECINITSID_UNLABELED;
281 sk->sk_security = ssec;
282
283 return 0;
284}
285
286static void sk_free_security(struct sock *sk)
287{
288 struct sk_security_struct *ssec = sk->sk_security;
289
Stephen Smalley9ac49d22006-02-01 03:05:56 -0800290 if (sk->sk_family != PF_UNIX)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700291 return;
292
293 sk->sk_security = NULL;
294 kfree(ssec);
295}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700296
297/* The security server must be initialized before
298 any labeling or access decisions can be provided. */
299extern int ss_initialized;
300
301/* The file system's label must be initialized prior to use. */
302
303static char *labeling_behaviors[6] = {
304 "uses xattr",
305 "uses transition SIDs",
306 "uses task SIDs",
307 "uses genfs_contexts",
308 "not configured for labeling",
309 "uses mountpoint labeling",
310};
311
312static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry);
313
314static inline int inode_doinit(struct inode *inode)
315{
316 return inode_doinit_with_dentry(inode, NULL);
317}
318
319enum {
320 Opt_context = 1,
321 Opt_fscontext = 2,
322 Opt_defcontext = 4,
323};
324
325static match_table_t tokens = {
326 {Opt_context, "context=%s"},
327 {Opt_fscontext, "fscontext=%s"},
328 {Opt_defcontext, "defcontext=%s"},
329};
330
331#define SEL_MOUNT_FAIL_MSG "SELinux: duplicate or incompatible mount options\n"
332
Eric Parisc312feb2006-07-10 04:43:53 -0700333static int may_context_mount_sb_relabel(u32 sid,
334 struct superblock_security_struct *sbsec,
335 struct task_security_struct *tsec)
336{
337 int rc;
338
339 rc = avc_has_perm(tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
340 FILESYSTEM__RELABELFROM, NULL);
341 if (rc)
342 return rc;
343
344 rc = avc_has_perm(tsec->sid, sid, SECCLASS_FILESYSTEM,
345 FILESYSTEM__RELABELTO, NULL);
346 return rc;
347}
348
Linus Torvalds1da177e2005-04-16 15:20:36 -0700349static int try_context_mount(struct super_block *sb, void *data)
350{
351 char *context = NULL, *defcontext = NULL;
Eric Parisc312feb2006-07-10 04:43:53 -0700352 char *fscontext = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700353 const char *name;
354 u32 sid;
355 int alloc = 0, rc = 0, seen = 0;
356 struct task_security_struct *tsec = current->security;
357 struct superblock_security_struct *sbsec = sb->s_security;
358
359 if (!data)
360 goto out;
361
362 name = sb->s_type->name;
363
364 if (sb->s_type->fs_flags & FS_BINARY_MOUNTDATA) {
365
366 /* NFS we understand. */
367 if (!strcmp(name, "nfs")) {
368 struct nfs_mount_data *d = data;
369
370 if (d->version < NFS_MOUNT_VERSION)
371 goto out;
372
373 if (d->context[0]) {
374 context = d->context;
375 seen |= Opt_context;
376 }
377 } else
378 goto out;
379
380 } else {
381 /* Standard string-based options. */
382 char *p, *options = data;
383
384 while ((p = strsep(&options, ",")) != NULL) {
385 int token;
386 substring_t args[MAX_OPT_ARGS];
387
388 if (!*p)
389 continue;
390
391 token = match_token(p, tokens, args);
392
393 switch (token) {
394 case Opt_context:
Eric Parisc312feb2006-07-10 04:43:53 -0700395 if (seen & (Opt_context|Opt_defcontext)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700396 rc = -EINVAL;
397 printk(KERN_WARNING SEL_MOUNT_FAIL_MSG);
398 goto out_free;
399 }
400 context = match_strdup(&args[0]);
401 if (!context) {
402 rc = -ENOMEM;
403 goto out_free;
404 }
405 if (!alloc)
406 alloc = 1;
407 seen |= Opt_context;
408 break;
409
410 case Opt_fscontext:
Eric Parisc312feb2006-07-10 04:43:53 -0700411 if (seen & Opt_fscontext) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700412 rc = -EINVAL;
413 printk(KERN_WARNING SEL_MOUNT_FAIL_MSG);
414 goto out_free;
415 }
Eric Parisc312feb2006-07-10 04:43:53 -0700416 fscontext = match_strdup(&args[0]);
417 if (!fscontext) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700418 rc = -ENOMEM;
419 goto out_free;
420 }
421 if (!alloc)
422 alloc = 1;
423 seen |= Opt_fscontext;
424 break;
425
426 case Opt_defcontext:
427 if (sbsec->behavior != SECURITY_FS_USE_XATTR) {
428 rc = -EINVAL;
429 printk(KERN_WARNING "SELinux: "
430 "defcontext option is invalid "
431 "for this filesystem type\n");
432 goto out_free;
433 }
434 if (seen & (Opt_context|Opt_defcontext)) {
435 rc = -EINVAL;
436 printk(KERN_WARNING SEL_MOUNT_FAIL_MSG);
437 goto out_free;
438 }
439 defcontext = match_strdup(&args[0]);
440 if (!defcontext) {
441 rc = -ENOMEM;
442 goto out_free;
443 }
444 if (!alloc)
445 alloc = 1;
446 seen |= Opt_defcontext;
447 break;
448
449 default:
450 rc = -EINVAL;
451 printk(KERN_WARNING "SELinux: unknown mount "
452 "option\n");
453 goto out_free;
454
455 }
456 }
457 }
458
459 if (!seen)
460 goto out;
461
Eric Parisc312feb2006-07-10 04:43:53 -0700462 /* sets the context of the superblock for the fs being mounted. */
463 if (fscontext) {
464 rc = security_context_to_sid(fscontext, strlen(fscontext), &sid);
465 if (rc) {
466 printk(KERN_WARNING "SELinux: security_context_to_sid"
467 "(%s) failed for (dev %s, type %s) errno=%d\n",
468 fscontext, sb->s_id, name, rc);
469 goto out_free;
470 }
471
472 rc = may_context_mount_sb_relabel(sid, sbsec, tsec);
473 if (rc)
474 goto out_free;
475
476 sbsec->sid = sid;
477 }
478
479 /*
480 * Switch to using mount point labeling behavior.
481 * sets the label used on all file below the mountpoint, and will set
482 * the superblock context if not already set.
483 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700484 if (context) {
485 rc = security_context_to_sid(context, strlen(context), &sid);
486 if (rc) {
487 printk(KERN_WARNING "SELinux: security_context_to_sid"
488 "(%s) failed for (dev %s, type %s) errno=%d\n",
489 context, sb->s_id, name, rc);
490 goto out_free;
491 }
492
Eric Parisc312feb2006-07-10 04:43:53 -0700493 rc = may_context_mount_sb_relabel(sid, sbsec, tsec);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700494 if (rc)
495 goto out_free;
496
Eric Parisc312feb2006-07-10 04:43:53 -0700497 if (!fscontext)
498 sbsec->sid = sid;
499 sbsec->mntpoint_sid = sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700500
Eric Parisc312feb2006-07-10 04:43:53 -0700501 sbsec->behavior = SECURITY_FS_USE_MNTPOINT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700502 }
503
504 if (defcontext) {
505 rc = security_context_to_sid(defcontext, strlen(defcontext), &sid);
506 if (rc) {
507 printk(KERN_WARNING "SELinux: security_context_to_sid"
508 "(%s) failed for (dev %s, type %s) errno=%d\n",
509 defcontext, sb->s_id, name, rc);
510 goto out_free;
511 }
512
513 if (sid == sbsec->def_sid)
514 goto out_free;
515
516 rc = avc_has_perm(tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
517 FILESYSTEM__RELABELFROM, NULL);
518 if (rc)
519 goto out_free;
520
521 rc = avc_has_perm(sid, sbsec->sid, SECCLASS_FILESYSTEM,
522 FILESYSTEM__ASSOCIATE, NULL);
523 if (rc)
524 goto out_free;
525
526 sbsec->def_sid = sid;
527 }
528
529out_free:
530 if (alloc) {
531 kfree(context);
532 kfree(defcontext);
Eric Parisc312feb2006-07-10 04:43:53 -0700533 kfree(fscontext);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700534 }
535out:
536 return rc;
537}
538
539static int superblock_doinit(struct super_block *sb, void *data)
540{
541 struct superblock_security_struct *sbsec = sb->s_security;
542 struct dentry *root = sb->s_root;
543 struct inode *inode = root->d_inode;
544 int rc = 0;
545
546 down(&sbsec->sem);
547 if (sbsec->initialized)
548 goto out;
549
550 if (!ss_initialized) {
551 /* Defer initialization until selinux_complete_init,
552 after the initial policy is loaded and the security
553 server is ready to handle calls. */
554 spin_lock(&sb_security_lock);
555 if (list_empty(&sbsec->list))
556 list_add(&sbsec->list, &superblock_security_head);
557 spin_unlock(&sb_security_lock);
558 goto out;
559 }
560
561 /* Determine the labeling behavior to use for this filesystem type. */
562 rc = security_fs_use(sb->s_type->name, &sbsec->behavior, &sbsec->sid);
563 if (rc) {
564 printk(KERN_WARNING "%s: security_fs_use(%s) returned %d\n",
565 __FUNCTION__, sb->s_type->name, rc);
566 goto out;
567 }
568
569 rc = try_context_mount(sb, data);
570 if (rc)
571 goto out;
572
573 if (sbsec->behavior == SECURITY_FS_USE_XATTR) {
574 /* Make sure that the xattr handler exists and that no
575 error other than -ENODATA is returned by getxattr on
576 the root directory. -ENODATA is ok, as this may be
577 the first boot of the SELinux kernel before we have
578 assigned xattr values to the filesystem. */
579 if (!inode->i_op->getxattr) {
580 printk(KERN_WARNING "SELinux: (dev %s, type %s) has no "
581 "xattr support\n", sb->s_id, sb->s_type->name);
582 rc = -EOPNOTSUPP;
583 goto out;
584 }
585 rc = inode->i_op->getxattr(root, XATTR_NAME_SELINUX, NULL, 0);
586 if (rc < 0 && rc != -ENODATA) {
587 if (rc == -EOPNOTSUPP)
588 printk(KERN_WARNING "SELinux: (dev %s, type "
589 "%s) has no security xattr handler\n",
590 sb->s_id, sb->s_type->name);
591 else
592 printk(KERN_WARNING "SELinux: (dev %s, type "
593 "%s) getxattr errno %d\n", sb->s_id,
594 sb->s_type->name, -rc);
595 goto out;
596 }
597 }
598
599 if (strcmp(sb->s_type->name, "proc") == 0)
600 sbsec->proc = 1;
601
602 sbsec->initialized = 1;
603
604 if (sbsec->behavior > ARRAY_SIZE(labeling_behaviors)) {
605 printk(KERN_INFO "SELinux: initialized (dev %s, type %s), unknown behavior\n",
606 sb->s_id, sb->s_type->name);
607 }
608 else {
609 printk(KERN_INFO "SELinux: initialized (dev %s, type %s), %s\n",
610 sb->s_id, sb->s_type->name,
611 labeling_behaviors[sbsec->behavior-1]);
612 }
613
614 /* Initialize the root inode. */
615 rc = inode_doinit_with_dentry(sb->s_root->d_inode, sb->s_root);
616
617 /* Initialize any other inodes associated with the superblock, e.g.
618 inodes created prior to initial policy load or inodes created
619 during get_sb by a pseudo filesystem that directly
620 populates itself. */
621 spin_lock(&sbsec->isec_lock);
622next_inode:
623 if (!list_empty(&sbsec->isec_head)) {
624 struct inode_security_struct *isec =
625 list_entry(sbsec->isec_head.next,
626 struct inode_security_struct, list);
627 struct inode *inode = isec->inode;
628 spin_unlock(&sbsec->isec_lock);
629 inode = igrab(inode);
630 if (inode) {
631 if (!IS_PRIVATE (inode))
632 inode_doinit(inode);
633 iput(inode);
634 }
635 spin_lock(&sbsec->isec_lock);
636 list_del_init(&isec->list);
637 goto next_inode;
638 }
639 spin_unlock(&sbsec->isec_lock);
640out:
641 up(&sbsec->sem);
642 return rc;
643}
644
645static inline u16 inode_mode_to_security_class(umode_t mode)
646{
647 switch (mode & S_IFMT) {
648 case S_IFSOCK:
649 return SECCLASS_SOCK_FILE;
650 case S_IFLNK:
651 return SECCLASS_LNK_FILE;
652 case S_IFREG:
653 return SECCLASS_FILE;
654 case S_IFBLK:
655 return SECCLASS_BLK_FILE;
656 case S_IFDIR:
657 return SECCLASS_DIR;
658 case S_IFCHR:
659 return SECCLASS_CHR_FILE;
660 case S_IFIFO:
661 return SECCLASS_FIFO_FILE;
662
663 }
664
665 return SECCLASS_FILE;
666}
667
James Morris13402582005-09-30 14:24:34 -0400668static inline int default_protocol_stream(int protocol)
669{
670 return (protocol == IPPROTO_IP || protocol == IPPROTO_TCP);
671}
672
673static inline int default_protocol_dgram(int protocol)
674{
675 return (protocol == IPPROTO_IP || protocol == IPPROTO_UDP);
676}
677
Linus Torvalds1da177e2005-04-16 15:20:36 -0700678static inline u16 socket_type_to_security_class(int family, int type, int protocol)
679{
680 switch (family) {
681 case PF_UNIX:
682 switch (type) {
683 case SOCK_STREAM:
684 case SOCK_SEQPACKET:
685 return SECCLASS_UNIX_STREAM_SOCKET;
686 case SOCK_DGRAM:
687 return SECCLASS_UNIX_DGRAM_SOCKET;
688 }
689 break;
690 case PF_INET:
691 case PF_INET6:
692 switch (type) {
693 case SOCK_STREAM:
James Morris13402582005-09-30 14:24:34 -0400694 if (default_protocol_stream(protocol))
695 return SECCLASS_TCP_SOCKET;
696 else
697 return SECCLASS_RAWIP_SOCKET;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700698 case SOCK_DGRAM:
James Morris13402582005-09-30 14:24:34 -0400699 if (default_protocol_dgram(protocol))
700 return SECCLASS_UDP_SOCKET;
701 else
702 return SECCLASS_RAWIP_SOCKET;
703 default:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700704 return SECCLASS_RAWIP_SOCKET;
705 }
706 break;
707 case PF_NETLINK:
708 switch (protocol) {
709 case NETLINK_ROUTE:
710 return SECCLASS_NETLINK_ROUTE_SOCKET;
711 case NETLINK_FIREWALL:
712 return SECCLASS_NETLINK_FIREWALL_SOCKET;
James Morris216efaa2005-08-15 20:34:48 -0700713 case NETLINK_INET_DIAG:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700714 return SECCLASS_NETLINK_TCPDIAG_SOCKET;
715 case NETLINK_NFLOG:
716 return SECCLASS_NETLINK_NFLOG_SOCKET;
717 case NETLINK_XFRM:
718 return SECCLASS_NETLINK_XFRM_SOCKET;
719 case NETLINK_SELINUX:
720 return SECCLASS_NETLINK_SELINUX_SOCKET;
721 case NETLINK_AUDIT:
722 return SECCLASS_NETLINK_AUDIT_SOCKET;
723 case NETLINK_IP6_FW:
724 return SECCLASS_NETLINK_IP6FW_SOCKET;
725 case NETLINK_DNRTMSG:
726 return SECCLASS_NETLINK_DNRT_SOCKET;
James Morris0c9b7942005-04-16 15:24:13 -0700727 case NETLINK_KOBJECT_UEVENT:
728 return SECCLASS_NETLINK_KOBJECT_UEVENT_SOCKET;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700729 default:
730 return SECCLASS_NETLINK_SOCKET;
731 }
732 case PF_PACKET:
733 return SECCLASS_PACKET_SOCKET;
734 case PF_KEY:
735 return SECCLASS_KEY_SOCKET;
Christopher J. PeBenito3e3ff152006-06-09 00:25:03 -0700736 case PF_APPLETALK:
737 return SECCLASS_APPLETALK_SOCKET;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700738 }
739
740 return SECCLASS_SOCKET;
741}
742
743#ifdef CONFIG_PROC_FS
744static int selinux_proc_get_sid(struct proc_dir_entry *de,
745 u16 tclass,
746 u32 *sid)
747{
748 int buflen, rc;
749 char *buffer, *path, *end;
750
751 buffer = (char*)__get_free_page(GFP_KERNEL);
752 if (!buffer)
753 return -ENOMEM;
754
755 buflen = PAGE_SIZE;
756 end = buffer+buflen;
757 *--end = '\0';
758 buflen--;
759 path = end-1;
760 *path = '/';
761 while (de && de != de->parent) {
762 buflen -= de->namelen + 1;
763 if (buflen < 0)
764 break;
765 end -= de->namelen;
766 memcpy(end, de->name, de->namelen);
767 *--end = '/';
768 path = end;
769 de = de->parent;
770 }
771 rc = security_genfs_sid("proc", path, tclass, sid);
772 free_page((unsigned long)buffer);
773 return rc;
774}
775#else
776static int selinux_proc_get_sid(struct proc_dir_entry *de,
777 u16 tclass,
778 u32 *sid)
779{
780 return -EINVAL;
781}
782#endif
783
784/* The inode's security attributes must be initialized before first use. */
785static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry)
786{
787 struct superblock_security_struct *sbsec = NULL;
788 struct inode_security_struct *isec = inode->i_security;
789 u32 sid;
790 struct dentry *dentry;
791#define INITCONTEXTLEN 255
792 char *context = NULL;
793 unsigned len = 0;
794 int rc = 0;
795 int hold_sem = 0;
796
797 if (isec->initialized)
798 goto out;
799
800 down(&isec->sem);
801 hold_sem = 1;
802 if (isec->initialized)
803 goto out;
804
805 sbsec = inode->i_sb->s_security;
806 if (!sbsec->initialized) {
807 /* Defer initialization until selinux_complete_init,
808 after the initial policy is loaded and the security
809 server is ready to handle calls. */
810 spin_lock(&sbsec->isec_lock);
811 if (list_empty(&isec->list))
812 list_add(&isec->list, &sbsec->isec_head);
813 spin_unlock(&sbsec->isec_lock);
814 goto out;
815 }
816
817 switch (sbsec->behavior) {
818 case SECURITY_FS_USE_XATTR:
819 if (!inode->i_op->getxattr) {
820 isec->sid = sbsec->def_sid;
821 break;
822 }
823
824 /* Need a dentry, since the xattr API requires one.
825 Life would be simpler if we could just pass the inode. */
826 if (opt_dentry) {
827 /* Called from d_instantiate or d_splice_alias. */
828 dentry = dget(opt_dentry);
829 } else {
830 /* Called from selinux_complete_init, try to find a dentry. */
831 dentry = d_find_alias(inode);
832 }
833 if (!dentry) {
834 printk(KERN_WARNING "%s: no dentry for dev=%s "
835 "ino=%ld\n", __FUNCTION__, inode->i_sb->s_id,
836 inode->i_ino);
837 goto out;
838 }
839
840 len = INITCONTEXTLEN;
841 context = kmalloc(len, GFP_KERNEL);
842 if (!context) {
843 rc = -ENOMEM;
844 dput(dentry);
845 goto out;
846 }
847 rc = inode->i_op->getxattr(dentry, XATTR_NAME_SELINUX,
848 context, len);
849 if (rc == -ERANGE) {
850 /* Need a larger buffer. Query for the right size. */
851 rc = inode->i_op->getxattr(dentry, XATTR_NAME_SELINUX,
852 NULL, 0);
853 if (rc < 0) {
854 dput(dentry);
855 goto out;
856 }
857 kfree(context);
858 len = rc;
859 context = kmalloc(len, GFP_KERNEL);
860 if (!context) {
861 rc = -ENOMEM;
862 dput(dentry);
863 goto out;
864 }
865 rc = inode->i_op->getxattr(dentry,
866 XATTR_NAME_SELINUX,
867 context, len);
868 }
869 dput(dentry);
870 if (rc < 0) {
871 if (rc != -ENODATA) {
872 printk(KERN_WARNING "%s: getxattr returned "
873 "%d for dev=%s ino=%ld\n", __FUNCTION__,
874 -rc, inode->i_sb->s_id, inode->i_ino);
875 kfree(context);
876 goto out;
877 }
878 /* Map ENODATA to the default file SID */
879 sid = sbsec->def_sid;
880 rc = 0;
881 } else {
James Morrisf5c1d5b2005-07-28 01:07:37 -0700882 rc = security_context_to_sid_default(context, rc, &sid,
883 sbsec->def_sid);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700884 if (rc) {
885 printk(KERN_WARNING "%s: context_to_sid(%s) "
886 "returned %d for dev=%s ino=%ld\n",
887 __FUNCTION__, context, -rc,
888 inode->i_sb->s_id, inode->i_ino);
889 kfree(context);
890 /* Leave with the unlabeled SID */
891 rc = 0;
892 break;
893 }
894 }
895 kfree(context);
896 isec->sid = sid;
897 break;
898 case SECURITY_FS_USE_TASK:
899 isec->sid = isec->task_sid;
900 break;
901 case SECURITY_FS_USE_TRANS:
902 /* Default to the fs SID. */
903 isec->sid = sbsec->sid;
904
905 /* Try to obtain a transition SID. */
906 isec->sclass = inode_mode_to_security_class(inode->i_mode);
907 rc = security_transition_sid(isec->task_sid,
908 sbsec->sid,
909 isec->sclass,
910 &sid);
911 if (rc)
912 goto out;
913 isec->sid = sid;
914 break;
Eric Parisc312feb2006-07-10 04:43:53 -0700915 case SECURITY_FS_USE_MNTPOINT:
916 isec->sid = sbsec->mntpoint_sid;
917 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700918 default:
Eric Parisc312feb2006-07-10 04:43:53 -0700919 /* Default to the fs superblock SID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700920 isec->sid = sbsec->sid;
921
922 if (sbsec->proc) {
923 struct proc_inode *proci = PROC_I(inode);
924 if (proci->pde) {
925 isec->sclass = inode_mode_to_security_class(inode->i_mode);
926 rc = selinux_proc_get_sid(proci->pde,
927 isec->sclass,
928 &sid);
929 if (rc)
930 goto out;
931 isec->sid = sid;
932 }
933 }
934 break;
935 }
936
937 isec->initialized = 1;
938
939out:
940 if (isec->sclass == SECCLASS_FILE)
941 isec->sclass = inode_mode_to_security_class(inode->i_mode);
942
943 if (hold_sem)
944 up(&isec->sem);
945 return rc;
946}
947
948/* Convert a Linux signal to an access vector. */
949static inline u32 signal_to_av(int sig)
950{
951 u32 perm = 0;
952
953 switch (sig) {
954 case SIGCHLD:
955 /* Commonly granted from child to parent. */
956 perm = PROCESS__SIGCHLD;
957 break;
958 case SIGKILL:
959 /* Cannot be caught or ignored */
960 perm = PROCESS__SIGKILL;
961 break;
962 case SIGSTOP:
963 /* Cannot be caught or ignored */
964 perm = PROCESS__SIGSTOP;
965 break;
966 default:
967 /* All other signals. */
968 perm = PROCESS__SIGNAL;
969 break;
970 }
971
972 return perm;
973}
974
975/* Check permission betweeen a pair of tasks, e.g. signal checks,
976 fork check, ptrace check, etc. */
977static int task_has_perm(struct task_struct *tsk1,
978 struct task_struct *tsk2,
979 u32 perms)
980{
981 struct task_security_struct *tsec1, *tsec2;
982
983 tsec1 = tsk1->security;
984 tsec2 = tsk2->security;
985 return avc_has_perm(tsec1->sid, tsec2->sid,
986 SECCLASS_PROCESS, perms, NULL);
987}
988
989/* Check whether a task is allowed to use a capability. */
990static int task_has_capability(struct task_struct *tsk,
991 int cap)
992{
993 struct task_security_struct *tsec;
994 struct avc_audit_data ad;
995
996 tsec = tsk->security;
997
998 AVC_AUDIT_DATA_INIT(&ad,CAP);
999 ad.tsk = tsk;
1000 ad.u.cap = cap;
1001
1002 return avc_has_perm(tsec->sid, tsec->sid,
1003 SECCLASS_CAPABILITY, CAP_TO_MASK(cap), &ad);
1004}
1005
1006/* Check whether a task is allowed to use a system operation. */
1007static int task_has_system(struct task_struct *tsk,
1008 u32 perms)
1009{
1010 struct task_security_struct *tsec;
1011
1012 tsec = tsk->security;
1013
1014 return avc_has_perm(tsec->sid, SECINITSID_KERNEL,
1015 SECCLASS_SYSTEM, perms, NULL);
1016}
1017
1018/* Check whether a task has a particular permission to an inode.
1019 The 'adp' parameter is optional and allows other audit
1020 data to be passed (e.g. the dentry). */
1021static int inode_has_perm(struct task_struct *tsk,
1022 struct inode *inode,
1023 u32 perms,
1024 struct avc_audit_data *adp)
1025{
1026 struct task_security_struct *tsec;
1027 struct inode_security_struct *isec;
1028 struct avc_audit_data ad;
1029
1030 tsec = tsk->security;
1031 isec = inode->i_security;
1032
1033 if (!adp) {
1034 adp = &ad;
1035 AVC_AUDIT_DATA_INIT(&ad, FS);
1036 ad.u.fs.inode = inode;
1037 }
1038
1039 return avc_has_perm(tsec->sid, isec->sid, isec->sclass, perms, adp);
1040}
1041
1042/* Same as inode_has_perm, but pass explicit audit data containing
1043 the dentry to help the auditing code to more easily generate the
1044 pathname if needed. */
1045static inline int dentry_has_perm(struct task_struct *tsk,
1046 struct vfsmount *mnt,
1047 struct dentry *dentry,
1048 u32 av)
1049{
1050 struct inode *inode = dentry->d_inode;
1051 struct avc_audit_data ad;
1052 AVC_AUDIT_DATA_INIT(&ad,FS);
1053 ad.u.fs.mnt = mnt;
1054 ad.u.fs.dentry = dentry;
1055 return inode_has_perm(tsk, inode, av, &ad);
1056}
1057
1058/* Check whether a task can use an open file descriptor to
1059 access an inode in a given way. Check access to the
1060 descriptor itself, and then use dentry_has_perm to
1061 check a particular permission to the file.
1062 Access to the descriptor is implicitly granted if it
1063 has the same SID as the process. If av is zero, then
1064 access to the file is not checked, e.g. for cases
1065 where only the descriptor is affected like seek. */
Arjan van de Ven858119e2006-01-14 13:20:43 -08001066static int file_has_perm(struct task_struct *tsk,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001067 struct file *file,
1068 u32 av)
1069{
1070 struct task_security_struct *tsec = tsk->security;
1071 struct file_security_struct *fsec = file->f_security;
1072 struct vfsmount *mnt = file->f_vfsmnt;
1073 struct dentry *dentry = file->f_dentry;
1074 struct inode *inode = dentry->d_inode;
1075 struct avc_audit_data ad;
1076 int rc;
1077
1078 AVC_AUDIT_DATA_INIT(&ad, FS);
1079 ad.u.fs.mnt = mnt;
1080 ad.u.fs.dentry = dentry;
1081
1082 if (tsec->sid != fsec->sid) {
1083 rc = avc_has_perm(tsec->sid, fsec->sid,
1084 SECCLASS_FD,
1085 FD__USE,
1086 &ad);
1087 if (rc)
1088 return rc;
1089 }
1090
1091 /* av is zero if only checking access to the descriptor. */
1092 if (av)
1093 return inode_has_perm(tsk, inode, av, &ad);
1094
1095 return 0;
1096}
1097
1098/* Check whether a task can create a file. */
1099static int may_create(struct inode *dir,
1100 struct dentry *dentry,
1101 u16 tclass)
1102{
1103 struct task_security_struct *tsec;
1104 struct inode_security_struct *dsec;
1105 struct superblock_security_struct *sbsec;
1106 u32 newsid;
1107 struct avc_audit_data ad;
1108 int rc;
1109
1110 tsec = current->security;
1111 dsec = dir->i_security;
1112 sbsec = dir->i_sb->s_security;
1113
1114 AVC_AUDIT_DATA_INIT(&ad, FS);
1115 ad.u.fs.dentry = dentry;
1116
1117 rc = avc_has_perm(tsec->sid, dsec->sid, SECCLASS_DIR,
1118 DIR__ADD_NAME | DIR__SEARCH,
1119 &ad);
1120 if (rc)
1121 return rc;
1122
1123 if (tsec->create_sid && sbsec->behavior != SECURITY_FS_USE_MNTPOINT) {
1124 newsid = tsec->create_sid;
1125 } else {
1126 rc = security_transition_sid(tsec->sid, dsec->sid, tclass,
1127 &newsid);
1128 if (rc)
1129 return rc;
1130 }
1131
1132 rc = avc_has_perm(tsec->sid, newsid, tclass, FILE__CREATE, &ad);
1133 if (rc)
1134 return rc;
1135
1136 return avc_has_perm(newsid, sbsec->sid,
1137 SECCLASS_FILESYSTEM,
1138 FILESYSTEM__ASSOCIATE, &ad);
1139}
1140
Michael LeMay4eb582c2006-06-26 00:24:57 -07001141/* Check whether a task can create a key. */
1142static int may_create_key(u32 ksid,
1143 struct task_struct *ctx)
1144{
1145 struct task_security_struct *tsec;
1146
1147 tsec = ctx->security;
1148
1149 return avc_has_perm(tsec->sid, ksid, SECCLASS_KEY, KEY__CREATE, NULL);
1150}
1151
Linus Torvalds1da177e2005-04-16 15:20:36 -07001152#define MAY_LINK 0
1153#define MAY_UNLINK 1
1154#define MAY_RMDIR 2
1155
1156/* Check whether a task can link, unlink, or rmdir a file/directory. */
1157static int may_link(struct inode *dir,
1158 struct dentry *dentry,
1159 int kind)
1160
1161{
1162 struct task_security_struct *tsec;
1163 struct inode_security_struct *dsec, *isec;
1164 struct avc_audit_data ad;
1165 u32 av;
1166 int rc;
1167
1168 tsec = current->security;
1169 dsec = dir->i_security;
1170 isec = dentry->d_inode->i_security;
1171
1172 AVC_AUDIT_DATA_INIT(&ad, FS);
1173 ad.u.fs.dentry = dentry;
1174
1175 av = DIR__SEARCH;
1176 av |= (kind ? DIR__REMOVE_NAME : DIR__ADD_NAME);
1177 rc = avc_has_perm(tsec->sid, dsec->sid, SECCLASS_DIR, av, &ad);
1178 if (rc)
1179 return rc;
1180
1181 switch (kind) {
1182 case MAY_LINK:
1183 av = FILE__LINK;
1184 break;
1185 case MAY_UNLINK:
1186 av = FILE__UNLINK;
1187 break;
1188 case MAY_RMDIR:
1189 av = DIR__RMDIR;
1190 break;
1191 default:
1192 printk(KERN_WARNING "may_link: unrecognized kind %d\n", kind);
1193 return 0;
1194 }
1195
1196 rc = avc_has_perm(tsec->sid, isec->sid, isec->sclass, av, &ad);
1197 return rc;
1198}
1199
1200static inline int may_rename(struct inode *old_dir,
1201 struct dentry *old_dentry,
1202 struct inode *new_dir,
1203 struct dentry *new_dentry)
1204{
1205 struct task_security_struct *tsec;
1206 struct inode_security_struct *old_dsec, *new_dsec, *old_isec, *new_isec;
1207 struct avc_audit_data ad;
1208 u32 av;
1209 int old_is_dir, new_is_dir;
1210 int rc;
1211
1212 tsec = current->security;
1213 old_dsec = old_dir->i_security;
1214 old_isec = old_dentry->d_inode->i_security;
1215 old_is_dir = S_ISDIR(old_dentry->d_inode->i_mode);
1216 new_dsec = new_dir->i_security;
1217
1218 AVC_AUDIT_DATA_INIT(&ad, FS);
1219
1220 ad.u.fs.dentry = old_dentry;
1221 rc = avc_has_perm(tsec->sid, old_dsec->sid, SECCLASS_DIR,
1222 DIR__REMOVE_NAME | DIR__SEARCH, &ad);
1223 if (rc)
1224 return rc;
1225 rc = avc_has_perm(tsec->sid, old_isec->sid,
1226 old_isec->sclass, FILE__RENAME, &ad);
1227 if (rc)
1228 return rc;
1229 if (old_is_dir && new_dir != old_dir) {
1230 rc = avc_has_perm(tsec->sid, old_isec->sid,
1231 old_isec->sclass, DIR__REPARENT, &ad);
1232 if (rc)
1233 return rc;
1234 }
1235
1236 ad.u.fs.dentry = new_dentry;
1237 av = DIR__ADD_NAME | DIR__SEARCH;
1238 if (new_dentry->d_inode)
1239 av |= DIR__REMOVE_NAME;
1240 rc = avc_has_perm(tsec->sid, new_dsec->sid, SECCLASS_DIR, av, &ad);
1241 if (rc)
1242 return rc;
1243 if (new_dentry->d_inode) {
1244 new_isec = new_dentry->d_inode->i_security;
1245 new_is_dir = S_ISDIR(new_dentry->d_inode->i_mode);
1246 rc = avc_has_perm(tsec->sid, new_isec->sid,
1247 new_isec->sclass,
1248 (new_is_dir ? DIR__RMDIR : FILE__UNLINK), &ad);
1249 if (rc)
1250 return rc;
1251 }
1252
1253 return 0;
1254}
1255
1256/* Check whether a task can perform a filesystem operation. */
1257static int superblock_has_perm(struct task_struct *tsk,
1258 struct super_block *sb,
1259 u32 perms,
1260 struct avc_audit_data *ad)
1261{
1262 struct task_security_struct *tsec;
1263 struct superblock_security_struct *sbsec;
1264
1265 tsec = tsk->security;
1266 sbsec = sb->s_security;
1267 return avc_has_perm(tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
1268 perms, ad);
1269}
1270
1271/* Convert a Linux mode and permission mask to an access vector. */
1272static inline u32 file_mask_to_av(int mode, int mask)
1273{
1274 u32 av = 0;
1275
1276 if ((mode & S_IFMT) != S_IFDIR) {
1277 if (mask & MAY_EXEC)
1278 av |= FILE__EXECUTE;
1279 if (mask & MAY_READ)
1280 av |= FILE__READ;
1281
1282 if (mask & MAY_APPEND)
1283 av |= FILE__APPEND;
1284 else if (mask & MAY_WRITE)
1285 av |= FILE__WRITE;
1286
1287 } else {
1288 if (mask & MAY_EXEC)
1289 av |= DIR__SEARCH;
1290 if (mask & MAY_WRITE)
1291 av |= DIR__WRITE;
1292 if (mask & MAY_READ)
1293 av |= DIR__READ;
1294 }
1295
1296 return av;
1297}
1298
1299/* Convert a Linux file to an access vector. */
1300static inline u32 file_to_av(struct file *file)
1301{
1302 u32 av = 0;
1303
1304 if (file->f_mode & FMODE_READ)
1305 av |= FILE__READ;
1306 if (file->f_mode & FMODE_WRITE) {
1307 if (file->f_flags & O_APPEND)
1308 av |= FILE__APPEND;
1309 else
1310 av |= FILE__WRITE;
1311 }
1312
1313 return av;
1314}
1315
1316/* Set an inode's SID to a specified value. */
1317static int inode_security_set_sid(struct inode *inode, u32 sid)
1318{
1319 struct inode_security_struct *isec = inode->i_security;
1320 struct superblock_security_struct *sbsec = inode->i_sb->s_security;
1321
1322 if (!sbsec->initialized) {
1323 /* Defer initialization to selinux_complete_init. */
1324 return 0;
1325 }
1326
1327 down(&isec->sem);
1328 isec->sclass = inode_mode_to_security_class(inode->i_mode);
1329 isec->sid = sid;
1330 isec->initialized = 1;
1331 up(&isec->sem);
1332 return 0;
1333}
1334
Linus Torvalds1da177e2005-04-16 15:20:36 -07001335/* Hook functions begin here. */
1336
1337static int selinux_ptrace(struct task_struct *parent, struct task_struct *child)
1338{
1339 struct task_security_struct *psec = parent->security;
1340 struct task_security_struct *csec = child->security;
1341 int rc;
1342
1343 rc = secondary_ops->ptrace(parent,child);
1344 if (rc)
1345 return rc;
1346
1347 rc = task_has_perm(parent, child, PROCESS__PTRACE);
1348 /* Save the SID of the tracing process for later use in apply_creds. */
Stephen Smalley341c2d82006-03-11 03:27:16 -08001349 if (!(child->ptrace & PT_PTRACED) && !rc)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001350 csec->ptrace_sid = psec->sid;
1351 return rc;
1352}
1353
1354static int selinux_capget(struct task_struct *target, kernel_cap_t *effective,
1355 kernel_cap_t *inheritable, kernel_cap_t *permitted)
1356{
1357 int error;
1358
1359 error = task_has_perm(current, target, PROCESS__GETCAP);
1360 if (error)
1361 return error;
1362
1363 return secondary_ops->capget(target, effective, inheritable, permitted);
1364}
1365
1366static int selinux_capset_check(struct task_struct *target, kernel_cap_t *effective,
1367 kernel_cap_t *inheritable, kernel_cap_t *permitted)
1368{
1369 int error;
1370
1371 error = secondary_ops->capset_check(target, effective, inheritable, permitted);
1372 if (error)
1373 return error;
1374
1375 return task_has_perm(current, target, PROCESS__SETCAP);
1376}
1377
1378static void selinux_capset_set(struct task_struct *target, kernel_cap_t *effective,
1379 kernel_cap_t *inheritable, kernel_cap_t *permitted)
1380{
1381 secondary_ops->capset_set(target, effective, inheritable, permitted);
1382}
1383
1384static int selinux_capable(struct task_struct *tsk, int cap)
1385{
1386 int rc;
1387
1388 rc = secondary_ops->capable(tsk, cap);
1389 if (rc)
1390 return rc;
1391
1392 return task_has_capability(tsk,cap);
1393}
1394
1395static int selinux_sysctl(ctl_table *table, int op)
1396{
1397 int error = 0;
1398 u32 av;
1399 struct task_security_struct *tsec;
1400 u32 tsid;
1401 int rc;
1402
1403 rc = secondary_ops->sysctl(table, op);
1404 if (rc)
1405 return rc;
1406
1407 tsec = current->security;
1408
1409 rc = selinux_proc_get_sid(table->de, (op == 001) ?
1410 SECCLASS_DIR : SECCLASS_FILE, &tsid);
1411 if (rc) {
1412 /* Default to the well-defined sysctl SID. */
1413 tsid = SECINITSID_SYSCTL;
1414 }
1415
1416 /* The op values are "defined" in sysctl.c, thereby creating
1417 * a bad coupling between this module and sysctl.c */
1418 if(op == 001) {
1419 error = avc_has_perm(tsec->sid, tsid,
1420 SECCLASS_DIR, DIR__SEARCH, NULL);
1421 } else {
1422 av = 0;
1423 if (op & 004)
1424 av |= FILE__READ;
1425 if (op & 002)
1426 av |= FILE__WRITE;
1427 if (av)
1428 error = avc_has_perm(tsec->sid, tsid,
1429 SECCLASS_FILE, av, NULL);
1430 }
1431
1432 return error;
1433}
1434
1435static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb)
1436{
1437 int rc = 0;
1438
1439 if (!sb)
1440 return 0;
1441
1442 switch (cmds) {
1443 case Q_SYNC:
1444 case Q_QUOTAON:
1445 case Q_QUOTAOFF:
1446 case Q_SETINFO:
1447 case Q_SETQUOTA:
1448 rc = superblock_has_perm(current,
1449 sb,
1450 FILESYSTEM__QUOTAMOD, NULL);
1451 break;
1452 case Q_GETFMT:
1453 case Q_GETINFO:
1454 case Q_GETQUOTA:
1455 rc = superblock_has_perm(current,
1456 sb,
1457 FILESYSTEM__QUOTAGET, NULL);
1458 break;
1459 default:
1460 rc = 0; /* let the kernel handle invalid cmds */
1461 break;
1462 }
1463 return rc;
1464}
1465
1466static int selinux_quota_on(struct dentry *dentry)
1467{
1468 return dentry_has_perm(current, NULL, dentry, FILE__QUOTAON);
1469}
1470
1471static int selinux_syslog(int type)
1472{
1473 int rc;
1474
1475 rc = secondary_ops->syslog(type);
1476 if (rc)
1477 return rc;
1478
1479 switch (type) {
1480 case 3: /* Read last kernel messages */
1481 case 10: /* Return size of the log buffer */
1482 rc = task_has_system(current, SYSTEM__SYSLOG_READ);
1483 break;
1484 case 6: /* Disable logging to console */
1485 case 7: /* Enable logging to console */
1486 case 8: /* Set level of messages printed to console */
1487 rc = task_has_system(current, SYSTEM__SYSLOG_CONSOLE);
1488 break;
1489 case 0: /* Close log */
1490 case 1: /* Open log */
1491 case 2: /* Read from log */
1492 case 4: /* Read/clear last kernel messages */
1493 case 5: /* Clear ring buffer */
1494 default:
1495 rc = task_has_system(current, SYSTEM__SYSLOG_MOD);
1496 break;
1497 }
1498 return rc;
1499}
1500
1501/*
1502 * Check that a process has enough memory to allocate a new virtual
1503 * mapping. 0 means there is enough memory for the allocation to
1504 * succeed and -ENOMEM implies there is not.
1505 *
1506 * Note that secondary_ops->capable and task_has_perm_noaudit return 0
1507 * if the capability is granted, but __vm_enough_memory requires 1 if
1508 * the capability is granted.
1509 *
1510 * Do not audit the selinux permission check, as this is applied to all
1511 * processes that allocate mappings.
1512 */
1513static int selinux_vm_enough_memory(long pages)
1514{
1515 int rc, cap_sys_admin = 0;
1516 struct task_security_struct *tsec = current->security;
1517
1518 rc = secondary_ops->capable(current, CAP_SYS_ADMIN);
1519 if (rc == 0)
1520 rc = avc_has_perm_noaudit(tsec->sid, tsec->sid,
1521 SECCLASS_CAPABILITY,
1522 CAP_TO_MASK(CAP_SYS_ADMIN),
1523 NULL);
1524
1525 if (rc == 0)
1526 cap_sys_admin = 1;
1527
1528 return __vm_enough_memory(pages, cap_sys_admin);
1529}
1530
1531/* binprm security operations */
1532
1533static int selinux_bprm_alloc_security(struct linux_binprm *bprm)
1534{
1535 struct bprm_security_struct *bsec;
1536
James Morris89d155e2005-10-30 14:59:21 -08001537 bsec = kzalloc(sizeof(struct bprm_security_struct), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001538 if (!bsec)
1539 return -ENOMEM;
1540
Linus Torvalds1da177e2005-04-16 15:20:36 -07001541 bsec->bprm = bprm;
1542 bsec->sid = SECINITSID_UNLABELED;
1543 bsec->set = 0;
1544
1545 bprm->security = bsec;
1546 return 0;
1547}
1548
1549static int selinux_bprm_set_security(struct linux_binprm *bprm)
1550{
1551 struct task_security_struct *tsec;
1552 struct inode *inode = bprm->file->f_dentry->d_inode;
1553 struct inode_security_struct *isec;
1554 struct bprm_security_struct *bsec;
1555 u32 newsid;
1556 struct avc_audit_data ad;
1557 int rc;
1558
1559 rc = secondary_ops->bprm_set_security(bprm);
1560 if (rc)
1561 return rc;
1562
1563 bsec = bprm->security;
1564
1565 if (bsec->set)
1566 return 0;
1567
1568 tsec = current->security;
1569 isec = inode->i_security;
1570
1571 /* Default to the current task SID. */
1572 bsec->sid = tsec->sid;
1573
Michael LeMay28eba5b2006-06-27 02:53:42 -07001574 /* Reset fs, key, and sock SIDs on execve. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001575 tsec->create_sid = 0;
Michael LeMay28eba5b2006-06-27 02:53:42 -07001576 tsec->keycreate_sid = 0;
Eric Paris42c3e032006-06-26 00:26:03 -07001577 tsec->sockcreate_sid = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001578
1579 if (tsec->exec_sid) {
1580 newsid = tsec->exec_sid;
1581 /* Reset exec SID on execve. */
1582 tsec->exec_sid = 0;
1583 } else {
1584 /* Check for a default transition on this program. */
1585 rc = security_transition_sid(tsec->sid, isec->sid,
1586 SECCLASS_PROCESS, &newsid);
1587 if (rc)
1588 return rc;
1589 }
1590
1591 AVC_AUDIT_DATA_INIT(&ad, FS);
1592 ad.u.fs.mnt = bprm->file->f_vfsmnt;
1593 ad.u.fs.dentry = bprm->file->f_dentry;
1594
1595 if (bprm->file->f_vfsmnt->mnt_flags & MNT_NOSUID)
1596 newsid = tsec->sid;
1597
1598 if (tsec->sid == newsid) {
1599 rc = avc_has_perm(tsec->sid, isec->sid,
1600 SECCLASS_FILE, FILE__EXECUTE_NO_TRANS, &ad);
1601 if (rc)
1602 return rc;
1603 } else {
1604 /* Check permissions for the transition. */
1605 rc = avc_has_perm(tsec->sid, newsid,
1606 SECCLASS_PROCESS, PROCESS__TRANSITION, &ad);
1607 if (rc)
1608 return rc;
1609
1610 rc = avc_has_perm(newsid, isec->sid,
1611 SECCLASS_FILE, FILE__ENTRYPOINT, &ad);
1612 if (rc)
1613 return rc;
1614
1615 /* Clear any possibly unsafe personality bits on exec: */
1616 current->personality &= ~PER_CLEAR_ON_SETID;
1617
1618 /* Set the security field to the new SID. */
1619 bsec->sid = newsid;
1620 }
1621
1622 bsec->set = 1;
1623 return 0;
1624}
1625
1626static int selinux_bprm_check_security (struct linux_binprm *bprm)
1627{
1628 return secondary_ops->bprm_check_security(bprm);
1629}
1630
1631
1632static int selinux_bprm_secureexec (struct linux_binprm *bprm)
1633{
1634 struct task_security_struct *tsec = current->security;
1635 int atsecure = 0;
1636
1637 if (tsec->osid != tsec->sid) {
1638 /* Enable secure mode for SIDs transitions unless
1639 the noatsecure permission is granted between
1640 the two SIDs, i.e. ahp returns 0. */
1641 atsecure = avc_has_perm(tsec->osid, tsec->sid,
1642 SECCLASS_PROCESS,
1643 PROCESS__NOATSECURE, NULL);
1644 }
1645
1646 return (atsecure || secondary_ops->bprm_secureexec(bprm));
1647}
1648
1649static void selinux_bprm_free_security(struct linux_binprm *bprm)
1650{
Jesper Juhl9a5f04b2005-06-25 14:58:51 -07001651 kfree(bprm->security);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001652 bprm->security = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001653}
1654
1655extern struct vfsmount *selinuxfs_mount;
1656extern struct dentry *selinux_null;
1657
1658/* Derived from fs/exec.c:flush_old_files. */
1659static inline void flush_unauthorized_files(struct files_struct * files)
1660{
1661 struct avc_audit_data ad;
1662 struct file *file, *devnull = NULL;
1663 struct tty_struct *tty = current->signal->tty;
Dipankar Sarmabadf1662005-09-09 13:04:10 -07001664 struct fdtable *fdt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001665 long j = -1;
1666
1667 if (tty) {
1668 file_list_lock();
Eric Dumazet2f512012005-10-30 15:02:16 -08001669 file = list_entry(tty->tty_files.next, typeof(*file), f_u.fu_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001670 if (file) {
1671 /* Revalidate access to controlling tty.
1672 Use inode_has_perm on the tty inode directly rather
1673 than using file_has_perm, as this particular open
1674 file may belong to another process and we are only
1675 interested in the inode-based check here. */
1676 struct inode *inode = file->f_dentry->d_inode;
1677 if (inode_has_perm(current, inode,
1678 FILE__READ | FILE__WRITE, NULL)) {
1679 /* Reset controlling tty. */
1680 current->signal->tty = NULL;
1681 current->signal->tty_old_pgrp = 0;
1682 }
1683 }
1684 file_list_unlock();
1685 }
1686
1687 /* Revalidate access to inherited open files. */
1688
1689 AVC_AUDIT_DATA_INIT(&ad,FS);
1690
1691 spin_lock(&files->file_lock);
1692 for (;;) {
1693 unsigned long set, i;
1694 int fd;
1695
1696 j++;
1697 i = j * __NFDBITS;
Dipankar Sarmabadf1662005-09-09 13:04:10 -07001698 fdt = files_fdtable(files);
1699 if (i >= fdt->max_fds || i >= fdt->max_fdset)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001700 break;
Dipankar Sarmabadf1662005-09-09 13:04:10 -07001701 set = fdt->open_fds->fds_bits[j];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001702 if (!set)
1703 continue;
1704 spin_unlock(&files->file_lock);
1705 for ( ; set ; i++,set >>= 1) {
1706 if (set & 1) {
1707 file = fget(i);
1708 if (!file)
1709 continue;
1710 if (file_has_perm(current,
1711 file,
1712 file_to_av(file))) {
1713 sys_close(i);
1714 fd = get_unused_fd();
1715 if (fd != i) {
1716 if (fd >= 0)
1717 put_unused_fd(fd);
1718 fput(file);
1719 continue;
1720 }
1721 if (devnull) {
Nick Piggin095975d2006-01-08 01:02:19 -08001722 get_file(devnull);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001723 } else {
1724 devnull = dentry_open(dget(selinux_null), mntget(selinuxfs_mount), O_RDWR);
1725 if (!devnull) {
1726 put_unused_fd(fd);
1727 fput(file);
1728 continue;
1729 }
1730 }
1731 fd_install(fd, devnull);
1732 }
1733 fput(file);
1734 }
1735 }
1736 spin_lock(&files->file_lock);
1737
1738 }
1739 spin_unlock(&files->file_lock);
1740}
1741
1742static void selinux_bprm_apply_creds(struct linux_binprm *bprm, int unsafe)
1743{
1744 struct task_security_struct *tsec;
1745 struct bprm_security_struct *bsec;
1746 u32 sid;
1747 int rc;
1748
1749 secondary_ops->bprm_apply_creds(bprm, unsafe);
1750
1751 tsec = current->security;
1752
1753 bsec = bprm->security;
1754 sid = bsec->sid;
1755
1756 tsec->osid = tsec->sid;
1757 bsec->unsafe = 0;
1758 if (tsec->sid != sid) {
1759 /* Check for shared state. If not ok, leave SID
1760 unchanged and kill. */
1761 if (unsafe & LSM_UNSAFE_SHARE) {
1762 rc = avc_has_perm(tsec->sid, sid, SECCLASS_PROCESS,
1763 PROCESS__SHARE, NULL);
1764 if (rc) {
1765 bsec->unsafe = 1;
1766 return;
1767 }
1768 }
1769
1770 /* Check for ptracing, and update the task SID if ok.
1771 Otherwise, leave SID unchanged and kill. */
1772 if (unsafe & (LSM_UNSAFE_PTRACE | LSM_UNSAFE_PTRACE_CAP)) {
1773 rc = avc_has_perm(tsec->ptrace_sid, sid,
1774 SECCLASS_PROCESS, PROCESS__PTRACE,
1775 NULL);
1776 if (rc) {
1777 bsec->unsafe = 1;
1778 return;
1779 }
1780 }
1781 tsec->sid = sid;
1782 }
1783}
1784
1785/*
1786 * called after apply_creds without the task lock held
1787 */
1788static void selinux_bprm_post_apply_creds(struct linux_binprm *bprm)
1789{
1790 struct task_security_struct *tsec;
1791 struct rlimit *rlim, *initrlim;
1792 struct itimerval itimer;
1793 struct bprm_security_struct *bsec;
1794 int rc, i;
1795
1796 tsec = current->security;
1797 bsec = bprm->security;
1798
1799 if (bsec->unsafe) {
1800 force_sig_specific(SIGKILL, current);
1801 return;
1802 }
1803 if (tsec->osid == tsec->sid)
1804 return;
1805
1806 /* Close files for which the new task SID is not authorized. */
1807 flush_unauthorized_files(current->files);
1808
1809 /* Check whether the new SID can inherit signal state
1810 from the old SID. If not, clear itimers to avoid
1811 subsequent signal generation and flush and unblock
1812 signals. This must occur _after_ the task SID has
1813 been updated so that any kill done after the flush
1814 will be checked against the new SID. */
1815 rc = avc_has_perm(tsec->osid, tsec->sid, SECCLASS_PROCESS,
1816 PROCESS__SIGINH, NULL);
1817 if (rc) {
1818 memset(&itimer, 0, sizeof itimer);
1819 for (i = 0; i < 3; i++)
1820 do_setitimer(i, &itimer, NULL);
1821 flush_signals(current);
1822 spin_lock_irq(&current->sighand->siglock);
1823 flush_signal_handlers(current, 1);
1824 sigemptyset(&current->blocked);
1825 recalc_sigpending();
1826 spin_unlock_irq(&current->sighand->siglock);
1827 }
1828
1829 /* Check whether the new SID can inherit resource limits
1830 from the old SID. If not, reset all soft limits to
1831 the lower of the current task's hard limit and the init
1832 task's soft limit. Note that the setting of hard limits
1833 (even to lower them) can be controlled by the setrlimit
1834 check. The inclusion of the init task's soft limit into
1835 the computation is to avoid resetting soft limits higher
1836 than the default soft limit for cases where the default
1837 is lower than the hard limit, e.g. RLIMIT_CORE or
1838 RLIMIT_STACK.*/
1839 rc = avc_has_perm(tsec->osid, tsec->sid, SECCLASS_PROCESS,
1840 PROCESS__RLIMITINH, NULL);
1841 if (rc) {
1842 for (i = 0; i < RLIM_NLIMITS; i++) {
1843 rlim = current->signal->rlim + i;
1844 initrlim = init_task.signal->rlim+i;
1845 rlim->rlim_cur = min(rlim->rlim_max,initrlim->rlim_cur);
1846 }
1847 if (current->signal->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY) {
1848 /*
1849 * This will cause RLIMIT_CPU calculations
1850 * to be refigured.
1851 */
1852 current->it_prof_expires = jiffies_to_cputime(1);
1853 }
1854 }
1855
1856 /* Wake up the parent if it is waiting so that it can
1857 recheck wait permission to the new task SID. */
1858 wake_up_interruptible(&current->parent->signal->wait_chldexit);
1859}
1860
1861/* superblock security operations */
1862
1863static int selinux_sb_alloc_security(struct super_block *sb)
1864{
1865 return superblock_alloc_security(sb);
1866}
1867
1868static void selinux_sb_free_security(struct super_block *sb)
1869{
1870 superblock_free_security(sb);
1871}
1872
1873static inline int match_prefix(char *prefix, int plen, char *option, int olen)
1874{
1875 if (plen > olen)
1876 return 0;
1877
1878 return !memcmp(prefix, option, plen);
1879}
1880
1881static inline int selinux_option(char *option, int len)
1882{
1883 return (match_prefix("context=", sizeof("context=")-1, option, len) ||
1884 match_prefix("fscontext=", sizeof("fscontext=")-1, option, len) ||
1885 match_prefix("defcontext=", sizeof("defcontext=")-1, option, len));
1886}
1887
1888static inline void take_option(char **to, char *from, int *first, int len)
1889{
1890 if (!*first) {
1891 **to = ',';
1892 *to += 1;
1893 }
1894 else
1895 *first = 0;
1896 memcpy(*to, from, len);
1897 *to += len;
1898}
1899
1900static int selinux_sb_copy_data(struct file_system_type *type, void *orig, void *copy)
1901{
1902 int fnosec, fsec, rc = 0;
1903 char *in_save, *in_curr, *in_end;
1904 char *sec_curr, *nosec_save, *nosec;
1905
1906 in_curr = orig;
1907 sec_curr = copy;
1908
1909 /* Binary mount data: just copy */
1910 if (type->fs_flags & FS_BINARY_MOUNTDATA) {
1911 copy_page(sec_curr, in_curr);
1912 goto out;
1913 }
1914
1915 nosec = (char *)get_zeroed_page(GFP_KERNEL);
1916 if (!nosec) {
1917 rc = -ENOMEM;
1918 goto out;
1919 }
1920
1921 nosec_save = nosec;
1922 fnosec = fsec = 1;
1923 in_save = in_end = orig;
1924
1925 do {
1926 if (*in_end == ',' || *in_end == '\0') {
1927 int len = in_end - in_curr;
1928
1929 if (selinux_option(in_curr, len))
1930 take_option(&sec_curr, in_curr, &fsec, len);
1931 else
1932 take_option(&nosec, in_curr, &fnosec, len);
1933
1934 in_curr = in_end + 1;
1935 }
1936 } while (*in_end++);
1937
Eric Paris6931dfc2005-06-30 02:58:51 -07001938 strcpy(in_save, nosec_save);
Gerald Schaeferda3caa22005-06-21 17:15:18 -07001939 free_page((unsigned long)nosec_save);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001940out:
1941 return rc;
1942}
1943
1944static int selinux_sb_kern_mount(struct super_block *sb, void *data)
1945{
1946 struct avc_audit_data ad;
1947 int rc;
1948
1949 rc = superblock_doinit(sb, data);
1950 if (rc)
1951 return rc;
1952
1953 AVC_AUDIT_DATA_INIT(&ad,FS);
1954 ad.u.fs.dentry = sb->s_root;
1955 return superblock_has_perm(current, sb, FILESYSTEM__MOUNT, &ad);
1956}
1957
David Howells726c3342006-06-23 02:02:58 -07001958static int selinux_sb_statfs(struct dentry *dentry)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001959{
1960 struct avc_audit_data ad;
1961
1962 AVC_AUDIT_DATA_INIT(&ad,FS);
David Howells726c3342006-06-23 02:02:58 -07001963 ad.u.fs.dentry = dentry->d_sb->s_root;
1964 return superblock_has_perm(current, dentry->d_sb, FILESYSTEM__GETATTR, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001965}
1966
1967static int selinux_mount(char * dev_name,
1968 struct nameidata *nd,
1969 char * type,
1970 unsigned long flags,
1971 void * data)
1972{
1973 int rc;
1974
1975 rc = secondary_ops->sb_mount(dev_name, nd, type, flags, data);
1976 if (rc)
1977 return rc;
1978
1979 if (flags & MS_REMOUNT)
1980 return superblock_has_perm(current, nd->mnt->mnt_sb,
1981 FILESYSTEM__REMOUNT, NULL);
1982 else
1983 return dentry_has_perm(current, nd->mnt, nd->dentry,
1984 FILE__MOUNTON);
1985}
1986
1987static int selinux_umount(struct vfsmount *mnt, int flags)
1988{
1989 int rc;
1990
1991 rc = secondary_ops->sb_umount(mnt, flags);
1992 if (rc)
1993 return rc;
1994
1995 return superblock_has_perm(current,mnt->mnt_sb,
1996 FILESYSTEM__UNMOUNT,NULL);
1997}
1998
1999/* inode security operations */
2000
2001static int selinux_inode_alloc_security(struct inode *inode)
2002{
2003 return inode_alloc_security(inode);
2004}
2005
2006static void selinux_inode_free_security(struct inode *inode)
2007{
2008 inode_free_security(inode);
2009}
2010
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002011static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
2012 char **name, void **value,
2013 size_t *len)
2014{
2015 struct task_security_struct *tsec;
2016 struct inode_security_struct *dsec;
2017 struct superblock_security_struct *sbsec;
Stephen Smalley570bc1c2005-09-09 13:01:43 -07002018 u32 newsid, clen;
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002019 int rc;
Stephen Smalley570bc1c2005-09-09 13:01:43 -07002020 char *namep = NULL, *context;
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002021
2022 tsec = current->security;
2023 dsec = dir->i_security;
2024 sbsec = dir->i_sb->s_security;
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002025
2026 if (tsec->create_sid && sbsec->behavior != SECURITY_FS_USE_MNTPOINT) {
2027 newsid = tsec->create_sid;
2028 } else {
2029 rc = security_transition_sid(tsec->sid, dsec->sid,
2030 inode_mode_to_security_class(inode->i_mode),
2031 &newsid);
2032 if (rc) {
2033 printk(KERN_WARNING "%s: "
2034 "security_transition_sid failed, rc=%d (dev=%s "
2035 "ino=%ld)\n",
2036 __FUNCTION__,
2037 -rc, inode->i_sb->s_id, inode->i_ino);
2038 return rc;
2039 }
2040 }
2041
2042 inode_security_set_sid(inode, newsid);
2043
Stephen Smalley8aad3872006-03-22 00:09:13 -08002044 if (!ss_initialized || sbsec->behavior == SECURITY_FS_USE_MNTPOINT)
Stephen Smalley25a74f32005-11-08 21:34:33 -08002045 return -EOPNOTSUPP;
2046
Stephen Smalley570bc1c2005-09-09 13:01:43 -07002047 if (name) {
2048 namep = kstrdup(XATTR_SELINUX_SUFFIX, GFP_KERNEL);
2049 if (!namep)
2050 return -ENOMEM;
2051 *name = namep;
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002052 }
Stephen Smalley570bc1c2005-09-09 13:01:43 -07002053
2054 if (value && len) {
2055 rc = security_sid_to_context(newsid, &context, &clen);
2056 if (rc) {
2057 kfree(namep);
2058 return rc;
2059 }
2060 *value = context;
2061 *len = clen;
2062 }
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002063
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002064 return 0;
2065}
2066
Linus Torvalds1da177e2005-04-16 15:20:36 -07002067static int selinux_inode_create(struct inode *dir, struct dentry *dentry, int mask)
2068{
2069 return may_create(dir, dentry, SECCLASS_FILE);
2070}
2071
Linus Torvalds1da177e2005-04-16 15:20:36 -07002072static int selinux_inode_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry)
2073{
2074 int rc;
2075
2076 rc = secondary_ops->inode_link(old_dentry,dir,new_dentry);
2077 if (rc)
2078 return rc;
2079 return may_link(dir, old_dentry, MAY_LINK);
2080}
2081
Linus Torvalds1da177e2005-04-16 15:20:36 -07002082static int selinux_inode_unlink(struct inode *dir, struct dentry *dentry)
2083{
2084 int rc;
2085
2086 rc = secondary_ops->inode_unlink(dir, dentry);
2087 if (rc)
2088 return rc;
2089 return may_link(dir, dentry, MAY_UNLINK);
2090}
2091
2092static int selinux_inode_symlink(struct inode *dir, struct dentry *dentry, const char *name)
2093{
2094 return may_create(dir, dentry, SECCLASS_LNK_FILE);
2095}
2096
Linus Torvalds1da177e2005-04-16 15:20:36 -07002097static int selinux_inode_mkdir(struct inode *dir, struct dentry *dentry, int mask)
2098{
2099 return may_create(dir, dentry, SECCLASS_DIR);
2100}
2101
Linus Torvalds1da177e2005-04-16 15:20:36 -07002102static int selinux_inode_rmdir(struct inode *dir, struct dentry *dentry)
2103{
2104 return may_link(dir, dentry, MAY_RMDIR);
2105}
2106
2107static int selinux_inode_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
2108{
2109 int rc;
2110
2111 rc = secondary_ops->inode_mknod(dir, dentry, mode, dev);
2112 if (rc)
2113 return rc;
2114
2115 return may_create(dir, dentry, inode_mode_to_security_class(mode));
2116}
2117
Linus Torvalds1da177e2005-04-16 15:20:36 -07002118static int selinux_inode_rename(struct inode *old_inode, struct dentry *old_dentry,
2119 struct inode *new_inode, struct dentry *new_dentry)
2120{
2121 return may_rename(old_inode, old_dentry, new_inode, new_dentry);
2122}
2123
Linus Torvalds1da177e2005-04-16 15:20:36 -07002124static int selinux_inode_readlink(struct dentry *dentry)
2125{
2126 return dentry_has_perm(current, NULL, dentry, FILE__READ);
2127}
2128
2129static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *nameidata)
2130{
2131 int rc;
2132
2133 rc = secondary_ops->inode_follow_link(dentry,nameidata);
2134 if (rc)
2135 return rc;
2136 return dentry_has_perm(current, NULL, dentry, FILE__READ);
2137}
2138
2139static int selinux_inode_permission(struct inode *inode, int mask,
2140 struct nameidata *nd)
2141{
2142 int rc;
2143
2144 rc = secondary_ops->inode_permission(inode, mask, nd);
2145 if (rc)
2146 return rc;
2147
2148 if (!mask) {
2149 /* No permission to check. Existence test. */
2150 return 0;
2151 }
2152
2153 return inode_has_perm(current, inode,
2154 file_mask_to_av(inode->i_mode, mask), NULL);
2155}
2156
2157static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
2158{
2159 int rc;
2160
2161 rc = secondary_ops->inode_setattr(dentry, iattr);
2162 if (rc)
2163 return rc;
2164
2165 if (iattr->ia_valid & ATTR_FORCE)
2166 return 0;
2167
2168 if (iattr->ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID |
2169 ATTR_ATIME_SET | ATTR_MTIME_SET))
2170 return dentry_has_perm(current, NULL, dentry, FILE__SETATTR);
2171
2172 return dentry_has_perm(current, NULL, dentry, FILE__WRITE);
2173}
2174
2175static int selinux_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
2176{
2177 return dentry_has_perm(current, mnt, dentry, FILE__GETATTR);
2178}
2179
2180static int selinux_inode_setxattr(struct dentry *dentry, char *name, void *value, size_t size, int flags)
2181{
2182 struct task_security_struct *tsec = current->security;
2183 struct inode *inode = dentry->d_inode;
2184 struct inode_security_struct *isec = inode->i_security;
2185 struct superblock_security_struct *sbsec;
2186 struct avc_audit_data ad;
2187 u32 newsid;
2188 int rc = 0;
2189
2190 if (strcmp(name, XATTR_NAME_SELINUX)) {
2191 if (!strncmp(name, XATTR_SECURITY_PREFIX,
2192 sizeof XATTR_SECURITY_PREFIX - 1) &&
2193 !capable(CAP_SYS_ADMIN)) {
2194 /* A different attribute in the security namespace.
2195 Restrict to administrator. */
2196 return -EPERM;
2197 }
2198
2199 /* Not an attribute we recognize, so just check the
2200 ordinary setattr permission. */
2201 return dentry_has_perm(current, NULL, dentry, FILE__SETATTR);
2202 }
2203
2204 sbsec = inode->i_sb->s_security;
2205 if (sbsec->behavior == SECURITY_FS_USE_MNTPOINT)
2206 return -EOPNOTSUPP;
2207
2208 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
2209 return -EPERM;
2210
2211 AVC_AUDIT_DATA_INIT(&ad,FS);
2212 ad.u.fs.dentry = dentry;
2213
2214 rc = avc_has_perm(tsec->sid, isec->sid, isec->sclass,
2215 FILE__RELABELFROM, &ad);
2216 if (rc)
2217 return rc;
2218
2219 rc = security_context_to_sid(value, size, &newsid);
2220 if (rc)
2221 return rc;
2222
2223 rc = avc_has_perm(tsec->sid, newsid, isec->sclass,
2224 FILE__RELABELTO, &ad);
2225 if (rc)
2226 return rc;
2227
2228 rc = security_validate_transition(isec->sid, newsid, tsec->sid,
2229 isec->sclass);
2230 if (rc)
2231 return rc;
2232
2233 return avc_has_perm(newsid,
2234 sbsec->sid,
2235 SECCLASS_FILESYSTEM,
2236 FILESYSTEM__ASSOCIATE,
2237 &ad);
2238}
2239
2240static void selinux_inode_post_setxattr(struct dentry *dentry, char *name,
2241 void *value, size_t size, int flags)
2242{
2243 struct inode *inode = dentry->d_inode;
2244 struct inode_security_struct *isec = inode->i_security;
2245 u32 newsid;
2246 int rc;
2247
2248 if (strcmp(name, XATTR_NAME_SELINUX)) {
2249 /* Not an attribute we recognize, so nothing to do. */
2250 return;
2251 }
2252
2253 rc = security_context_to_sid(value, size, &newsid);
2254 if (rc) {
2255 printk(KERN_WARNING "%s: unable to obtain SID for context "
2256 "%s, rc=%d\n", __FUNCTION__, (char*)value, -rc);
2257 return;
2258 }
2259
2260 isec->sid = newsid;
2261 return;
2262}
2263
2264static int selinux_inode_getxattr (struct dentry *dentry, char *name)
2265{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002266 return dentry_has_perm(current, NULL, dentry, FILE__GETATTR);
2267}
2268
2269static int selinux_inode_listxattr (struct dentry *dentry)
2270{
2271 return dentry_has_perm(current, NULL, dentry, FILE__GETATTR);
2272}
2273
2274static int selinux_inode_removexattr (struct dentry *dentry, char *name)
2275{
2276 if (strcmp(name, XATTR_NAME_SELINUX)) {
2277 if (!strncmp(name, XATTR_SECURITY_PREFIX,
2278 sizeof XATTR_SECURITY_PREFIX - 1) &&
2279 !capable(CAP_SYS_ADMIN)) {
2280 /* A different attribute in the security namespace.
2281 Restrict to administrator. */
2282 return -EPERM;
2283 }
2284
2285 /* Not an attribute we recognize, so just check the
2286 ordinary setattr permission. Might want a separate
2287 permission for removexattr. */
2288 return dentry_has_perm(current, NULL, dentry, FILE__SETATTR);
2289 }
2290
2291 /* No one is allowed to remove a SELinux security label.
2292 You can change the label, but all data must be labeled. */
2293 return -EACCES;
2294}
2295
Dustin Kirkland8c8570f2005-11-03 17:15:16 +00002296static const char *selinux_inode_xattr_getsuffix(void)
2297{
2298 return XATTR_SELINUX_SUFFIX;
2299}
2300
James Morrisd381d8a2005-10-30 14:59:22 -08002301/*
2302 * Copy the in-core inode security context value to the user. If the
2303 * getxattr() prior to this succeeded, check to see if we need to
2304 * canonicalize the value to be finally returned to the user.
2305 *
2306 * Permission check is handled by selinux_inode_getxattr hook.
2307 */
Dustin Kirkland7306a0b2005-11-16 15:53:13 +00002308static int selinux_inode_getsecurity(const struct inode *inode, const char *name, void *buffer, size_t size, int err)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002309{
2310 struct inode_security_struct *isec = inode->i_security;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002311
Dustin Kirkland8c8570f2005-11-03 17:15:16 +00002312 if (strcmp(name, XATTR_SELINUX_SUFFIX))
2313 return -EOPNOTSUPP;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002314
Dustin Kirkland8c8570f2005-11-03 17:15:16 +00002315 return selinux_getsecurity(isec->sid, buffer, size);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002316}
2317
2318static int selinux_inode_setsecurity(struct inode *inode, const char *name,
2319 const void *value, size_t size, int flags)
2320{
2321 struct inode_security_struct *isec = inode->i_security;
2322 u32 newsid;
2323 int rc;
2324
2325 if (strcmp(name, XATTR_SELINUX_SUFFIX))
2326 return -EOPNOTSUPP;
2327
2328 if (!value || !size)
2329 return -EACCES;
2330
2331 rc = security_context_to_sid((void*)value, size, &newsid);
2332 if (rc)
2333 return rc;
2334
2335 isec->sid = newsid;
2336 return 0;
2337}
2338
2339static int selinux_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size)
2340{
2341 const int len = sizeof(XATTR_NAME_SELINUX);
2342 if (buffer && len <= buffer_size)
2343 memcpy(buffer, XATTR_NAME_SELINUX, len);
2344 return len;
2345}
2346
2347/* file security operations */
2348
2349static int selinux_file_permission(struct file *file, int mask)
2350{
2351 struct inode *inode = file->f_dentry->d_inode;
2352
2353 if (!mask) {
2354 /* No permission to check. Existence test. */
2355 return 0;
2356 }
2357
2358 /* file_mask_to_av won't add FILE__WRITE if MAY_APPEND is set */
2359 if ((file->f_flags & O_APPEND) && (mask & MAY_WRITE))
2360 mask |= MAY_APPEND;
2361
2362 return file_has_perm(current, file,
2363 file_mask_to_av(inode->i_mode, mask));
2364}
2365
2366static int selinux_file_alloc_security(struct file *file)
2367{
2368 return file_alloc_security(file);
2369}
2370
2371static void selinux_file_free_security(struct file *file)
2372{
2373 file_free_security(file);
2374}
2375
2376static int selinux_file_ioctl(struct file *file, unsigned int cmd,
2377 unsigned long arg)
2378{
2379 int error = 0;
2380
2381 switch (cmd) {
2382 case FIONREAD:
2383 /* fall through */
2384 case FIBMAP:
2385 /* fall through */
2386 case FIGETBSZ:
2387 /* fall through */
2388 case EXT2_IOC_GETFLAGS:
2389 /* fall through */
2390 case EXT2_IOC_GETVERSION:
2391 error = file_has_perm(current, file, FILE__GETATTR);
2392 break;
2393
2394 case EXT2_IOC_SETFLAGS:
2395 /* fall through */
2396 case EXT2_IOC_SETVERSION:
2397 error = file_has_perm(current, file, FILE__SETATTR);
2398 break;
2399
2400 /* sys_ioctl() checks */
2401 case FIONBIO:
2402 /* fall through */
2403 case FIOASYNC:
2404 error = file_has_perm(current, file, 0);
2405 break;
2406
2407 case KDSKBENT:
2408 case KDSKBSENT:
2409 error = task_has_capability(current,CAP_SYS_TTY_CONFIG);
2410 break;
2411
2412 /* default case assumes that the command will go
2413 * to the file's ioctl() function.
2414 */
2415 default:
2416 error = file_has_perm(current, file, FILE__IOCTL);
2417
2418 }
2419 return error;
2420}
2421
2422static int file_map_prot_check(struct file *file, unsigned long prot, int shared)
2423{
2424#ifndef CONFIG_PPC32
2425 if ((prot & PROT_EXEC) && (!file || (!shared && (prot & PROT_WRITE)))) {
2426 /*
2427 * We are making executable an anonymous mapping or a
2428 * private file mapping that will also be writable.
2429 * This has an additional check.
2430 */
2431 int rc = task_has_perm(current, current, PROCESS__EXECMEM);
2432 if (rc)
2433 return rc;
2434 }
2435#endif
2436
2437 if (file) {
2438 /* read access is always possible with a mapping */
2439 u32 av = FILE__READ;
2440
2441 /* write access only matters if the mapping is shared */
2442 if (shared && (prot & PROT_WRITE))
2443 av |= FILE__WRITE;
2444
2445 if (prot & PROT_EXEC)
2446 av |= FILE__EXECUTE;
2447
2448 return file_has_perm(current, file, av);
2449 }
2450 return 0;
2451}
2452
2453static int selinux_file_mmap(struct file *file, unsigned long reqprot,
2454 unsigned long prot, unsigned long flags)
2455{
2456 int rc;
2457
2458 rc = secondary_ops->file_mmap(file, reqprot, prot, flags);
2459 if (rc)
2460 return rc;
2461
2462 if (selinux_checkreqprot)
2463 prot = reqprot;
2464
2465 return file_map_prot_check(file, prot,
2466 (flags & MAP_TYPE) == MAP_SHARED);
2467}
2468
2469static int selinux_file_mprotect(struct vm_area_struct *vma,
2470 unsigned long reqprot,
2471 unsigned long prot)
2472{
2473 int rc;
2474
2475 rc = secondary_ops->file_mprotect(vma, reqprot, prot);
2476 if (rc)
2477 return rc;
2478
2479 if (selinux_checkreqprot)
2480 prot = reqprot;
2481
2482#ifndef CONFIG_PPC32
Stephen Smalleydb4c9642006-02-01 03:05:54 -08002483 if ((prot & PROT_EXEC) && !(vma->vm_flags & VM_EXEC)) {
2484 rc = 0;
2485 if (vma->vm_start >= vma->vm_mm->start_brk &&
2486 vma->vm_end <= vma->vm_mm->brk) {
2487 rc = task_has_perm(current, current,
2488 PROCESS__EXECHEAP);
2489 } else if (!vma->vm_file &&
2490 vma->vm_start <= vma->vm_mm->start_stack &&
2491 vma->vm_end >= vma->vm_mm->start_stack) {
2492 rc = task_has_perm(current, current, PROCESS__EXECSTACK);
2493 } else if (vma->vm_file && vma->anon_vma) {
2494 /*
2495 * We are making executable a file mapping that has
2496 * had some COW done. Since pages might have been
2497 * written, check ability to execute the possibly
2498 * modified content. This typically should only
2499 * occur for text relocations.
2500 */
2501 rc = file_has_perm(current, vma->vm_file,
2502 FILE__EXECMOD);
2503 }
Lorenzo Hernandez García-Hierro6b992192005-06-25 14:54:34 -07002504 if (rc)
2505 return rc;
2506 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002507#endif
2508
2509 return file_map_prot_check(vma->vm_file, prot, vma->vm_flags&VM_SHARED);
2510}
2511
2512static int selinux_file_lock(struct file *file, unsigned int cmd)
2513{
2514 return file_has_perm(current, file, FILE__LOCK);
2515}
2516
2517static int selinux_file_fcntl(struct file *file, unsigned int cmd,
2518 unsigned long arg)
2519{
2520 int err = 0;
2521
2522 switch (cmd) {
2523 case F_SETFL:
2524 if (!file->f_dentry || !file->f_dentry->d_inode) {
2525 err = -EINVAL;
2526 break;
2527 }
2528
2529 if ((file->f_flags & O_APPEND) && !(arg & O_APPEND)) {
2530 err = file_has_perm(current, file,FILE__WRITE);
2531 break;
2532 }
2533 /* fall through */
2534 case F_SETOWN:
2535 case F_SETSIG:
2536 case F_GETFL:
2537 case F_GETOWN:
2538 case F_GETSIG:
2539 /* Just check FD__USE permission */
2540 err = file_has_perm(current, file, 0);
2541 break;
2542 case F_GETLK:
2543 case F_SETLK:
2544 case F_SETLKW:
2545#if BITS_PER_LONG == 32
2546 case F_GETLK64:
2547 case F_SETLK64:
2548 case F_SETLKW64:
2549#endif
2550 if (!file->f_dentry || !file->f_dentry->d_inode) {
2551 err = -EINVAL;
2552 break;
2553 }
2554 err = file_has_perm(current, file, FILE__LOCK);
2555 break;
2556 }
2557
2558 return err;
2559}
2560
2561static int selinux_file_set_fowner(struct file *file)
2562{
2563 struct task_security_struct *tsec;
2564 struct file_security_struct *fsec;
2565
2566 tsec = current->security;
2567 fsec = file->f_security;
2568 fsec->fown_sid = tsec->sid;
2569
2570 return 0;
2571}
2572
2573static int selinux_file_send_sigiotask(struct task_struct *tsk,
2574 struct fown_struct *fown, int signum)
2575{
2576 struct file *file;
2577 u32 perm;
2578 struct task_security_struct *tsec;
2579 struct file_security_struct *fsec;
2580
2581 /* struct fown_struct is never outside the context of a struct file */
2582 file = (struct file *)((long)fown - offsetof(struct file,f_owner));
2583
2584 tsec = tsk->security;
2585 fsec = file->f_security;
2586
2587 if (!signum)
2588 perm = signal_to_av(SIGIO); /* as per send_sigio_to_task */
2589 else
2590 perm = signal_to_av(signum);
2591
2592 return avc_has_perm(fsec->fown_sid, tsec->sid,
2593 SECCLASS_PROCESS, perm, NULL);
2594}
2595
2596static int selinux_file_receive(struct file *file)
2597{
2598 return file_has_perm(current, file, file_to_av(file));
2599}
2600
2601/* task security operations */
2602
2603static int selinux_task_create(unsigned long clone_flags)
2604{
2605 int rc;
2606
2607 rc = secondary_ops->task_create(clone_flags);
2608 if (rc)
2609 return rc;
2610
2611 return task_has_perm(current, current, PROCESS__FORK);
2612}
2613
2614static int selinux_task_alloc_security(struct task_struct *tsk)
2615{
2616 struct task_security_struct *tsec1, *tsec2;
2617 int rc;
2618
2619 tsec1 = current->security;
2620
2621 rc = task_alloc_security(tsk);
2622 if (rc)
2623 return rc;
2624 tsec2 = tsk->security;
2625
2626 tsec2->osid = tsec1->osid;
2627 tsec2->sid = tsec1->sid;
2628
Michael LeMay28eba5b2006-06-27 02:53:42 -07002629 /* Retain the exec, fs, key, and sock SIDs across fork */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002630 tsec2->exec_sid = tsec1->exec_sid;
2631 tsec2->create_sid = tsec1->create_sid;
Michael LeMay28eba5b2006-06-27 02:53:42 -07002632 tsec2->keycreate_sid = tsec1->keycreate_sid;
Eric Paris42c3e032006-06-26 00:26:03 -07002633 tsec2->sockcreate_sid = tsec1->sockcreate_sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002634
2635 /* Retain ptracer SID across fork, if any.
2636 This will be reset by the ptrace hook upon any
2637 subsequent ptrace_attach operations. */
2638 tsec2->ptrace_sid = tsec1->ptrace_sid;
2639
2640 return 0;
2641}
2642
2643static void selinux_task_free_security(struct task_struct *tsk)
2644{
2645 task_free_security(tsk);
2646}
2647
2648static int selinux_task_setuid(uid_t id0, uid_t id1, uid_t id2, int flags)
2649{
2650 /* Since setuid only affects the current process, and
2651 since the SELinux controls are not based on the Linux
2652 identity attributes, SELinux does not need to control
2653 this operation. However, SELinux does control the use
2654 of the CAP_SETUID and CAP_SETGID capabilities using the
2655 capable hook. */
2656 return 0;
2657}
2658
2659static int selinux_task_post_setuid(uid_t id0, uid_t id1, uid_t id2, int flags)
2660{
2661 return secondary_ops->task_post_setuid(id0,id1,id2,flags);
2662}
2663
2664static int selinux_task_setgid(gid_t id0, gid_t id1, gid_t id2, int flags)
2665{
2666 /* See the comment for setuid above. */
2667 return 0;
2668}
2669
2670static int selinux_task_setpgid(struct task_struct *p, pid_t pgid)
2671{
2672 return task_has_perm(current, p, PROCESS__SETPGID);
2673}
2674
2675static int selinux_task_getpgid(struct task_struct *p)
2676{
2677 return task_has_perm(current, p, PROCESS__GETPGID);
2678}
2679
2680static int selinux_task_getsid(struct task_struct *p)
2681{
2682 return task_has_perm(current, p, PROCESS__GETSESSION);
2683}
2684
David Quigleyf9008e42006-06-30 01:55:46 -07002685static void selinux_task_getsecid(struct task_struct *p, u32 *secid)
2686{
2687 selinux_get_task_sid(p, secid);
2688}
2689
Linus Torvalds1da177e2005-04-16 15:20:36 -07002690static int selinux_task_setgroups(struct group_info *group_info)
2691{
2692 /* See the comment for setuid above. */
2693 return 0;
2694}
2695
2696static int selinux_task_setnice(struct task_struct *p, int nice)
2697{
2698 int rc;
2699
2700 rc = secondary_ops->task_setnice(p, nice);
2701 if (rc)
2702 return rc;
2703
2704 return task_has_perm(current,p, PROCESS__SETSCHED);
2705}
2706
James Morris03e68062006-06-23 02:03:58 -07002707static int selinux_task_setioprio(struct task_struct *p, int ioprio)
2708{
2709 return task_has_perm(current, p, PROCESS__SETSCHED);
2710}
2711
David Quigleya1836a42006-06-30 01:55:49 -07002712static int selinux_task_getioprio(struct task_struct *p)
2713{
2714 return task_has_perm(current, p, PROCESS__GETSCHED);
2715}
2716
Linus Torvalds1da177e2005-04-16 15:20:36 -07002717static int selinux_task_setrlimit(unsigned int resource, struct rlimit *new_rlim)
2718{
2719 struct rlimit *old_rlim = current->signal->rlim + resource;
2720 int rc;
2721
2722 rc = secondary_ops->task_setrlimit(resource, new_rlim);
2723 if (rc)
2724 return rc;
2725
2726 /* Control the ability to change the hard limit (whether
2727 lowering or raising it), so that the hard limit can
2728 later be used as a safe reset point for the soft limit
2729 upon context transitions. See selinux_bprm_apply_creds. */
2730 if (old_rlim->rlim_max != new_rlim->rlim_max)
2731 return task_has_perm(current, current, PROCESS__SETRLIMIT);
2732
2733 return 0;
2734}
2735
2736static int selinux_task_setscheduler(struct task_struct *p, int policy, struct sched_param *lp)
2737{
2738 return task_has_perm(current, p, PROCESS__SETSCHED);
2739}
2740
2741static int selinux_task_getscheduler(struct task_struct *p)
2742{
2743 return task_has_perm(current, p, PROCESS__GETSCHED);
2744}
2745
David Quigley35601542006-06-23 02:04:01 -07002746static int selinux_task_movememory(struct task_struct *p)
2747{
2748 return task_has_perm(current, p, PROCESS__SETSCHED);
2749}
2750
David Quigleyf9008e42006-06-30 01:55:46 -07002751static int selinux_task_kill(struct task_struct *p, struct siginfo *info,
2752 int sig, u32 secid)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002753{
2754 u32 perm;
2755 int rc;
David Quigleyf9008e42006-06-30 01:55:46 -07002756 struct task_security_struct *tsec;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002757
David Quigleyf9008e42006-06-30 01:55:46 -07002758 rc = secondary_ops->task_kill(p, info, sig, secid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002759 if (rc)
2760 return rc;
2761
Oleg Nesterov621d3122005-10-30 15:03:45 -08002762 if (info != SEND_SIG_NOINFO && (is_si_special(info) || SI_FROMKERNEL(info)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002763 return 0;
2764
2765 if (!sig)
2766 perm = PROCESS__SIGNULL; /* null signal; existence test */
2767 else
2768 perm = signal_to_av(sig);
David Quigleyf9008e42006-06-30 01:55:46 -07002769 tsec = p->security;
2770 if (secid)
2771 rc = avc_has_perm(secid, tsec->sid, SECCLASS_PROCESS, perm, NULL);
2772 else
2773 rc = task_has_perm(current, p, perm);
2774 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002775}
2776
2777static int selinux_task_prctl(int option,
2778 unsigned long arg2,
2779 unsigned long arg3,
2780 unsigned long arg4,
2781 unsigned long arg5)
2782{
2783 /* The current prctl operations do not appear to require
2784 any SELinux controls since they merely observe or modify
2785 the state of the current process. */
2786 return 0;
2787}
2788
2789static int selinux_task_wait(struct task_struct *p)
2790{
2791 u32 perm;
2792
2793 perm = signal_to_av(p->exit_signal);
2794
2795 return task_has_perm(p, current, perm);
2796}
2797
2798static void selinux_task_reparent_to_init(struct task_struct *p)
2799{
2800 struct task_security_struct *tsec;
2801
2802 secondary_ops->task_reparent_to_init(p);
2803
2804 tsec = p->security;
2805 tsec->osid = tsec->sid;
2806 tsec->sid = SECINITSID_KERNEL;
2807 return;
2808}
2809
2810static void selinux_task_to_inode(struct task_struct *p,
2811 struct inode *inode)
2812{
2813 struct task_security_struct *tsec = p->security;
2814 struct inode_security_struct *isec = inode->i_security;
2815
2816 isec->sid = tsec->sid;
2817 isec->initialized = 1;
2818 return;
2819}
2820
Linus Torvalds1da177e2005-04-16 15:20:36 -07002821/* Returns error only if unable to parse addresses */
2822static int selinux_parse_skb_ipv4(struct sk_buff *skb, struct avc_audit_data *ad)
2823{
2824 int offset, ihlen, ret = -EINVAL;
2825 struct iphdr _iph, *ih;
2826
2827 offset = skb->nh.raw - skb->data;
2828 ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph);
2829 if (ih == NULL)
2830 goto out;
2831
2832 ihlen = ih->ihl * 4;
2833 if (ihlen < sizeof(_iph))
2834 goto out;
2835
2836 ad->u.net.v4info.saddr = ih->saddr;
2837 ad->u.net.v4info.daddr = ih->daddr;
2838 ret = 0;
2839
2840 switch (ih->protocol) {
2841 case IPPROTO_TCP: {
2842 struct tcphdr _tcph, *th;
2843
2844 if (ntohs(ih->frag_off) & IP_OFFSET)
2845 break;
2846
2847 offset += ihlen;
2848 th = skb_header_pointer(skb, offset, sizeof(_tcph), &_tcph);
2849 if (th == NULL)
2850 break;
2851
2852 ad->u.net.sport = th->source;
2853 ad->u.net.dport = th->dest;
2854 break;
2855 }
2856
2857 case IPPROTO_UDP: {
2858 struct udphdr _udph, *uh;
2859
2860 if (ntohs(ih->frag_off) & IP_OFFSET)
2861 break;
2862
2863 offset += ihlen;
2864 uh = skb_header_pointer(skb, offset, sizeof(_udph), &_udph);
2865 if (uh == NULL)
2866 break;
2867
2868 ad->u.net.sport = uh->source;
2869 ad->u.net.dport = uh->dest;
2870 break;
2871 }
2872
2873 default:
2874 break;
2875 }
2876out:
2877 return ret;
2878}
2879
2880#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
2881
2882/* Returns error only if unable to parse addresses */
2883static int selinux_parse_skb_ipv6(struct sk_buff *skb, struct avc_audit_data *ad)
2884{
2885 u8 nexthdr;
2886 int ret = -EINVAL, offset;
2887 struct ipv6hdr _ipv6h, *ip6;
2888
2889 offset = skb->nh.raw - skb->data;
2890 ip6 = skb_header_pointer(skb, offset, sizeof(_ipv6h), &_ipv6h);
2891 if (ip6 == NULL)
2892 goto out;
2893
2894 ipv6_addr_copy(&ad->u.net.v6info.saddr, &ip6->saddr);
2895 ipv6_addr_copy(&ad->u.net.v6info.daddr, &ip6->daddr);
2896 ret = 0;
2897
2898 nexthdr = ip6->nexthdr;
2899 offset += sizeof(_ipv6h);
Herbert Xu0d3d0772005-04-24 20:16:19 -07002900 offset = ipv6_skip_exthdr(skb, offset, &nexthdr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002901 if (offset < 0)
2902 goto out;
2903
2904 switch (nexthdr) {
2905 case IPPROTO_TCP: {
2906 struct tcphdr _tcph, *th;
2907
2908 th = skb_header_pointer(skb, offset, sizeof(_tcph), &_tcph);
2909 if (th == NULL)
2910 break;
2911
2912 ad->u.net.sport = th->source;
2913 ad->u.net.dport = th->dest;
2914 break;
2915 }
2916
2917 case IPPROTO_UDP: {
2918 struct udphdr _udph, *uh;
2919
2920 uh = skb_header_pointer(skb, offset, sizeof(_udph), &_udph);
2921 if (uh == NULL)
2922 break;
2923
2924 ad->u.net.sport = uh->source;
2925 ad->u.net.dport = uh->dest;
2926 break;
2927 }
2928
2929 /* includes fragments */
2930 default:
2931 break;
2932 }
2933out:
2934 return ret;
2935}
2936
2937#endif /* IPV6 */
2938
2939static int selinux_parse_skb(struct sk_buff *skb, struct avc_audit_data *ad,
2940 char **addrp, int *len, int src)
2941{
2942 int ret = 0;
2943
2944 switch (ad->u.net.family) {
2945 case PF_INET:
2946 ret = selinux_parse_skb_ipv4(skb, ad);
2947 if (ret || !addrp)
2948 break;
2949 *len = 4;
2950 *addrp = (char *)(src ? &ad->u.net.v4info.saddr :
2951 &ad->u.net.v4info.daddr);
2952 break;
2953
2954#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
2955 case PF_INET6:
2956 ret = selinux_parse_skb_ipv6(skb, ad);
2957 if (ret || !addrp)
2958 break;
2959 *len = 16;
2960 *addrp = (char *)(src ? &ad->u.net.v6info.saddr :
2961 &ad->u.net.v6info.daddr);
2962 break;
2963#endif /* IPV6 */
2964 default:
2965 break;
2966 }
2967
2968 return ret;
2969}
2970
2971/* socket security operations */
2972static int socket_has_perm(struct task_struct *task, struct socket *sock,
2973 u32 perms)
2974{
2975 struct inode_security_struct *isec;
2976 struct task_security_struct *tsec;
2977 struct avc_audit_data ad;
2978 int err = 0;
2979
2980 tsec = task->security;
2981 isec = SOCK_INODE(sock)->i_security;
2982
2983 if (isec->sid == SECINITSID_KERNEL)
2984 goto out;
2985
2986 AVC_AUDIT_DATA_INIT(&ad,NET);
2987 ad.u.net.sk = sock->sk;
2988 err = avc_has_perm(tsec->sid, isec->sid, isec->sclass, perms, &ad);
2989
2990out:
2991 return err;
2992}
2993
2994static int selinux_socket_create(int family, int type,
2995 int protocol, int kern)
2996{
2997 int err = 0;
2998 struct task_security_struct *tsec;
Eric Paris42c3e032006-06-26 00:26:03 -07002999 u32 newsid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003000
3001 if (kern)
3002 goto out;
3003
3004 tsec = current->security;
Eric Paris42c3e032006-06-26 00:26:03 -07003005 newsid = tsec->sockcreate_sid ? : tsec->sid;
3006 err = avc_has_perm(tsec->sid, newsid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003007 socket_type_to_security_class(family, type,
3008 protocol), SOCKET__CREATE, NULL);
3009
3010out:
3011 return err;
3012}
3013
3014static void selinux_socket_post_create(struct socket *sock, int family,
3015 int type, int protocol, int kern)
3016{
3017 struct inode_security_struct *isec;
3018 struct task_security_struct *tsec;
Eric Paris42c3e032006-06-26 00:26:03 -07003019 u32 newsid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003020
3021 isec = SOCK_INODE(sock)->i_security;
3022
3023 tsec = current->security;
Eric Paris42c3e032006-06-26 00:26:03 -07003024 newsid = tsec->sockcreate_sid ? : tsec->sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003025 isec->sclass = socket_type_to_security_class(family, type, protocol);
Eric Paris42c3e032006-06-26 00:26:03 -07003026 isec->sid = kern ? SECINITSID_KERNEL : newsid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003027 isec->initialized = 1;
3028
3029 return;
3030}
3031
3032/* Range of port numbers used to automatically bind.
3033 Need to determine whether we should perform a name_bind
3034 permission check between the socket and the port number. */
3035#define ip_local_port_range_0 sysctl_local_port_range[0]
3036#define ip_local_port_range_1 sysctl_local_port_range[1]
3037
3038static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen)
3039{
3040 u16 family;
3041 int err;
3042
3043 err = socket_has_perm(current, sock, SOCKET__BIND);
3044 if (err)
3045 goto out;
3046
3047 /*
3048 * If PF_INET or PF_INET6, check name_bind permission for the port.
James Morris13402582005-09-30 14:24:34 -04003049 * Multiple address binding for SCTP is not supported yet: we just
3050 * check the first address now.
Linus Torvalds1da177e2005-04-16 15:20:36 -07003051 */
3052 family = sock->sk->sk_family;
3053 if (family == PF_INET || family == PF_INET6) {
3054 char *addrp;
3055 struct inode_security_struct *isec;
3056 struct task_security_struct *tsec;
3057 struct avc_audit_data ad;
3058 struct sockaddr_in *addr4 = NULL;
3059 struct sockaddr_in6 *addr6 = NULL;
3060 unsigned short snum;
3061 struct sock *sk = sock->sk;
3062 u32 sid, node_perm, addrlen;
3063
3064 tsec = current->security;
3065 isec = SOCK_INODE(sock)->i_security;
3066
3067 if (family == PF_INET) {
3068 addr4 = (struct sockaddr_in *)address;
3069 snum = ntohs(addr4->sin_port);
3070 addrlen = sizeof(addr4->sin_addr.s_addr);
3071 addrp = (char *)&addr4->sin_addr.s_addr;
3072 } else {
3073 addr6 = (struct sockaddr_in6 *)address;
3074 snum = ntohs(addr6->sin6_port);
3075 addrlen = sizeof(addr6->sin6_addr.s6_addr);
3076 addrp = (char *)&addr6->sin6_addr.s6_addr;
3077 }
3078
3079 if (snum&&(snum < max(PROT_SOCK,ip_local_port_range_0) ||
3080 snum > ip_local_port_range_1)) {
3081 err = security_port_sid(sk->sk_family, sk->sk_type,
3082 sk->sk_protocol, snum, &sid);
3083 if (err)
3084 goto out;
3085 AVC_AUDIT_DATA_INIT(&ad,NET);
3086 ad.u.net.sport = htons(snum);
3087 ad.u.net.family = family;
3088 err = avc_has_perm(isec->sid, sid,
3089 isec->sclass,
3090 SOCKET__NAME_BIND, &ad);
3091 if (err)
3092 goto out;
3093 }
3094
James Morris13402582005-09-30 14:24:34 -04003095 switch(isec->sclass) {
3096 case SECCLASS_TCP_SOCKET:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003097 node_perm = TCP_SOCKET__NODE_BIND;
3098 break;
3099
James Morris13402582005-09-30 14:24:34 -04003100 case SECCLASS_UDP_SOCKET:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003101 node_perm = UDP_SOCKET__NODE_BIND;
3102 break;
3103
3104 default:
3105 node_perm = RAWIP_SOCKET__NODE_BIND;
3106 break;
3107 }
3108
3109 err = security_node_sid(family, addrp, addrlen, &sid);
3110 if (err)
3111 goto out;
3112
3113 AVC_AUDIT_DATA_INIT(&ad,NET);
3114 ad.u.net.sport = htons(snum);
3115 ad.u.net.family = family;
3116
3117 if (family == PF_INET)
3118 ad.u.net.v4info.saddr = addr4->sin_addr.s_addr;
3119 else
3120 ipv6_addr_copy(&ad.u.net.v6info.saddr, &addr6->sin6_addr);
3121
3122 err = avc_has_perm(isec->sid, sid,
3123 isec->sclass, node_perm, &ad);
3124 if (err)
3125 goto out;
3126 }
3127out:
3128 return err;
3129}
3130
3131static int selinux_socket_connect(struct socket *sock, struct sockaddr *address, int addrlen)
3132{
3133 struct inode_security_struct *isec;
3134 int err;
3135
3136 err = socket_has_perm(current, sock, SOCKET__CONNECT);
3137 if (err)
3138 return err;
3139
3140 /*
3141 * If a TCP socket, check name_connect permission for the port.
3142 */
3143 isec = SOCK_INODE(sock)->i_security;
3144 if (isec->sclass == SECCLASS_TCP_SOCKET) {
3145 struct sock *sk = sock->sk;
3146 struct avc_audit_data ad;
3147 struct sockaddr_in *addr4 = NULL;
3148 struct sockaddr_in6 *addr6 = NULL;
3149 unsigned short snum;
3150 u32 sid;
3151
3152 if (sk->sk_family == PF_INET) {
3153 addr4 = (struct sockaddr_in *)address;
Stephen Smalley911656f2005-07-28 21:16:21 -07003154 if (addrlen < sizeof(struct sockaddr_in))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003155 return -EINVAL;
3156 snum = ntohs(addr4->sin_port);
3157 } else {
3158 addr6 = (struct sockaddr_in6 *)address;
Stephen Smalley911656f2005-07-28 21:16:21 -07003159 if (addrlen < SIN6_LEN_RFC2133)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003160 return -EINVAL;
3161 snum = ntohs(addr6->sin6_port);
3162 }
3163
3164 err = security_port_sid(sk->sk_family, sk->sk_type,
3165 sk->sk_protocol, snum, &sid);
3166 if (err)
3167 goto out;
3168
3169 AVC_AUDIT_DATA_INIT(&ad,NET);
3170 ad.u.net.dport = htons(snum);
3171 ad.u.net.family = sk->sk_family;
3172 err = avc_has_perm(isec->sid, sid, isec->sclass,
3173 TCP_SOCKET__NAME_CONNECT, &ad);
3174 if (err)
3175 goto out;
3176 }
3177
3178out:
3179 return err;
3180}
3181
3182static int selinux_socket_listen(struct socket *sock, int backlog)
3183{
3184 return socket_has_perm(current, sock, SOCKET__LISTEN);
3185}
3186
3187static int selinux_socket_accept(struct socket *sock, struct socket *newsock)
3188{
3189 int err;
3190 struct inode_security_struct *isec;
3191 struct inode_security_struct *newisec;
3192
3193 err = socket_has_perm(current, sock, SOCKET__ACCEPT);
3194 if (err)
3195 return err;
3196
3197 newisec = SOCK_INODE(newsock)->i_security;
3198
3199 isec = SOCK_INODE(sock)->i_security;
3200 newisec->sclass = isec->sclass;
3201 newisec->sid = isec->sid;
3202 newisec->initialized = 1;
3203
3204 return 0;
3205}
3206
3207static int selinux_socket_sendmsg(struct socket *sock, struct msghdr *msg,
3208 int size)
3209{
3210 return socket_has_perm(current, sock, SOCKET__WRITE);
3211}
3212
3213static int selinux_socket_recvmsg(struct socket *sock, struct msghdr *msg,
3214 int size, int flags)
3215{
3216 return socket_has_perm(current, sock, SOCKET__READ);
3217}
3218
3219static int selinux_socket_getsockname(struct socket *sock)
3220{
3221 return socket_has_perm(current, sock, SOCKET__GETATTR);
3222}
3223
3224static int selinux_socket_getpeername(struct socket *sock)
3225{
3226 return socket_has_perm(current, sock, SOCKET__GETATTR);
3227}
3228
3229static int selinux_socket_setsockopt(struct socket *sock,int level,int optname)
3230{
3231 return socket_has_perm(current, sock, SOCKET__SETOPT);
3232}
3233
3234static int selinux_socket_getsockopt(struct socket *sock, int level,
3235 int optname)
3236{
3237 return socket_has_perm(current, sock, SOCKET__GETOPT);
3238}
3239
3240static int selinux_socket_shutdown(struct socket *sock, int how)
3241{
3242 return socket_has_perm(current, sock, SOCKET__SHUTDOWN);
3243}
3244
3245static int selinux_socket_unix_stream_connect(struct socket *sock,
3246 struct socket *other,
3247 struct sock *newsk)
3248{
3249 struct sk_security_struct *ssec;
3250 struct inode_security_struct *isec;
3251 struct inode_security_struct *other_isec;
3252 struct avc_audit_data ad;
3253 int err;
3254
3255 err = secondary_ops->unix_stream_connect(sock, other, newsk);
3256 if (err)
3257 return err;
3258
3259 isec = SOCK_INODE(sock)->i_security;
3260 other_isec = SOCK_INODE(other)->i_security;
3261
3262 AVC_AUDIT_DATA_INIT(&ad,NET);
3263 ad.u.net.sk = other->sk;
3264
3265 err = avc_has_perm(isec->sid, other_isec->sid,
3266 isec->sclass,
3267 UNIX_STREAM_SOCKET__CONNECTTO, &ad);
3268 if (err)
3269 return err;
3270
3271 /* connecting socket */
3272 ssec = sock->sk->sk_security;
3273 ssec->peer_sid = other_isec->sid;
3274
3275 /* server child socket */
3276 ssec = newsk->sk_security;
3277 ssec->peer_sid = isec->sid;
3278
3279 return 0;
3280}
3281
3282static int selinux_socket_unix_may_send(struct socket *sock,
3283 struct socket *other)
3284{
3285 struct inode_security_struct *isec;
3286 struct inode_security_struct *other_isec;
3287 struct avc_audit_data ad;
3288 int err;
3289
3290 isec = SOCK_INODE(sock)->i_security;
3291 other_isec = SOCK_INODE(other)->i_security;
3292
3293 AVC_AUDIT_DATA_INIT(&ad,NET);
3294 ad.u.net.sk = other->sk;
3295
3296 err = avc_has_perm(isec->sid, other_isec->sid,
3297 isec->sclass, SOCKET__SENDTO, &ad);
3298 if (err)
3299 return err;
3300
3301 return 0;
3302}
3303
James Morris4e5ab4c2006-06-09 00:33:33 -07003304static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
3305 struct avc_audit_data *ad, u32 sock_sid, u16 sock_class,
3306 u16 family, char *addrp, int len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003307{
James Morris4e5ab4c2006-06-09 00:33:33 -07003308 int err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003309 u32 netif_perm, node_perm, node_sid, if_sid, recv_perm = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003310
James Morris4e5ab4c2006-06-09 00:33:33 -07003311 if (!skb->dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003312 goto out;
3313
James Morris4e5ab4c2006-06-09 00:33:33 -07003314 err = sel_netif_sids(skb->dev, &if_sid, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003315 if (err)
3316 goto out;
3317
3318 switch (sock_class) {
3319 case SECCLASS_UDP_SOCKET:
3320 netif_perm = NETIF__UDP_RECV;
3321 node_perm = NODE__UDP_RECV;
3322 recv_perm = UDP_SOCKET__RECV_MSG;
3323 break;
3324
3325 case SECCLASS_TCP_SOCKET:
3326 netif_perm = NETIF__TCP_RECV;
3327 node_perm = NODE__TCP_RECV;
3328 recv_perm = TCP_SOCKET__RECV_MSG;
3329 break;
3330
3331 default:
3332 netif_perm = NETIF__RAWIP_RECV;
3333 node_perm = NODE__RAWIP_RECV;
3334 break;
3335 }
3336
James Morris4e5ab4c2006-06-09 00:33:33 -07003337 err = avc_has_perm(sock_sid, if_sid, SECCLASS_NETIF, netif_perm, ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003338 if (err)
3339 goto out;
3340
Linus Torvalds1da177e2005-04-16 15:20:36 -07003341 err = security_node_sid(family, addrp, len, &node_sid);
3342 if (err)
3343 goto out;
3344
James Morris4e5ab4c2006-06-09 00:33:33 -07003345 err = avc_has_perm(sock_sid, node_sid, SECCLASS_NODE, node_perm, ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003346 if (err)
3347 goto out;
3348
3349 if (recv_perm) {
3350 u32 port_sid;
3351
Linus Torvalds1da177e2005-04-16 15:20:36 -07003352 err = security_port_sid(sk->sk_family, sk->sk_type,
James Morris4e5ab4c2006-06-09 00:33:33 -07003353 sk->sk_protocol, ntohs(ad->u.net.sport),
Linus Torvalds1da177e2005-04-16 15:20:36 -07003354 &port_sid);
3355 if (err)
3356 goto out;
3357
3358 err = avc_has_perm(sock_sid, port_sid,
James Morris4e5ab4c2006-06-09 00:33:33 -07003359 sock_class, recv_perm, ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003360 }
Trent Jaegerd28d1e02005-12-13 23:12:40 -08003361
James Morris4e5ab4c2006-06-09 00:33:33 -07003362out:
3363 return err;
3364}
Trent Jaegerd28d1e02005-12-13 23:12:40 -08003365
James Morris4e5ab4c2006-06-09 00:33:33 -07003366static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
3367{
3368 u16 family;
3369 u16 sock_class = 0;
3370 char *addrp;
3371 int len, err = 0;
3372 u32 sock_sid = 0;
3373 struct socket *sock;
3374 struct avc_audit_data ad;
3375
3376 family = sk->sk_family;
3377 if (family != PF_INET && family != PF_INET6)
3378 goto out;
3379
3380 /* Handle mapped IPv4 packets arriving via IPv6 sockets */
3381 if (family == PF_INET6 && skb->protocol == ntohs(ETH_P_IP))
3382 family = PF_INET;
3383
3384 read_lock_bh(&sk->sk_callback_lock);
3385 sock = sk->sk_socket;
3386 if (sock) {
3387 struct inode *inode;
3388 inode = SOCK_INODE(sock);
3389 if (inode) {
3390 struct inode_security_struct *isec;
3391 isec = inode->i_security;
3392 sock_sid = isec->sid;
3393 sock_class = isec->sclass;
3394 }
3395 }
3396 read_unlock_bh(&sk->sk_callback_lock);
3397 if (!sock_sid)
3398 goto out;
3399
3400 AVC_AUDIT_DATA_INIT(&ad, NET);
3401 ad.u.net.netif = skb->dev ? skb->dev->name : "[unknown]";
3402 ad.u.net.family = family;
3403
3404 err = selinux_parse_skb(skb, &ad, &addrp, &len, 1);
3405 if (err)
3406 goto out;
3407
3408 if (selinux_compat_net)
3409 err = selinux_sock_rcv_skb_compat(sk, skb, &ad, sock_sid,
3410 sock_class, family,
3411 addrp, len);
3412 else
3413 err = avc_has_perm(sock_sid, skb->secmark, SECCLASS_PACKET,
3414 PACKET__RECV, &ad);
3415 if (err)
3416 goto out;
3417
3418 err = selinux_xfrm_sock_rcv_skb(sock_sid, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003419out:
3420 return err;
3421}
3422
Catherine Zhang2c7946a2006-03-20 22:41:23 -08003423static int selinux_socket_getpeersec_stream(struct socket *sock, char __user *optval,
3424 int __user *optlen, unsigned len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003425{
3426 int err = 0;
3427 char *scontext;
3428 u32 scontext_len;
3429 struct sk_security_struct *ssec;
3430 struct inode_security_struct *isec;
Catherine Zhang2c7946a2006-03-20 22:41:23 -08003431 u32 peer_sid = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003432
3433 isec = SOCK_INODE(sock)->i_security;
Catherine Zhang2c7946a2006-03-20 22:41:23 -08003434
3435 /* if UNIX_STREAM check peer_sid, if TCP check dst for labelled sa */
3436 if (isec->sclass == SECCLASS_UNIX_STREAM_SOCKET) {
3437 ssec = sock->sk->sk_security;
3438 peer_sid = ssec->peer_sid;
3439 }
3440 else if (isec->sclass == SECCLASS_TCP_SOCKET) {
3441 peer_sid = selinux_socket_getpeer_stream(sock->sk);
3442
3443 if (peer_sid == SECSID_NULL) {
3444 err = -ENOPROTOOPT;
3445 goto out;
3446 }
3447 }
3448 else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003449 err = -ENOPROTOOPT;
3450 goto out;
3451 }
3452
Catherine Zhang2c7946a2006-03-20 22:41:23 -08003453 err = security_sid_to_context(peer_sid, &scontext, &scontext_len);
3454
Linus Torvalds1da177e2005-04-16 15:20:36 -07003455 if (err)
3456 goto out;
3457
3458 if (scontext_len > len) {
3459 err = -ERANGE;
3460 goto out_len;
3461 }
3462
3463 if (copy_to_user(optval, scontext, scontext_len))
3464 err = -EFAULT;
3465
3466out_len:
3467 if (put_user(scontext_len, optlen))
3468 err = -EFAULT;
3469
3470 kfree(scontext);
3471out:
3472 return err;
3473}
3474
Catherine Zhang2c7946a2006-03-20 22:41:23 -08003475static int selinux_socket_getpeersec_dgram(struct sk_buff *skb, char **secdata, u32 *seclen)
3476{
3477 int err = 0;
Catherine Zhang877ce7c2006-06-29 12:27:47 -07003478 u32 peer_sid;
3479
3480 if (skb->sk->sk_family == PF_UNIX)
3481 selinux_get_inode_sid(SOCK_INODE(skb->sk->sk_socket),
3482 &peer_sid);
3483 else
3484 peer_sid = selinux_socket_getpeer_dgram(skb);
Catherine Zhang2c7946a2006-03-20 22:41:23 -08003485
3486 if (peer_sid == SECSID_NULL)
3487 return -EINVAL;
3488
3489 err = security_sid_to_context(peer_sid, secdata, seclen);
3490 if (err)
3491 return err;
3492
3493 return 0;
3494}
3495
Al Viro7d877f32005-10-21 03:20:43 -04003496static int selinux_sk_alloc_security(struct sock *sk, int family, gfp_t priority)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003497{
3498 return sk_alloc_security(sk, family, priority);
3499}
3500
3501static void selinux_sk_free_security(struct sock *sk)
3502{
3503 sk_free_security(sk);
3504}
3505
Trent Jaegerd28d1e02005-12-13 23:12:40 -08003506static unsigned int selinux_sk_getsid_security(struct sock *sk, struct flowi *fl, u8 dir)
3507{
3508 struct inode_security_struct *isec;
3509 u32 sock_sid = SECINITSID_ANY_SOCKET;
3510
3511 if (!sk)
3512 return selinux_no_sk_sid(fl);
3513
3514 read_lock_bh(&sk->sk_callback_lock);
3515 isec = get_sock_isec(sk);
3516
3517 if (isec)
3518 sock_sid = isec->sid;
3519
3520 read_unlock_bh(&sk->sk_callback_lock);
3521 return sock_sid;
3522}
3523
Linus Torvalds1da177e2005-04-16 15:20:36 -07003524static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
3525{
3526 int err = 0;
3527 u32 perm;
3528 struct nlmsghdr *nlh;
3529 struct socket *sock = sk->sk_socket;
3530 struct inode_security_struct *isec = SOCK_INODE(sock)->i_security;
3531
3532 if (skb->len < NLMSG_SPACE(0)) {
3533 err = -EINVAL;
3534 goto out;
3535 }
3536 nlh = (struct nlmsghdr *)skb->data;
3537
3538 err = selinux_nlmsg_lookup(isec->sclass, nlh->nlmsg_type, &perm);
3539 if (err) {
3540 if (err == -EINVAL) {
David Woodhouse9ad9ad32005-06-22 15:04:33 +01003541 audit_log(current->audit_context, GFP_KERNEL, AUDIT_SELINUX_ERR,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003542 "SELinux: unrecognized netlink message"
3543 " type=%hu for sclass=%hu\n",
3544 nlh->nlmsg_type, isec->sclass);
3545 if (!selinux_enforcing)
3546 err = 0;
3547 }
3548
3549 /* Ignore */
3550 if (err == -ENOENT)
3551 err = 0;
3552 goto out;
3553 }
3554
3555 err = socket_has_perm(current, sock, perm);
3556out:
3557 return err;
3558}
3559
3560#ifdef CONFIG_NETFILTER
3561
James Morris4e5ab4c2006-06-09 00:33:33 -07003562static int selinux_ip_postroute_last_compat(struct sock *sk, struct net_device *dev,
3563 struct inode_security_struct *isec,
3564 struct avc_audit_data *ad,
3565 u16 family, char *addrp, int len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003566{
James Morris4e5ab4c2006-06-09 00:33:33 -07003567 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003568 u32 netif_perm, node_perm, node_sid, if_sid, send_perm = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003569
Linus Torvalds1da177e2005-04-16 15:20:36 -07003570 err = sel_netif_sids(dev, &if_sid, NULL);
3571 if (err)
3572 goto out;
3573
Linus Torvalds1da177e2005-04-16 15:20:36 -07003574 switch (isec->sclass) {
3575 case SECCLASS_UDP_SOCKET:
3576 netif_perm = NETIF__UDP_SEND;
3577 node_perm = NODE__UDP_SEND;
3578 send_perm = UDP_SOCKET__SEND_MSG;
3579 break;
3580
3581 case SECCLASS_TCP_SOCKET:
3582 netif_perm = NETIF__TCP_SEND;
3583 node_perm = NODE__TCP_SEND;
3584 send_perm = TCP_SOCKET__SEND_MSG;
3585 break;
3586
3587 default:
3588 netif_perm = NETIF__RAWIP_SEND;
3589 node_perm = NODE__RAWIP_SEND;
3590 break;
3591 }
3592
James Morris4e5ab4c2006-06-09 00:33:33 -07003593 err = avc_has_perm(isec->sid, if_sid, SECCLASS_NETIF, netif_perm, ad);
3594 if (err)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003595 goto out;
3596
James Morris4e5ab4c2006-06-09 00:33:33 -07003597 err = security_node_sid(family, addrp, len, &node_sid);
3598 if (err)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003599 goto out;
3600
James Morris4e5ab4c2006-06-09 00:33:33 -07003601 err = avc_has_perm(isec->sid, node_sid, SECCLASS_NODE, node_perm, ad);
3602 if (err)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003603 goto out;
3604
3605 if (send_perm) {
3606 u32 port_sid;
3607
Linus Torvalds1da177e2005-04-16 15:20:36 -07003608 err = security_port_sid(sk->sk_family,
3609 sk->sk_type,
3610 sk->sk_protocol,
James Morris4e5ab4c2006-06-09 00:33:33 -07003611 ntohs(ad->u.net.dport),
3612 &port_sid);
3613 if (err)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003614 goto out;
3615
3616 err = avc_has_perm(isec->sid, port_sid, isec->sclass,
James Morris4e5ab4c2006-06-09 00:33:33 -07003617 send_perm, ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003618 }
James Morris4e5ab4c2006-06-09 00:33:33 -07003619out:
3620 return err;
3621}
Linus Torvalds1da177e2005-04-16 15:20:36 -07003622
James Morris4e5ab4c2006-06-09 00:33:33 -07003623static unsigned int selinux_ip_postroute_last(unsigned int hooknum,
3624 struct sk_buff **pskb,
3625 const struct net_device *in,
3626 const struct net_device *out,
3627 int (*okfn)(struct sk_buff *),
3628 u16 family)
3629{
3630 char *addrp;
3631 int len, err = 0;
3632 struct sock *sk;
3633 struct socket *sock;
3634 struct inode *inode;
3635 struct sk_buff *skb = *pskb;
3636 struct inode_security_struct *isec;
3637 struct avc_audit_data ad;
3638 struct net_device *dev = (struct net_device *)out;
3639
3640 sk = skb->sk;
3641 if (!sk)
3642 goto out;
3643
3644 sock = sk->sk_socket;
3645 if (!sock)
3646 goto out;
3647
3648 inode = SOCK_INODE(sock);
3649 if (!inode)
3650 goto out;
3651
3652 isec = inode->i_security;
3653
3654 AVC_AUDIT_DATA_INIT(&ad, NET);
3655 ad.u.net.netif = dev->name;
3656 ad.u.net.family = family;
3657
3658 err = selinux_parse_skb(skb, &ad, &addrp, &len, 0);
3659 if (err)
3660 goto out;
3661
3662 if (selinux_compat_net)
3663 err = selinux_ip_postroute_last_compat(sk, dev, isec, &ad,
3664 family, addrp, len);
3665 else
3666 err = avc_has_perm(isec->sid, skb->secmark, SECCLASS_PACKET,
3667 PACKET__SEND, &ad);
3668
3669 if (err)
Trent Jaegerd28d1e02005-12-13 23:12:40 -08003670 goto out;
3671
3672 err = selinux_xfrm_postroute_last(isec->sid, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003673out:
James Morris4e5ab4c2006-06-09 00:33:33 -07003674 return err ? NF_DROP : NF_ACCEPT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003675}
3676
3677static unsigned int selinux_ipv4_postroute_last(unsigned int hooknum,
3678 struct sk_buff **pskb,
3679 const struct net_device *in,
3680 const struct net_device *out,
3681 int (*okfn)(struct sk_buff *))
3682{
3683 return selinux_ip_postroute_last(hooknum, pskb, in, out, okfn, PF_INET);
3684}
3685
3686#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
3687
3688static unsigned int selinux_ipv6_postroute_last(unsigned int hooknum,
3689 struct sk_buff **pskb,
3690 const struct net_device *in,
3691 const struct net_device *out,
3692 int (*okfn)(struct sk_buff *))
3693{
3694 return selinux_ip_postroute_last(hooknum, pskb, in, out, okfn, PF_INET6);
3695}
3696
3697#endif /* IPV6 */
3698
3699#endif /* CONFIG_NETFILTER */
3700
Linus Torvalds1da177e2005-04-16 15:20:36 -07003701static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb)
3702{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003703 int err;
3704
3705 err = secondary_ops->netlink_send(sk, skb);
3706 if (err)
3707 return err;
3708
Linus Torvalds1da177e2005-04-16 15:20:36 -07003709 if (policydb_loaded_version >= POLICYDB_VERSION_NLCLASS)
3710 err = selinux_nlmsg_perm(sk, skb);
3711
3712 return err;
3713}
3714
Darrel Goeddelc7bdb542006-06-27 13:26:11 -07003715static int selinux_netlink_recv(struct sk_buff *skb, int capability)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003716{
Darrel Goeddelc7bdb542006-06-27 13:26:11 -07003717 int err;
3718 struct avc_audit_data ad;
3719
3720 err = secondary_ops->netlink_recv(skb, capability);
3721 if (err)
3722 return err;
3723
3724 AVC_AUDIT_DATA_INIT(&ad, CAP);
3725 ad.u.cap = capability;
3726
3727 return avc_has_perm(NETLINK_CB(skb).sid, NETLINK_CB(skb).sid,
3728 SECCLASS_CAPABILITY, CAP_TO_MASK(capability), &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003729}
3730
3731static int ipc_alloc_security(struct task_struct *task,
3732 struct kern_ipc_perm *perm,
3733 u16 sclass)
3734{
3735 struct task_security_struct *tsec = task->security;
3736 struct ipc_security_struct *isec;
3737
James Morris89d155e2005-10-30 14:59:21 -08003738 isec = kzalloc(sizeof(struct ipc_security_struct), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003739 if (!isec)
3740 return -ENOMEM;
3741
Linus Torvalds1da177e2005-04-16 15:20:36 -07003742 isec->sclass = sclass;
3743 isec->ipc_perm = perm;
Stephen Smalley9ac49d22006-02-01 03:05:56 -08003744 isec->sid = tsec->sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003745 perm->security = isec;
3746
3747 return 0;
3748}
3749
3750static void ipc_free_security(struct kern_ipc_perm *perm)
3751{
3752 struct ipc_security_struct *isec = perm->security;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003753 perm->security = NULL;
3754 kfree(isec);
3755}
3756
3757static int msg_msg_alloc_security(struct msg_msg *msg)
3758{
3759 struct msg_security_struct *msec;
3760
James Morris89d155e2005-10-30 14:59:21 -08003761 msec = kzalloc(sizeof(struct msg_security_struct), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003762 if (!msec)
3763 return -ENOMEM;
3764
Linus Torvalds1da177e2005-04-16 15:20:36 -07003765 msec->msg = msg;
3766 msec->sid = SECINITSID_UNLABELED;
3767 msg->security = msec;
3768
3769 return 0;
3770}
3771
3772static void msg_msg_free_security(struct msg_msg *msg)
3773{
3774 struct msg_security_struct *msec = msg->security;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003775
3776 msg->security = NULL;
3777 kfree(msec);
3778}
3779
3780static int ipc_has_perm(struct kern_ipc_perm *ipc_perms,
Stephen Smalley6af963f2005-05-01 08:58:39 -07003781 u32 perms)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003782{
3783 struct task_security_struct *tsec;
3784 struct ipc_security_struct *isec;
3785 struct avc_audit_data ad;
3786
3787 tsec = current->security;
3788 isec = ipc_perms->security;
3789
3790 AVC_AUDIT_DATA_INIT(&ad, IPC);
3791 ad.u.ipc_id = ipc_perms->key;
3792
Stephen Smalley6af963f2005-05-01 08:58:39 -07003793 return avc_has_perm(tsec->sid, isec->sid, isec->sclass, perms, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003794}
3795
3796static int selinux_msg_msg_alloc_security(struct msg_msg *msg)
3797{
3798 return msg_msg_alloc_security(msg);
3799}
3800
3801static void selinux_msg_msg_free_security(struct msg_msg *msg)
3802{
3803 msg_msg_free_security(msg);
3804}
3805
3806/* message queue security operations */
3807static int selinux_msg_queue_alloc_security(struct msg_queue *msq)
3808{
3809 struct task_security_struct *tsec;
3810 struct ipc_security_struct *isec;
3811 struct avc_audit_data ad;
3812 int rc;
3813
3814 rc = ipc_alloc_security(current, &msq->q_perm, SECCLASS_MSGQ);
3815 if (rc)
3816 return rc;
3817
3818 tsec = current->security;
3819 isec = msq->q_perm.security;
3820
3821 AVC_AUDIT_DATA_INIT(&ad, IPC);
3822 ad.u.ipc_id = msq->q_perm.key;
3823
3824 rc = avc_has_perm(tsec->sid, isec->sid, SECCLASS_MSGQ,
3825 MSGQ__CREATE, &ad);
3826 if (rc) {
3827 ipc_free_security(&msq->q_perm);
3828 return rc;
3829 }
3830 return 0;
3831}
3832
3833static void selinux_msg_queue_free_security(struct msg_queue *msq)
3834{
3835 ipc_free_security(&msq->q_perm);
3836}
3837
3838static int selinux_msg_queue_associate(struct msg_queue *msq, int msqflg)
3839{
3840 struct task_security_struct *tsec;
3841 struct ipc_security_struct *isec;
3842 struct avc_audit_data ad;
3843
3844 tsec = current->security;
3845 isec = msq->q_perm.security;
3846
3847 AVC_AUDIT_DATA_INIT(&ad, IPC);
3848 ad.u.ipc_id = msq->q_perm.key;
3849
3850 return avc_has_perm(tsec->sid, isec->sid, SECCLASS_MSGQ,
3851 MSGQ__ASSOCIATE, &ad);
3852}
3853
3854static int selinux_msg_queue_msgctl(struct msg_queue *msq, int cmd)
3855{
3856 int err;
3857 int perms;
3858
3859 switch(cmd) {
3860 case IPC_INFO:
3861 case MSG_INFO:
3862 /* No specific object, just general system-wide information. */
3863 return task_has_system(current, SYSTEM__IPC_INFO);
3864 case IPC_STAT:
3865 case MSG_STAT:
3866 perms = MSGQ__GETATTR | MSGQ__ASSOCIATE;
3867 break;
3868 case IPC_SET:
3869 perms = MSGQ__SETATTR;
3870 break;
3871 case IPC_RMID:
3872 perms = MSGQ__DESTROY;
3873 break;
3874 default:
3875 return 0;
3876 }
3877
Stephen Smalley6af963f2005-05-01 08:58:39 -07003878 err = ipc_has_perm(&msq->q_perm, perms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003879 return err;
3880}
3881
3882static int selinux_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg, int msqflg)
3883{
3884 struct task_security_struct *tsec;
3885 struct ipc_security_struct *isec;
3886 struct msg_security_struct *msec;
3887 struct avc_audit_data ad;
3888 int rc;
3889
3890 tsec = current->security;
3891 isec = msq->q_perm.security;
3892 msec = msg->security;
3893
3894 /*
3895 * First time through, need to assign label to the message
3896 */
3897 if (msec->sid == SECINITSID_UNLABELED) {
3898 /*
3899 * Compute new sid based on current process and
3900 * message queue this message will be stored in
3901 */
3902 rc = security_transition_sid(tsec->sid,
3903 isec->sid,
3904 SECCLASS_MSG,
3905 &msec->sid);
3906 if (rc)
3907 return rc;
3908 }
3909
3910 AVC_AUDIT_DATA_INIT(&ad, IPC);
3911 ad.u.ipc_id = msq->q_perm.key;
3912
3913 /* Can this process write to the queue? */
3914 rc = avc_has_perm(tsec->sid, isec->sid, SECCLASS_MSGQ,
3915 MSGQ__WRITE, &ad);
3916 if (!rc)
3917 /* Can this process send the message */
3918 rc = avc_has_perm(tsec->sid, msec->sid,
3919 SECCLASS_MSG, MSG__SEND, &ad);
3920 if (!rc)
3921 /* Can the message be put in the queue? */
3922 rc = avc_has_perm(msec->sid, isec->sid,
3923 SECCLASS_MSGQ, MSGQ__ENQUEUE, &ad);
3924
3925 return rc;
3926}
3927
3928static int selinux_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg,
3929 struct task_struct *target,
3930 long type, int mode)
3931{
3932 struct task_security_struct *tsec;
3933 struct ipc_security_struct *isec;
3934 struct msg_security_struct *msec;
3935 struct avc_audit_data ad;
3936 int rc;
3937
3938 tsec = target->security;
3939 isec = msq->q_perm.security;
3940 msec = msg->security;
3941
3942 AVC_AUDIT_DATA_INIT(&ad, IPC);
3943 ad.u.ipc_id = msq->q_perm.key;
3944
3945 rc = avc_has_perm(tsec->sid, isec->sid,
3946 SECCLASS_MSGQ, MSGQ__READ, &ad);
3947 if (!rc)
3948 rc = avc_has_perm(tsec->sid, msec->sid,
3949 SECCLASS_MSG, MSG__RECEIVE, &ad);
3950 return rc;
3951}
3952
3953/* Shared Memory security operations */
3954static int selinux_shm_alloc_security(struct shmid_kernel *shp)
3955{
3956 struct task_security_struct *tsec;
3957 struct ipc_security_struct *isec;
3958 struct avc_audit_data ad;
3959 int rc;
3960
3961 rc = ipc_alloc_security(current, &shp->shm_perm, SECCLASS_SHM);
3962 if (rc)
3963 return rc;
3964
3965 tsec = current->security;
3966 isec = shp->shm_perm.security;
3967
3968 AVC_AUDIT_DATA_INIT(&ad, IPC);
3969 ad.u.ipc_id = shp->shm_perm.key;
3970
3971 rc = avc_has_perm(tsec->sid, isec->sid, SECCLASS_SHM,
3972 SHM__CREATE, &ad);
3973 if (rc) {
3974 ipc_free_security(&shp->shm_perm);
3975 return rc;
3976 }
3977 return 0;
3978}
3979
3980static void selinux_shm_free_security(struct shmid_kernel *shp)
3981{
3982 ipc_free_security(&shp->shm_perm);
3983}
3984
3985static int selinux_shm_associate(struct shmid_kernel *shp, int shmflg)
3986{
3987 struct task_security_struct *tsec;
3988 struct ipc_security_struct *isec;
3989 struct avc_audit_data ad;
3990
3991 tsec = current->security;
3992 isec = shp->shm_perm.security;
3993
3994 AVC_AUDIT_DATA_INIT(&ad, IPC);
3995 ad.u.ipc_id = shp->shm_perm.key;
3996
3997 return avc_has_perm(tsec->sid, isec->sid, SECCLASS_SHM,
3998 SHM__ASSOCIATE, &ad);
3999}
4000
4001/* Note, at this point, shp is locked down */
4002static int selinux_shm_shmctl(struct shmid_kernel *shp, int cmd)
4003{
4004 int perms;
4005 int err;
4006
4007 switch(cmd) {
4008 case IPC_INFO:
4009 case SHM_INFO:
4010 /* No specific object, just general system-wide information. */
4011 return task_has_system(current, SYSTEM__IPC_INFO);
4012 case IPC_STAT:
4013 case SHM_STAT:
4014 perms = SHM__GETATTR | SHM__ASSOCIATE;
4015 break;
4016 case IPC_SET:
4017 perms = SHM__SETATTR;
4018 break;
4019 case SHM_LOCK:
4020 case SHM_UNLOCK:
4021 perms = SHM__LOCK;
4022 break;
4023 case IPC_RMID:
4024 perms = SHM__DESTROY;
4025 break;
4026 default:
4027 return 0;
4028 }
4029
Stephen Smalley6af963f2005-05-01 08:58:39 -07004030 err = ipc_has_perm(&shp->shm_perm, perms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004031 return err;
4032}
4033
4034static int selinux_shm_shmat(struct shmid_kernel *shp,
4035 char __user *shmaddr, int shmflg)
4036{
4037 u32 perms;
4038 int rc;
4039
4040 rc = secondary_ops->shm_shmat(shp, shmaddr, shmflg);
4041 if (rc)
4042 return rc;
4043
4044 if (shmflg & SHM_RDONLY)
4045 perms = SHM__READ;
4046 else
4047 perms = SHM__READ | SHM__WRITE;
4048
Stephen Smalley6af963f2005-05-01 08:58:39 -07004049 return ipc_has_perm(&shp->shm_perm, perms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004050}
4051
4052/* Semaphore security operations */
4053static int selinux_sem_alloc_security(struct sem_array *sma)
4054{
4055 struct task_security_struct *tsec;
4056 struct ipc_security_struct *isec;
4057 struct avc_audit_data ad;
4058 int rc;
4059
4060 rc = ipc_alloc_security(current, &sma->sem_perm, SECCLASS_SEM);
4061 if (rc)
4062 return rc;
4063
4064 tsec = current->security;
4065 isec = sma->sem_perm.security;
4066
4067 AVC_AUDIT_DATA_INIT(&ad, IPC);
4068 ad.u.ipc_id = sma->sem_perm.key;
4069
4070 rc = avc_has_perm(tsec->sid, isec->sid, SECCLASS_SEM,
4071 SEM__CREATE, &ad);
4072 if (rc) {
4073 ipc_free_security(&sma->sem_perm);
4074 return rc;
4075 }
4076 return 0;
4077}
4078
4079static void selinux_sem_free_security(struct sem_array *sma)
4080{
4081 ipc_free_security(&sma->sem_perm);
4082}
4083
4084static int selinux_sem_associate(struct sem_array *sma, int semflg)
4085{
4086 struct task_security_struct *tsec;
4087 struct ipc_security_struct *isec;
4088 struct avc_audit_data ad;
4089
4090 tsec = current->security;
4091 isec = sma->sem_perm.security;
4092
4093 AVC_AUDIT_DATA_INIT(&ad, IPC);
4094 ad.u.ipc_id = sma->sem_perm.key;
4095
4096 return avc_has_perm(tsec->sid, isec->sid, SECCLASS_SEM,
4097 SEM__ASSOCIATE, &ad);
4098}
4099
4100/* Note, at this point, sma is locked down */
4101static int selinux_sem_semctl(struct sem_array *sma, int cmd)
4102{
4103 int err;
4104 u32 perms;
4105
4106 switch(cmd) {
4107 case IPC_INFO:
4108 case SEM_INFO:
4109 /* No specific object, just general system-wide information. */
4110 return task_has_system(current, SYSTEM__IPC_INFO);
4111 case GETPID:
4112 case GETNCNT:
4113 case GETZCNT:
4114 perms = SEM__GETATTR;
4115 break;
4116 case GETVAL:
4117 case GETALL:
4118 perms = SEM__READ;
4119 break;
4120 case SETVAL:
4121 case SETALL:
4122 perms = SEM__WRITE;
4123 break;
4124 case IPC_RMID:
4125 perms = SEM__DESTROY;
4126 break;
4127 case IPC_SET:
4128 perms = SEM__SETATTR;
4129 break;
4130 case IPC_STAT:
4131 case SEM_STAT:
4132 perms = SEM__GETATTR | SEM__ASSOCIATE;
4133 break;
4134 default:
4135 return 0;
4136 }
4137
Stephen Smalley6af963f2005-05-01 08:58:39 -07004138 err = ipc_has_perm(&sma->sem_perm, perms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004139 return err;
4140}
4141
4142static int selinux_sem_semop(struct sem_array *sma,
4143 struct sembuf *sops, unsigned nsops, int alter)
4144{
4145 u32 perms;
4146
4147 if (alter)
4148 perms = SEM__READ | SEM__WRITE;
4149 else
4150 perms = SEM__READ;
4151
Stephen Smalley6af963f2005-05-01 08:58:39 -07004152 return ipc_has_perm(&sma->sem_perm, perms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004153}
4154
4155static int selinux_ipc_permission(struct kern_ipc_perm *ipcp, short flag)
4156{
Linus Torvalds1da177e2005-04-16 15:20:36 -07004157 u32 av = 0;
4158
Linus Torvalds1da177e2005-04-16 15:20:36 -07004159 av = 0;
4160 if (flag & S_IRUGO)
4161 av |= IPC__UNIX_READ;
4162 if (flag & S_IWUGO)
4163 av |= IPC__UNIX_WRITE;
4164
4165 if (av == 0)
4166 return 0;
4167
Stephen Smalley6af963f2005-05-01 08:58:39 -07004168 return ipc_has_perm(ipcp, av);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004169}
4170
4171/* module stacking operations */
4172static int selinux_register_security (const char *name, struct security_operations *ops)
4173{
4174 if (secondary_ops != original_ops) {
4175 printk(KERN_INFO "%s: There is already a secondary security "
4176 "module registered.\n", __FUNCTION__);
4177 return -EINVAL;
4178 }
4179
4180 secondary_ops = ops;
4181
4182 printk(KERN_INFO "%s: Registering secondary module %s\n",
4183 __FUNCTION__,
4184 name);
4185
4186 return 0;
4187}
4188
4189static int selinux_unregister_security (const char *name, struct security_operations *ops)
4190{
4191 if (ops != secondary_ops) {
4192 printk (KERN_INFO "%s: trying to unregister a security module "
4193 "that is not registered.\n", __FUNCTION__);
4194 return -EINVAL;
4195 }
4196
4197 secondary_ops = original_ops;
4198
4199 return 0;
4200}
4201
4202static void selinux_d_instantiate (struct dentry *dentry, struct inode *inode)
4203{
4204 if (inode)
4205 inode_doinit_with_dentry(inode, dentry);
4206}
4207
4208static int selinux_getprocattr(struct task_struct *p,
4209 char *name, void *value, size_t size)
4210{
4211 struct task_security_struct *tsec;
Dustin Kirkland8c8570f2005-11-03 17:15:16 +00004212 u32 sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004213 int error;
4214
4215 if (current != p) {
4216 error = task_has_perm(current, p, PROCESS__GETATTR);
4217 if (error)
4218 return error;
4219 }
4220
Linus Torvalds1da177e2005-04-16 15:20:36 -07004221 tsec = p->security;
4222
4223 if (!strcmp(name, "current"))
4224 sid = tsec->sid;
4225 else if (!strcmp(name, "prev"))
4226 sid = tsec->osid;
4227 else if (!strcmp(name, "exec"))
4228 sid = tsec->exec_sid;
4229 else if (!strcmp(name, "fscreate"))
4230 sid = tsec->create_sid;
Michael LeMay4eb582c2006-06-26 00:24:57 -07004231 else if (!strcmp(name, "keycreate"))
4232 sid = tsec->keycreate_sid;
Eric Paris42c3e032006-06-26 00:26:03 -07004233 else if (!strcmp(name, "sockcreate"))
4234 sid = tsec->sockcreate_sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004235 else
4236 return -EINVAL;
4237
4238 if (!sid)
4239 return 0;
4240
Dustin Kirkland8c8570f2005-11-03 17:15:16 +00004241 return selinux_getsecurity(sid, value, size);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004242}
4243
4244static int selinux_setprocattr(struct task_struct *p,
4245 char *name, void *value, size_t size)
4246{
4247 struct task_security_struct *tsec;
4248 u32 sid = 0;
4249 int error;
4250 char *str = value;
4251
4252 if (current != p) {
4253 /* SELinux only allows a process to change its own
4254 security attributes. */
4255 return -EACCES;
4256 }
4257
4258 /*
4259 * Basic control over ability to set these attributes at all.
4260 * current == p, but we'll pass them separately in case the
4261 * above restriction is ever removed.
4262 */
4263 if (!strcmp(name, "exec"))
4264 error = task_has_perm(current, p, PROCESS__SETEXEC);
4265 else if (!strcmp(name, "fscreate"))
4266 error = task_has_perm(current, p, PROCESS__SETFSCREATE);
Michael LeMay4eb582c2006-06-26 00:24:57 -07004267 else if (!strcmp(name, "keycreate"))
4268 error = task_has_perm(current, p, PROCESS__SETKEYCREATE);
Eric Paris42c3e032006-06-26 00:26:03 -07004269 else if (!strcmp(name, "sockcreate"))
4270 error = task_has_perm(current, p, PROCESS__SETSOCKCREATE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004271 else if (!strcmp(name, "current"))
4272 error = task_has_perm(current, p, PROCESS__SETCURRENT);
4273 else
4274 error = -EINVAL;
4275 if (error)
4276 return error;
4277
4278 /* Obtain a SID for the context, if one was specified. */
4279 if (size && str[1] && str[1] != '\n') {
4280 if (str[size-1] == '\n') {
4281 str[size-1] = 0;
4282 size--;
4283 }
4284 error = security_context_to_sid(value, size, &sid);
4285 if (error)
4286 return error;
4287 }
4288
4289 /* Permission checking based on the specified context is
4290 performed during the actual operation (execve,
4291 open/mkdir/...), when we know the full context of the
4292 operation. See selinux_bprm_set_security for the execve
4293 checks and may_create for the file creation checks. The
4294 operation will then fail if the context is not permitted. */
4295 tsec = p->security;
4296 if (!strcmp(name, "exec"))
4297 tsec->exec_sid = sid;
4298 else if (!strcmp(name, "fscreate"))
4299 tsec->create_sid = sid;
Michael LeMay4eb582c2006-06-26 00:24:57 -07004300 else if (!strcmp(name, "keycreate")) {
4301 error = may_create_key(sid, p);
4302 if (error)
4303 return error;
4304 tsec->keycreate_sid = sid;
Eric Paris42c3e032006-06-26 00:26:03 -07004305 } else if (!strcmp(name, "sockcreate"))
4306 tsec->sockcreate_sid = sid;
4307 else if (!strcmp(name, "current")) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004308 struct av_decision avd;
4309
4310 if (sid == 0)
4311 return -EINVAL;
4312
4313 /* Only allow single threaded processes to change context */
4314 if (atomic_read(&p->mm->mm_users) != 1) {
4315 struct task_struct *g, *t;
4316 struct mm_struct *mm = p->mm;
4317 read_lock(&tasklist_lock);
4318 do_each_thread(g, t)
4319 if (t->mm == mm && t != p) {
4320 read_unlock(&tasklist_lock);
4321 return -EPERM;
4322 }
4323 while_each_thread(g, t);
4324 read_unlock(&tasklist_lock);
4325 }
4326
4327 /* Check permissions for the transition. */
4328 error = avc_has_perm(tsec->sid, sid, SECCLASS_PROCESS,
4329 PROCESS__DYNTRANSITION, NULL);
4330 if (error)
4331 return error;
4332
4333 /* Check for ptracing, and update the task SID if ok.
4334 Otherwise, leave SID unchanged and fail. */
4335 task_lock(p);
4336 if (p->ptrace & PT_PTRACED) {
4337 error = avc_has_perm_noaudit(tsec->ptrace_sid, sid,
4338 SECCLASS_PROCESS,
4339 PROCESS__PTRACE, &avd);
4340 if (!error)
4341 tsec->sid = sid;
4342 task_unlock(p);
4343 avc_audit(tsec->ptrace_sid, sid, SECCLASS_PROCESS,
4344 PROCESS__PTRACE, &avd, error, NULL);
4345 if (error)
4346 return error;
4347 } else {
4348 tsec->sid = sid;
4349 task_unlock(p);
4350 }
4351 }
4352 else
4353 return -EINVAL;
4354
4355 return size;
4356}
4357
Michael LeMayd7200242006-06-22 14:47:17 -07004358#ifdef CONFIG_KEYS
4359
David Howells7e047ef2006-06-26 00:24:50 -07004360static int selinux_key_alloc(struct key *k, struct task_struct *tsk,
4361 unsigned long flags)
Michael LeMayd7200242006-06-22 14:47:17 -07004362{
4363 struct task_security_struct *tsec = tsk->security;
4364 struct key_security_struct *ksec;
4365
4366 ksec = kzalloc(sizeof(struct key_security_struct), GFP_KERNEL);
4367 if (!ksec)
4368 return -ENOMEM;
4369
4370 ksec->obj = k;
Michael LeMay4eb582c2006-06-26 00:24:57 -07004371 if (tsec->keycreate_sid)
4372 ksec->sid = tsec->keycreate_sid;
4373 else
4374 ksec->sid = tsec->sid;
Michael LeMayd7200242006-06-22 14:47:17 -07004375 k->security = ksec;
4376
4377 return 0;
4378}
4379
4380static void selinux_key_free(struct key *k)
4381{
4382 struct key_security_struct *ksec = k->security;
4383
4384 k->security = NULL;
4385 kfree(ksec);
4386}
4387
4388static int selinux_key_permission(key_ref_t key_ref,
4389 struct task_struct *ctx,
4390 key_perm_t perm)
4391{
4392 struct key *key;
4393 struct task_security_struct *tsec;
4394 struct key_security_struct *ksec;
4395
4396 key = key_ref_to_ptr(key_ref);
4397
4398 tsec = ctx->security;
4399 ksec = key->security;
4400
4401 /* if no specific permissions are requested, we skip the
4402 permission check. No serious, additional covert channels
4403 appear to be created. */
4404 if (perm == 0)
4405 return 0;
4406
4407 return avc_has_perm(tsec->sid, ksec->sid,
4408 SECCLASS_KEY, perm, NULL);
4409}
4410
4411#endif
4412
Linus Torvalds1da177e2005-04-16 15:20:36 -07004413static struct security_operations selinux_ops = {
4414 .ptrace = selinux_ptrace,
4415 .capget = selinux_capget,
4416 .capset_check = selinux_capset_check,
4417 .capset_set = selinux_capset_set,
4418 .sysctl = selinux_sysctl,
4419 .capable = selinux_capable,
4420 .quotactl = selinux_quotactl,
4421 .quota_on = selinux_quota_on,
4422 .syslog = selinux_syslog,
4423 .vm_enough_memory = selinux_vm_enough_memory,
4424
4425 .netlink_send = selinux_netlink_send,
4426 .netlink_recv = selinux_netlink_recv,
4427
4428 .bprm_alloc_security = selinux_bprm_alloc_security,
4429 .bprm_free_security = selinux_bprm_free_security,
4430 .bprm_apply_creds = selinux_bprm_apply_creds,
4431 .bprm_post_apply_creds = selinux_bprm_post_apply_creds,
4432 .bprm_set_security = selinux_bprm_set_security,
4433 .bprm_check_security = selinux_bprm_check_security,
4434 .bprm_secureexec = selinux_bprm_secureexec,
4435
4436 .sb_alloc_security = selinux_sb_alloc_security,
4437 .sb_free_security = selinux_sb_free_security,
4438 .sb_copy_data = selinux_sb_copy_data,
4439 .sb_kern_mount = selinux_sb_kern_mount,
4440 .sb_statfs = selinux_sb_statfs,
4441 .sb_mount = selinux_mount,
4442 .sb_umount = selinux_umount,
4443
4444 .inode_alloc_security = selinux_inode_alloc_security,
4445 .inode_free_security = selinux_inode_free_security,
Stephen Smalley5e41ff92005-09-09 13:01:35 -07004446 .inode_init_security = selinux_inode_init_security,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004447 .inode_create = selinux_inode_create,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004448 .inode_link = selinux_inode_link,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004449 .inode_unlink = selinux_inode_unlink,
4450 .inode_symlink = selinux_inode_symlink,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004451 .inode_mkdir = selinux_inode_mkdir,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004452 .inode_rmdir = selinux_inode_rmdir,
4453 .inode_mknod = selinux_inode_mknod,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004454 .inode_rename = selinux_inode_rename,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004455 .inode_readlink = selinux_inode_readlink,
4456 .inode_follow_link = selinux_inode_follow_link,
4457 .inode_permission = selinux_inode_permission,
4458 .inode_setattr = selinux_inode_setattr,
4459 .inode_getattr = selinux_inode_getattr,
4460 .inode_setxattr = selinux_inode_setxattr,
4461 .inode_post_setxattr = selinux_inode_post_setxattr,
4462 .inode_getxattr = selinux_inode_getxattr,
4463 .inode_listxattr = selinux_inode_listxattr,
4464 .inode_removexattr = selinux_inode_removexattr,
Dustin Kirkland8c8570f2005-11-03 17:15:16 +00004465 .inode_xattr_getsuffix = selinux_inode_xattr_getsuffix,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004466 .inode_getsecurity = selinux_inode_getsecurity,
4467 .inode_setsecurity = selinux_inode_setsecurity,
4468 .inode_listsecurity = selinux_inode_listsecurity,
4469
4470 .file_permission = selinux_file_permission,
4471 .file_alloc_security = selinux_file_alloc_security,
4472 .file_free_security = selinux_file_free_security,
4473 .file_ioctl = selinux_file_ioctl,
4474 .file_mmap = selinux_file_mmap,
4475 .file_mprotect = selinux_file_mprotect,
4476 .file_lock = selinux_file_lock,
4477 .file_fcntl = selinux_file_fcntl,
4478 .file_set_fowner = selinux_file_set_fowner,
4479 .file_send_sigiotask = selinux_file_send_sigiotask,
4480 .file_receive = selinux_file_receive,
4481
4482 .task_create = selinux_task_create,
4483 .task_alloc_security = selinux_task_alloc_security,
4484 .task_free_security = selinux_task_free_security,
4485 .task_setuid = selinux_task_setuid,
4486 .task_post_setuid = selinux_task_post_setuid,
4487 .task_setgid = selinux_task_setgid,
4488 .task_setpgid = selinux_task_setpgid,
4489 .task_getpgid = selinux_task_getpgid,
4490 .task_getsid = selinux_task_getsid,
David Quigleyf9008e42006-06-30 01:55:46 -07004491 .task_getsecid = selinux_task_getsecid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004492 .task_setgroups = selinux_task_setgroups,
4493 .task_setnice = selinux_task_setnice,
James Morris03e68062006-06-23 02:03:58 -07004494 .task_setioprio = selinux_task_setioprio,
David Quigleya1836a42006-06-30 01:55:49 -07004495 .task_getioprio = selinux_task_getioprio,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004496 .task_setrlimit = selinux_task_setrlimit,
4497 .task_setscheduler = selinux_task_setscheduler,
4498 .task_getscheduler = selinux_task_getscheduler,
David Quigley35601542006-06-23 02:04:01 -07004499 .task_movememory = selinux_task_movememory,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004500 .task_kill = selinux_task_kill,
4501 .task_wait = selinux_task_wait,
4502 .task_prctl = selinux_task_prctl,
4503 .task_reparent_to_init = selinux_task_reparent_to_init,
4504 .task_to_inode = selinux_task_to_inode,
4505
4506 .ipc_permission = selinux_ipc_permission,
4507
4508 .msg_msg_alloc_security = selinux_msg_msg_alloc_security,
4509 .msg_msg_free_security = selinux_msg_msg_free_security,
4510
4511 .msg_queue_alloc_security = selinux_msg_queue_alloc_security,
4512 .msg_queue_free_security = selinux_msg_queue_free_security,
4513 .msg_queue_associate = selinux_msg_queue_associate,
4514 .msg_queue_msgctl = selinux_msg_queue_msgctl,
4515 .msg_queue_msgsnd = selinux_msg_queue_msgsnd,
4516 .msg_queue_msgrcv = selinux_msg_queue_msgrcv,
4517
4518 .shm_alloc_security = selinux_shm_alloc_security,
4519 .shm_free_security = selinux_shm_free_security,
4520 .shm_associate = selinux_shm_associate,
4521 .shm_shmctl = selinux_shm_shmctl,
4522 .shm_shmat = selinux_shm_shmat,
4523
4524 .sem_alloc_security = selinux_sem_alloc_security,
4525 .sem_free_security = selinux_sem_free_security,
4526 .sem_associate = selinux_sem_associate,
4527 .sem_semctl = selinux_sem_semctl,
4528 .sem_semop = selinux_sem_semop,
4529
4530 .register_security = selinux_register_security,
4531 .unregister_security = selinux_unregister_security,
4532
4533 .d_instantiate = selinux_d_instantiate,
4534
4535 .getprocattr = selinux_getprocattr,
4536 .setprocattr = selinux_setprocattr,
4537
Linus Torvalds1da177e2005-04-16 15:20:36 -07004538 .unix_stream_connect = selinux_socket_unix_stream_connect,
4539 .unix_may_send = selinux_socket_unix_may_send,
4540
4541 .socket_create = selinux_socket_create,
4542 .socket_post_create = selinux_socket_post_create,
4543 .socket_bind = selinux_socket_bind,
4544 .socket_connect = selinux_socket_connect,
4545 .socket_listen = selinux_socket_listen,
4546 .socket_accept = selinux_socket_accept,
4547 .socket_sendmsg = selinux_socket_sendmsg,
4548 .socket_recvmsg = selinux_socket_recvmsg,
4549 .socket_getsockname = selinux_socket_getsockname,
4550 .socket_getpeername = selinux_socket_getpeername,
4551 .socket_getsockopt = selinux_socket_getsockopt,
4552 .socket_setsockopt = selinux_socket_setsockopt,
4553 .socket_shutdown = selinux_socket_shutdown,
4554 .socket_sock_rcv_skb = selinux_socket_sock_rcv_skb,
Catherine Zhang2c7946a2006-03-20 22:41:23 -08004555 .socket_getpeersec_stream = selinux_socket_getpeersec_stream,
4556 .socket_getpeersec_dgram = selinux_socket_getpeersec_dgram,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004557 .sk_alloc_security = selinux_sk_alloc_security,
4558 .sk_free_security = selinux_sk_free_security,
Trent Jaegerd28d1e02005-12-13 23:12:40 -08004559 .sk_getsid = selinux_sk_getsid_security,
Trent Jaegerd28d1e02005-12-13 23:12:40 -08004560
4561#ifdef CONFIG_SECURITY_NETWORK_XFRM
4562 .xfrm_policy_alloc_security = selinux_xfrm_policy_alloc,
4563 .xfrm_policy_clone_security = selinux_xfrm_policy_clone,
4564 .xfrm_policy_free_security = selinux_xfrm_policy_free,
Catherine Zhangc8c05a82006-06-08 23:39:49 -07004565 .xfrm_policy_delete_security = selinux_xfrm_policy_delete,
Trent Jaegerd28d1e02005-12-13 23:12:40 -08004566 .xfrm_state_alloc_security = selinux_xfrm_state_alloc,
4567 .xfrm_state_free_security = selinux_xfrm_state_free,
Catherine Zhangc8c05a82006-06-08 23:39:49 -07004568 .xfrm_state_delete_security = selinux_xfrm_state_delete,
Trent Jaegerd28d1e02005-12-13 23:12:40 -08004569 .xfrm_policy_lookup = selinux_xfrm_policy_lookup,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004570#endif
Michael LeMayd7200242006-06-22 14:47:17 -07004571
4572#ifdef CONFIG_KEYS
4573 .key_alloc = selinux_key_alloc,
4574 .key_free = selinux_key_free,
4575 .key_permission = selinux_key_permission,
4576#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07004577};
4578
4579static __init int selinux_init(void)
4580{
4581 struct task_security_struct *tsec;
4582
4583 if (!selinux_enabled) {
4584 printk(KERN_INFO "SELinux: Disabled at boot.\n");
4585 return 0;
4586 }
4587
4588 printk(KERN_INFO "SELinux: Initializing.\n");
4589
4590 /* Set the security state for the initial task. */
4591 if (task_alloc_security(current))
4592 panic("SELinux: Failed to initialize initial task.\n");
4593 tsec = current->security;
4594 tsec->osid = tsec->sid = SECINITSID_KERNEL;
4595
James Morris7cae7e22006-03-22 00:09:22 -08004596 sel_inode_cache = kmem_cache_create("selinux_inode_security",
4597 sizeof(struct inode_security_struct),
4598 0, SLAB_PANIC, NULL, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004599 avc_init();
4600
4601 original_ops = secondary_ops = security_ops;
4602 if (!secondary_ops)
4603 panic ("SELinux: No initial security operations\n");
4604 if (register_security (&selinux_ops))
4605 panic("SELinux: Unable to register with kernel.\n");
4606
4607 if (selinux_enforcing) {
4608 printk(KERN_INFO "SELinux: Starting in enforcing mode\n");
4609 } else {
4610 printk(KERN_INFO "SELinux: Starting in permissive mode\n");
4611 }
Michael LeMayd7200242006-06-22 14:47:17 -07004612
4613#ifdef CONFIG_KEYS
4614 /* Add security information to initial keyrings */
Michael LeMay4eb582c2006-06-26 00:24:57 -07004615 selinux_key_alloc(&root_user_keyring, current,
4616 KEY_ALLOC_NOT_IN_QUOTA);
4617 selinux_key_alloc(&root_session_keyring, current,
4618 KEY_ALLOC_NOT_IN_QUOTA);
Michael LeMayd7200242006-06-22 14:47:17 -07004619#endif
4620
Linus Torvalds1da177e2005-04-16 15:20:36 -07004621 return 0;
4622}
4623
4624void selinux_complete_init(void)
4625{
4626 printk(KERN_INFO "SELinux: Completing initialization.\n");
4627
4628 /* Set up any superblocks initialized prior to the policy load. */
4629 printk(KERN_INFO "SELinux: Setting up existing superblocks.\n");
Stephen Smalleyba0c19e2006-06-04 02:51:30 -07004630 spin_lock(&sb_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004631 spin_lock(&sb_security_lock);
4632next_sb:
4633 if (!list_empty(&superblock_security_head)) {
4634 struct superblock_security_struct *sbsec =
4635 list_entry(superblock_security_head.next,
4636 struct superblock_security_struct,
4637 list);
4638 struct super_block *sb = sbsec->sb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004639 sb->s_count++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004640 spin_unlock(&sb_security_lock);
Stephen Smalleyba0c19e2006-06-04 02:51:30 -07004641 spin_unlock(&sb_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004642 down_read(&sb->s_umount);
4643 if (sb->s_root)
4644 superblock_doinit(sb, NULL);
4645 drop_super(sb);
Stephen Smalleyba0c19e2006-06-04 02:51:30 -07004646 spin_lock(&sb_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004647 spin_lock(&sb_security_lock);
4648 list_del_init(&sbsec->list);
4649 goto next_sb;
4650 }
4651 spin_unlock(&sb_security_lock);
Stephen Smalleyba0c19e2006-06-04 02:51:30 -07004652 spin_unlock(&sb_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004653}
4654
4655/* SELinux requires early initialization in order to label
4656 all processes and objects when they are created. */
4657security_initcall(selinux_init);
4658
Stephen Smalleyc2b507f2006-02-04 23:27:50 -08004659#if defined(CONFIG_NETFILTER)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004660
4661static struct nf_hook_ops selinux_ipv4_op = {
4662 .hook = selinux_ipv4_postroute_last,
4663 .owner = THIS_MODULE,
4664 .pf = PF_INET,
4665 .hooknum = NF_IP_POST_ROUTING,
4666 .priority = NF_IP_PRI_SELINUX_LAST,
4667};
4668
4669#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
4670
4671static struct nf_hook_ops selinux_ipv6_op = {
4672 .hook = selinux_ipv6_postroute_last,
4673 .owner = THIS_MODULE,
4674 .pf = PF_INET6,
4675 .hooknum = NF_IP6_POST_ROUTING,
4676 .priority = NF_IP6_PRI_SELINUX_LAST,
4677};
4678
4679#endif /* IPV6 */
4680
4681static int __init selinux_nf_ip_init(void)
4682{
4683 int err = 0;
4684
4685 if (!selinux_enabled)
4686 goto out;
4687
4688 printk(KERN_INFO "SELinux: Registering netfilter hooks\n");
4689
4690 err = nf_register_hook(&selinux_ipv4_op);
4691 if (err)
4692 panic("SELinux: nf_register_hook for IPv4: error %d\n", err);
4693
4694#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
4695
4696 err = nf_register_hook(&selinux_ipv6_op);
4697 if (err)
4698 panic("SELinux: nf_register_hook for IPv6: error %d\n", err);
4699
4700#endif /* IPV6 */
Trent Jaegerd28d1e02005-12-13 23:12:40 -08004701
Linus Torvalds1da177e2005-04-16 15:20:36 -07004702out:
4703 return err;
4704}
4705
4706__initcall(selinux_nf_ip_init);
4707
4708#ifdef CONFIG_SECURITY_SELINUX_DISABLE
4709static void selinux_nf_ip_exit(void)
4710{
4711 printk(KERN_INFO "SELinux: Unregistering netfilter hooks\n");
4712
4713 nf_unregister_hook(&selinux_ipv4_op);
4714#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
4715 nf_unregister_hook(&selinux_ipv6_op);
4716#endif /* IPV6 */
4717}
4718#endif
4719
Stephen Smalleyc2b507f2006-02-04 23:27:50 -08004720#else /* CONFIG_NETFILTER */
Linus Torvalds1da177e2005-04-16 15:20:36 -07004721
4722#ifdef CONFIG_SECURITY_SELINUX_DISABLE
4723#define selinux_nf_ip_exit()
4724#endif
4725
Stephen Smalleyc2b507f2006-02-04 23:27:50 -08004726#endif /* CONFIG_NETFILTER */
Linus Torvalds1da177e2005-04-16 15:20:36 -07004727
4728#ifdef CONFIG_SECURITY_SELINUX_DISABLE
4729int selinux_disable(void)
4730{
4731 extern void exit_sel_fs(void);
4732 static int selinux_disabled = 0;
4733
4734 if (ss_initialized) {
4735 /* Not permitted after initial policy load. */
4736 return -EINVAL;
4737 }
4738
4739 if (selinux_disabled) {
4740 /* Only do this once. */
4741 return -EINVAL;
4742 }
4743
4744 printk(KERN_INFO "SELinux: Disabled at runtime.\n");
4745
4746 selinux_disabled = 1;
Stephen Smalley30d55282006-05-03 10:52:36 -04004747 selinux_enabled = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004748
4749 /* Reset security_ops to the secondary module, dummy or capability. */
4750 security_ops = secondary_ops;
4751
4752 /* Unregister netfilter hooks. */
4753 selinux_nf_ip_exit();
4754
4755 /* Unregister selinuxfs. */
4756 exit_sel_fs();
4757
4758 return 0;
4759}
4760#endif
4761
4762