aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorSage Weil <sage@inktank.com>2013-08-15 14:11:45 -0400
committerSage Weil <sage@inktank.com>2013-08-15 14:11:45 -0400
commitee3e542fec6e69bc9fb668698889a37d93950ddf (patch)
treee74ee766a4764769ef1d3d45d266b4dea64101d3 /security
parentfe2a801b50c0bb8039d627e5ae1fec249d10ff39 (diff)
parentf1d6e17f540af37bb1891480143669ba7636c4cf (diff)
Merge remote-tracking branch 'linus/master' into testing
Diffstat (limited to 'security')
-rw-r--r--security/apparmor/audit.c2
-rw-r--r--security/apparmor/context.c44
-rw-r--r--security/apparmor/domain.c26
-rw-r--r--security/apparmor/include/apparmor.h12
-rw-r--r--security/apparmor/include/context.h61
-rw-r--r--security/apparmor/include/file.h14
-rw-r--r--security/apparmor/include/match.h21
-rw-r--r--security/apparmor/include/policy.h16
-rw-r--r--security/apparmor/include/procattr.h1
-rw-r--r--security/apparmor/include/sid.h4
-rw-r--r--security/apparmor/ipc.c13
-rw-r--r--security/apparmor/lib.c44
-rw-r--r--security/apparmor/lsm.c69
-rw-r--r--security/apparmor/match.c23
-rw-r--r--security/apparmor/path.c2
-rw-r--r--security/apparmor/policy.c181
-rw-r--r--security/apparmor/policy_unpack.c4
-rw-r--r--security/apparmor/procattr.c6
-rw-r--r--security/apparmor/resource.c15
-rw-r--r--security/capability.c21
-rw-r--r--security/device_cgroup.c56
-rw-r--r--security/integrity/Kconfig15
-rw-r--r--security/integrity/Makefile1
-rw-r--r--security/integrity/evm/evm_main.c15
-rw-r--r--security/integrity/ima/Kconfig12
-rw-r--r--security/integrity/ima/Makefile1
-rw-r--r--security/integrity/ima/ima.h14
-rw-r--r--security/integrity/ima/ima_main.c2
-rw-r--r--security/integrity/integrity.h14
-rw-r--r--security/integrity/integrity_audit.c (renamed from security/integrity/ima/ima_audit.c)12
-rw-r--r--security/security.c24
-rw-r--r--security/selinux/hooks.c116
-rw-r--r--security/selinux/include/security.h2
-rw-r--r--security/selinux/netif.c2
-rw-r--r--security/selinux/ss/policydb.c5
-rw-r--r--security/smack/smack.h110
-rw-r--r--security/smack/smack_access.c43
-rw-r--r--security/smack/smack_lsm.c693
-rw-r--r--security/smack/smackfs.c53
39 files changed, 1124 insertions, 645 deletions
diff --git a/security/apparmor/audit.c b/security/apparmor/audit.c
index 3ae28db5a64f..031d2d9dd695 100644
--- a/security/apparmor/audit.c
+++ b/security/apparmor/audit.c
@@ -88,7 +88,7 @@ static const char *const aa_audit_type[] = {
88 "HINT", 88 "HINT",
89 "STATUS", 89 "STATUS",
90 "ERROR", 90 "ERROR",
91 "KILLED" 91 "KILLED",
92 "AUTO" 92 "AUTO"
93}; 93};
94 94
diff --git a/security/apparmor/context.c b/security/apparmor/context.c
index 8a9b5027c813..d5af1d15f26d 100644
--- a/security/apparmor/context.c
+++ b/security/apparmor/context.c
@@ -69,6 +69,23 @@ void aa_dup_task_context(struct aa_task_cxt *new, const struct aa_task_cxt *old)
69} 69}
70 70
71/** 71/**
72 * aa_get_task_profile - Get another task's profile
73 * @task: task to query (NOT NULL)
74 *
75 * Returns: counted reference to @task's profile
76 */
77struct aa_profile *aa_get_task_profile(struct task_struct *task)
78{
79 struct aa_profile *p;
80
81 rcu_read_lock();
82 p = aa_get_profile(__aa_task_profile(task));
83 rcu_read_unlock();
84
85 return p;
86}
87
88/**
72 * aa_replace_current_profile - replace the current tasks profiles 89 * aa_replace_current_profile - replace the current tasks profiles
73 * @profile: new profile (NOT NULL) 90 * @profile: new profile (NOT NULL)
74 * 91 *
@@ -76,7 +93,7 @@ void aa_dup_task_context(struct aa_task_cxt *new, const struct aa_task_cxt *old)
76 */ 93 */
77int aa_replace_current_profile(struct aa_profile *profile) 94int aa_replace_current_profile(struct aa_profile *profile)
78{ 95{
79 struct aa_task_cxt *cxt = current_cred()->security; 96 struct aa_task_cxt *cxt = current_cxt();
80 struct cred *new; 97 struct cred *new;
81 BUG_ON(!profile); 98 BUG_ON(!profile);
82 99
@@ -87,17 +104,13 @@ int aa_replace_current_profile(struct aa_profile *profile)
87 if (!new) 104 if (!new)
88 return -ENOMEM; 105 return -ENOMEM;
89 106
90 cxt = new->security; 107 cxt = cred_cxt(new);
91 if (unconfined(profile) || (cxt->profile->ns != profile->ns)) { 108 if (unconfined(profile) || (cxt->profile->ns != profile->ns))
92 /* if switching to unconfined or a different profile namespace 109 /* if switching to unconfined or a different profile namespace
93 * clear out context state 110 * clear out context state
94 */ 111 */
95 aa_put_profile(cxt->previous); 112 aa_clear_task_cxt_trans(cxt);
96 aa_put_profile(cxt->onexec); 113
97 cxt->previous = NULL;
98 cxt->onexec = NULL;
99 cxt->token = 0;
100 }
101 /* be careful switching cxt->profile, when racing replacement it 114 /* be careful switching cxt->profile, when racing replacement it
102 * is possible that cxt->profile->replacedby is the reference keeping 115 * is possible that cxt->profile->replacedby is the reference keeping
103 * @profile valid, so make sure to get its reference before dropping 116 * @profile valid, so make sure to get its reference before dropping
@@ -123,7 +136,7 @@ int aa_set_current_onexec(struct aa_profile *profile)
123 if (!new) 136 if (!new)
124 return -ENOMEM; 137 return -ENOMEM;
125 138
126 cxt = new->security; 139 cxt = cred_cxt(new);
127 aa_get_profile(profile); 140 aa_get_profile(profile);
128 aa_put_profile(cxt->onexec); 141 aa_put_profile(cxt->onexec);
129 cxt->onexec = profile; 142 cxt->onexec = profile;
@@ -150,7 +163,7 @@ int aa_set_current_hat(struct aa_profile *profile, u64 token)
150 return -ENOMEM; 163 return -ENOMEM;
151 BUG_ON(!profile); 164 BUG_ON(!profile);
152 165
153 cxt = new->security; 166 cxt = cred_cxt(new);
154 if (!cxt->previous) { 167 if (!cxt->previous) {
155 /* transfer refcount */ 168 /* transfer refcount */
156 cxt->previous = cxt->profile; 169 cxt->previous = cxt->profile;
@@ -187,7 +200,7 @@ int aa_restore_previous_profile(u64 token)
187 if (!new) 200 if (!new)
188 return -ENOMEM; 201 return -ENOMEM;
189 202
190 cxt = new->security; 203 cxt = cred_cxt(new);
191 if (cxt->token != token) { 204 if (cxt->token != token) {
192 abort_creds(new); 205 abort_creds(new);
193 return -EACCES; 206 return -EACCES;
@@ -205,11 +218,10 @@ int aa_restore_previous_profile(u64 token)
205 aa_get_profile(cxt->profile); 218 aa_get_profile(cxt->profile);
206 aa_put_profile(cxt->previous); 219 aa_put_profile(cxt->previous);
207 } 220 }
208 /* clear exec && prev information when restoring to previous context */ 221 /* ref has been transfered so avoid putting ref in clear_task_cxt */
209 cxt->previous = NULL; 222 cxt->previous = NULL;
210 cxt->token = 0; 223 /* clear exec && prev information when restoring to previous context */
211 aa_put_profile(cxt->onexec); 224 aa_clear_task_cxt_trans(cxt);
212 cxt->onexec = NULL;
213 225
214 commit_creds(new); 226 commit_creds(new);
215 return 0; 227 return 0;
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
index 859abdaac1ea..01b7bd669a88 100644
--- a/security/apparmor/domain.c
+++ b/security/apparmor/domain.c
@@ -62,17 +62,14 @@ static int may_change_ptraced_domain(struct task_struct *task,
62 struct aa_profile *to_profile) 62 struct aa_profile *to_profile)
63{ 63{
64 struct task_struct *tracer; 64 struct task_struct *tracer;
65 const struct cred *cred = NULL;
66 struct aa_profile *tracerp = NULL; 65 struct aa_profile *tracerp = NULL;
67 int error = 0; 66 int error = 0;
68 67
69 rcu_read_lock(); 68 rcu_read_lock();
70 tracer = ptrace_parent(task); 69 tracer = ptrace_parent(task);
71 if (tracer) { 70 if (tracer)
72 /* released below */ 71 /* released below */
73 cred = get_task_cred(tracer); 72 tracerp = aa_get_task_profile(tracer);
74 tracerp = aa_cred_profile(cred);
75 }
76 73
77 /* not ptraced */ 74 /* not ptraced */
78 if (!tracer || unconfined(tracerp)) 75 if (!tracer || unconfined(tracerp))
@@ -82,8 +79,7 @@ static int may_change_ptraced_domain(struct task_struct *task,
82 79
83out: 80out:
84 rcu_read_unlock(); 81 rcu_read_unlock();
85 if (cred) 82 aa_put_profile(tracerp);
86 put_cred(cred);
87 83
88 return error; 84 return error;
89} 85}
@@ -360,7 +356,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
360 if (bprm->cred_prepared) 356 if (bprm->cred_prepared)
361 return 0; 357 return 0;
362 358
363 cxt = bprm->cred->security; 359 cxt = cred_cxt(bprm->cred);
364 BUG_ON(!cxt); 360 BUG_ON(!cxt);
365 361
366 profile = aa_get_profile(aa_newest_version(cxt->profile)); 362 profile = aa_get_profile(aa_newest_version(cxt->profile));
@@ -443,6 +439,8 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
443 } else { 439 } else {
444 error = -ENOENT; 440 error = -ENOENT;
445 info = "profile not found"; 441 info = "profile not found";
442 /* remove MAY_EXEC to audit as failure */
443 perms.allow &= ~MAY_EXEC;
446 } 444 }
447 } 445 }
448 } else if (COMPLAIN_MODE(profile)) { 446 } else if (COMPLAIN_MODE(profile)) {
@@ -514,11 +512,7 @@ x_clear:
514 cxt->profile = new_profile; 512 cxt->profile = new_profile;
515 513
516 /* clear out all temporary/transitional state from the context */ 514 /* clear out all temporary/transitional state from the context */
517 aa_put_profile(cxt->previous); 515 aa_clear_task_cxt_trans(cxt);
518 aa_put_profile(cxt->onexec);
519 cxt->previous = NULL;
520 cxt->onexec = NULL;
521 cxt->token = 0;
522 516
523audit: 517audit:
524 error = aa_audit_file(profile, &perms, GFP_KERNEL, OP_EXEC, MAY_EXEC, 518 error = aa_audit_file(profile, &perms, GFP_KERNEL, OP_EXEC, MAY_EXEC,
@@ -557,7 +551,7 @@ int apparmor_bprm_secureexec(struct linux_binprm *bprm)
557void apparmor_bprm_committing_creds(struct linux_binprm *bprm) 551void apparmor_bprm_committing_creds(struct linux_binprm *bprm)
558{ 552{
559 struct aa_profile *profile = __aa_current_profile(); 553 struct aa_profile *profile = __aa_current_profile();
560 struct aa_task_cxt *new_cxt = bprm->cred->security; 554 struct aa_task_cxt *new_cxt = cred_cxt(bprm->cred);
561 555
562 /* bail out if unconfined or not changing profile */ 556 /* bail out if unconfined or not changing profile */
563 if ((new_cxt->profile == profile) || 557 if ((new_cxt->profile == profile) ||
@@ -634,7 +628,7 @@ int aa_change_hat(const char *hats[], int count, u64 token, bool permtest)
634 628
635 /* released below */ 629 /* released below */
636 cred = get_current_cred(); 630 cred = get_current_cred();
637 cxt = cred->security; 631 cxt = cred_cxt(cred);
638 profile = aa_cred_profile(cred); 632 profile = aa_cred_profile(cred);
639 previous_profile = cxt->previous; 633 previous_profile = cxt->previous;
640 634
@@ -750,7 +744,6 @@ int aa_change_profile(const char *ns_name, const char *hname, bool onexec,
750 bool permtest) 744 bool permtest)
751{ 745{
752 const struct cred *cred; 746 const struct cred *cred;
753 struct aa_task_cxt *cxt;
754 struct aa_profile *profile, *target = NULL; 747 struct aa_profile *profile, *target = NULL;
755 struct aa_namespace *ns = NULL; 748 struct aa_namespace *ns = NULL;
756 struct file_perms perms = {}; 749 struct file_perms perms = {};
@@ -770,7 +763,6 @@ int aa_change_profile(const char *ns_name, const char *hname, bool onexec,
770 } 763 }
771 764
772 cred = get_current_cred(); 765 cred = get_current_cred();
773 cxt = cred->security;
774 profile = aa_cred_profile(cred); 766 profile = aa_cred_profile(cred);
775 767
776 /* 768 /*
diff --git a/security/apparmor/include/apparmor.h b/security/apparmor/include/apparmor.h
index 40aedd9f73ea..1ba2ca56a6ef 100644
--- a/security/apparmor/include/apparmor.h
+++ b/security/apparmor/include/apparmor.h
@@ -15,6 +15,7 @@
15#ifndef __APPARMOR_H 15#ifndef __APPARMOR_H
16#define __APPARMOR_H 16#define __APPARMOR_H
17 17
18#include <linux/slab.h>
18#include <linux/fs.h> 19#include <linux/fs.h>
19 20
20#include "match.h" 21#include "match.h"
@@ -64,9 +65,18 @@ extern int apparmor_initialized __initdata;
64/* fn's in lib */ 65/* fn's in lib */
65char *aa_split_fqname(char *args, char **ns_name); 66char *aa_split_fqname(char *args, char **ns_name);
66void aa_info_message(const char *str); 67void aa_info_message(const char *str);
67void *kvmalloc(size_t size); 68void *__aa_kvmalloc(size_t size, gfp_t flags);
68void kvfree(void *buffer); 69void kvfree(void *buffer);
69 70
71static inline void *kvmalloc(size_t size)
72{
73 return __aa_kvmalloc(size, 0);
74}
75
76static inline void *kvzalloc(size_t size)
77{
78 return __aa_kvmalloc(size, __GFP_ZERO);
79}
70 80
71/** 81/**
72 * aa_strneq - compare null terminated @str to a non null terminated substring 82 * aa_strneq - compare null terminated @str to a non null terminated substring
diff --git a/security/apparmor/include/context.h b/security/apparmor/include/context.h
index a9cbee4d9e48..d44ba5802e3d 100644
--- a/security/apparmor/include/context.h
+++ b/security/apparmor/include/context.h
@@ -21,6 +21,9 @@
21 21
22#include "policy.h" 22#include "policy.h"
23 23
24#define cred_cxt(X) (X)->security
25#define current_cxt() cred_cxt(current_cred())
26
24/* struct aa_file_cxt - the AppArmor context the file was opened in 27/* struct aa_file_cxt - the AppArmor context the file was opened in
25 * @perms: the permission the file was opened with 28 * @perms: the permission the file was opened with
26 * 29 *
@@ -80,23 +83,8 @@ int aa_replace_current_profile(struct aa_profile *profile);
80int aa_set_current_onexec(struct aa_profile *profile); 83int aa_set_current_onexec(struct aa_profile *profile);
81int aa_set_current_hat(struct aa_profile *profile, u64 token); 84int aa_set_current_hat(struct aa_profile *profile, u64 token);
82int aa_restore_previous_profile(u64 cookie); 85int aa_restore_previous_profile(u64 cookie);
86struct aa_profile *aa_get_task_profile(struct task_struct *task);
83 87
84/**
85 * __aa_task_is_confined - determine if @task has any confinement
86 * @task: task to check confinement of (NOT NULL)
87 *
88 * If @task != current needs to be called in RCU safe critical section
89 */
90static inline bool __aa_task_is_confined(struct task_struct *task)
91{
92 struct aa_task_cxt *cxt = __task_cred(task)->security;
93
94 BUG_ON(!cxt || !cxt->profile);
95 if (unconfined(aa_newest_version(cxt->profile)))
96 return 0;
97
98 return 1;
99}
100 88
101/** 89/**
102 * aa_cred_profile - obtain cred's profiles 90 * aa_cred_profile - obtain cred's profiles
@@ -108,12 +96,36 @@ static inline bool __aa_task_is_confined(struct task_struct *task)
108 */ 96 */
109static inline struct aa_profile *aa_cred_profile(const struct cred *cred) 97static inline struct aa_profile *aa_cred_profile(const struct cred *cred)
110{ 98{
111 struct aa_task_cxt *cxt = cred->security; 99 struct aa_task_cxt *cxt = cred_cxt(cred);
112 BUG_ON(!cxt || !cxt->profile); 100 BUG_ON(!cxt || !cxt->profile);
113 return aa_newest_version(cxt->profile); 101 return aa_newest_version(cxt->profile);
114} 102}
115 103
116/** 104/**
105 * __aa_task_profile - retrieve another task's profile
106 * @task: task to query (NOT NULL)
107 *
108 * Returns: @task's profile without incrementing its ref count
109 *
110 * If @task != current needs to be called in RCU safe critical section
111 */
112static inline struct aa_profile *__aa_task_profile(struct task_struct *task)
113{
114 return aa_cred_profile(__task_cred(task));
115}
116
117/**
118 * __aa_task_is_confined - determine if @task has any confinement
119 * @task: task to check confinement of (NOT NULL)
120 *
121 * If @task != current needs to be called in RCU safe critical section
122 */
123static inline bool __aa_task_is_confined(struct task_struct *task)
124{
125 return !unconfined(__aa_task_profile(task));
126}
127
128/**
117 * __aa_current_profile - find the current tasks confining profile 129 * __aa_current_profile - find the current tasks confining profile
118 * 130 *
119 * Returns: up to date confining profile or the ns unconfined profile (NOT NULL) 131 * Returns: up to date confining profile or the ns unconfined profile (NOT NULL)
@@ -136,7 +148,7 @@ static inline struct aa_profile *__aa_current_profile(void)
136 */ 148 */
137static inline struct aa_profile *aa_current_profile(void) 149static inline struct aa_profile *aa_current_profile(void)
138{ 150{
139 const struct aa_task_cxt *cxt = current_cred()->security; 151 const struct aa_task_cxt *cxt = current_cxt();
140 struct aa_profile *profile; 152 struct aa_profile *profile;
141 BUG_ON(!cxt || !cxt->profile); 153 BUG_ON(!cxt || !cxt->profile);
142 154
@@ -151,4 +163,17 @@ static inline struct aa_profile *aa_current_profile(void)
151 return profile; 163 return profile;
152} 164}
153 165
166/**
167 * aa_clear_task_cxt_trans - clear transition tracking info from the cxt
168 * @cxt: task context to clear (NOT NULL)
169 */
170static inline void aa_clear_task_cxt_trans(struct aa_task_cxt *cxt)
171{
172 aa_put_profile(cxt->previous);
173 aa_put_profile(cxt->onexec);
174 cxt->previous = NULL;
175 cxt->onexec = NULL;
176 cxt->token = 0;
177}
178
154#endif /* __AA_CONTEXT_H */ 179#endif /* __AA_CONTEXT_H */
diff --git a/security/apparmor/include/file.h b/security/apparmor/include/file.h
index 967b2deda376..2c922b86bd44 100644
--- a/security/apparmor/include/file.h
+++ b/security/apparmor/include/file.h
@@ -186,11 +186,6 @@ static inline void aa_free_file_rules(struct aa_file_rules *rules)
186 aa_free_domain_entries(&rules->trans); 186 aa_free_domain_entries(&rules->trans);
187} 187}
188 188
189#define ACC_FMODE(x) (("\000\004\002\006"[(x)&O_ACCMODE]) | (((x) << 1) & 0x40))
190
191/* from namei.c */
192#define MAP_OPEN_FLAGS(x) ((((x) + 1) & O_ACCMODE) ? (x) + 1 : (x))
193
194/** 189/**
195 * aa_map_file_perms - map file flags to AppArmor permissions 190 * aa_map_file_perms - map file flags to AppArmor permissions
196 * @file: open file to map flags to AppArmor permissions 191 * @file: open file to map flags to AppArmor permissions
@@ -199,8 +194,13 @@ static inline void aa_free_file_rules(struct aa_file_rules *rules)
199 */ 194 */
200static inline u32 aa_map_file_to_perms(struct file *file) 195static inline u32 aa_map_file_to_perms(struct file *file)
201{ 196{
202 int flags = MAP_OPEN_FLAGS(file->f_flags); 197 int flags = file->f_flags;
203 u32 perms = ACC_FMODE(file->f_mode); 198 u32 perms = 0;
199
200 if (file->f_mode & FMODE_WRITE)
201 perms |= MAY_WRITE;
202 if (file->f_mode & FMODE_READ)
203 perms |= MAY_READ;
204 204
205 if ((flags & O_APPEND) && (perms & MAY_WRITE)) 205 if ((flags & O_APPEND) && (perms & MAY_WRITE))
206 perms = (perms & ~MAY_WRITE) | MAY_APPEND; 206 perms = (perms & ~MAY_WRITE) | MAY_APPEND;
diff --git a/security/apparmor/include/match.h b/security/apparmor/include/match.h
index 775843e7f984..001c43aa0406 100644
--- a/security/apparmor/include/match.h
+++ b/security/apparmor/include/match.h
@@ -4,7 +4,7 @@
4 * This file contains AppArmor policy dfa matching engine definitions. 4 * This file contains AppArmor policy dfa matching engine definitions.
5 * 5 *
6 * Copyright (C) 1998-2008 Novell/SUSE 6 * Copyright (C) 1998-2008 Novell/SUSE
7 * Copyright 2009-2010 Canonical Ltd. 7 * Copyright 2009-2012 Canonical Ltd.
8 * 8 *
9 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as 10 * modify it under the terms of the GNU General Public License as
@@ -16,25 +16,30 @@
16#define __AA_MATCH_H 16#define __AA_MATCH_H
17 17
18#include <linux/kref.h> 18#include <linux/kref.h>
19#include <linux/workqueue.h>
20 19
21#define DFA_NOMATCH 0 20#define DFA_NOMATCH 0
22#define DFA_START 1 21#define DFA_START 1
23 22
24#define DFA_VALID_PERM_MASK 0xffffffff
25#define DFA_VALID_PERM2_MASK 0xffffffff
26 23
27/** 24/**
28 * The format used for transition tables is based on the GNU flex table 25 * The format used for transition tables is based on the GNU flex table
29 * file format (--tables-file option; see Table File Format in the flex 26 * file format (--tables-file option; see Table File Format in the flex
30 * info pages and the flex sources for documentation). The magic number 27 * info pages and the flex sources for documentation). The magic number
31 * used in the header is 0x1B5E783D instead of 0xF13C57B1 though, because 28 * used in the header is 0x1B5E783D instead of 0xF13C57B1 though, because
32 * the YY_ID_CHK (check) and YY_ID_DEF (default) tables are used 29 * new tables have been defined and others YY_ID_CHK (check) and YY_ID_DEF
33 * slightly differently (see the apparmor-parser package). 30 * (default) tables are used slightly differently (see the apparmor-parser
31 * package).
32 *
33 *
34 * The data in the packed dfa is stored in network byte order, and the tables
35 * are arranged for flexibility. We convert the table data to host native
36 * byte order.
37 *
38 * The dfa begins with a table set header, and is followed by the actual
39 * tables.
34 */ 40 */
35 41
36#define YYTH_MAGIC 0x1B5E783D 42#define YYTH_MAGIC 0x1B5E783D
37#define YYTH_DEF_RECURSE 0x1 /* DEF Table is recursive */
38 43
39struct table_set_header { 44struct table_set_header {
40 u32 th_magic; /* YYTH_MAGIC */ 45 u32 th_magic; /* YYTH_MAGIC */
@@ -63,7 +68,7 @@ struct table_set_header {
63#define YYTD_DATA32 4 68#define YYTD_DATA32 4
64#define YYTD_DATA64 8 69#define YYTD_DATA64 8
65 70
66/* Each ACCEPT2 table gets 6 dedicated flags, YYTD_DATAX define the 71/* ACCEPT & ACCEPT2 tables gets 6 dedicated flags, YYTD_DATAX define the
67 * first flags 72 * first flags
68 */ 73 */
69#define ACCEPT1_FLAGS(X) ((X) & 0x3f) 74#define ACCEPT1_FLAGS(X) ((X) & 0x3f)
diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h
index bda4569fdd83..b25491a3046a 100644
--- a/security/apparmor/include/policy.h
+++ b/security/apparmor/include/policy.h
@@ -32,13 +32,13 @@
32extern const char *const profile_mode_names[]; 32extern const char *const profile_mode_names[];
33#define APPARMOR_NAMES_MAX_INDEX 3 33#define APPARMOR_NAMES_MAX_INDEX 3
34 34
35#define COMPLAIN_MODE(_profile) \ 35#define PROFILE_MODE(_profile, _mode) \
36 ((aa_g_profile_mode == APPARMOR_COMPLAIN) || \ 36 ((aa_g_profile_mode == (_mode)) || \
37 ((_profile)->mode == APPARMOR_COMPLAIN)) 37 ((_profile)->mode == (_mode)))
38 38
39#define KILL_MODE(_profile) \ 39#define COMPLAIN_MODE(_profile) PROFILE_MODE((_profile), APPARMOR_COMPLAIN)
40 ((aa_g_profile_mode == APPARMOR_KILL) || \ 40
41 ((_profile)->mode == APPARMOR_KILL)) 41#define KILL_MODE(_profile) PROFILE_MODE((_profile), APPARMOR_KILL)
42 42
43#define PROFILE_IS_HAT(_profile) ((_profile)->flags & PFLAG_HAT) 43#define PROFILE_IS_HAT(_profile) ((_profile)->flags & PFLAG_HAT)
44 44
@@ -105,6 +105,7 @@ struct aa_ns_acct {
105 * @acct: accounting for the namespace 105 * @acct: accounting for the namespace
106 * @unconfined: special unconfined profile for the namespace 106 * @unconfined: special unconfined profile for the namespace
107 * @sub_ns: list of namespaces under the current namespace. 107 * @sub_ns: list of namespaces under the current namespace.
108 * @uniq_null: uniq value used for null learning profiles
108 * 109 *
109 * An aa_namespace defines the set profiles that are searched to determine 110 * An aa_namespace defines the set profiles that are searched to determine
110 * which profile to attach to a task. Profiles can not be shared between 111 * which profile to attach to a task. Profiles can not be shared between
@@ -127,6 +128,7 @@ struct aa_namespace {
127 struct aa_ns_acct acct; 128 struct aa_ns_acct acct;
128 struct aa_profile *unconfined; 129 struct aa_profile *unconfined;
129 struct list_head sub_ns; 130 struct list_head sub_ns;
131 atomic_t uniq_null;
130}; 132};
131 133
132/* struct aa_policydb - match engine for a policy 134/* struct aa_policydb - match engine for a policy
@@ -148,7 +150,6 @@ struct aa_policydb {
148 * @rename: optional profile name that this profile renamed 150 * @rename: optional profile name that this profile renamed
149 * @xmatch: optional extended matching for unconfined executables names 151 * @xmatch: optional extended matching for unconfined executables names
150 * @xmatch_len: xmatch prefix len, used to determine xmatch priority 152 * @xmatch_len: xmatch prefix len, used to determine xmatch priority
151 * @sid: the unique security id number of this profile
152 * @audit: the auditing mode of the profile 153 * @audit: the auditing mode of the profile
153 * @mode: the enforcement mode of the profile 154 * @mode: the enforcement mode of the profile
154 * @flags: flags controlling profile behavior 155 * @flags: flags controlling profile behavior
@@ -184,7 +185,6 @@ struct aa_profile {
184 185
185 struct aa_dfa *xmatch; 186 struct aa_dfa *xmatch;
186 int xmatch_len; 187 int xmatch_len;
187 u32 sid;
188 enum audit_mode audit; 188 enum audit_mode audit;
189 enum profile_mode mode; 189 enum profile_mode mode;
190 u32 flags; 190 u32 flags;
diff --git a/security/apparmor/include/procattr.h b/security/apparmor/include/procattr.h
index 544aa6b766a4..6bd5f33d9533 100644
--- a/security/apparmor/include/procattr.h
+++ b/security/apparmor/include/procattr.h
@@ -21,6 +21,5 @@
21int aa_getprocattr(struct aa_profile *profile, char **string); 21int aa_getprocattr(struct aa_profile *profile, char **string);
22int aa_setprocattr_changehat(char *args, size_t size, int test); 22int aa_setprocattr_changehat(char *args, size_t size, int test);
23int aa_setprocattr_changeprofile(char *fqname, bool onexec, int test); 23int aa_setprocattr_changeprofile(char *fqname, bool onexec, int test);
24int aa_setprocattr_permipc(char *fqname);
25 24
26#endif /* __AA_PROCATTR_H */ 25#endif /* __AA_PROCATTR_H */
diff --git a/security/apparmor/include/sid.h b/security/apparmor/include/sid.h
index 020db35c3010..513ca0e48965 100644
--- a/security/apparmor/include/sid.h
+++ b/security/apparmor/include/sid.h
@@ -16,7 +16,9 @@
16 16
17#include <linux/types.h> 17#include <linux/types.h>
18 18
19struct aa_profile; 19/* sid value that will not be allocated */
20#define AA_SID_INVALID 0
21#define AA_SID_ALLOC AA_SID_INVALID
20 22
21u32 aa_alloc_sid(void); 23u32 aa_alloc_sid(void);
22void aa_free_sid(u32 sid); 24void aa_free_sid(u32 sid);
diff --git a/security/apparmor/ipc.c b/security/apparmor/ipc.c
index cf1071b14232..c51d2266587e 100644
--- a/security/apparmor/ipc.c
+++ b/security/apparmor/ipc.c
@@ -95,23 +95,18 @@ int aa_ptrace(struct task_struct *tracer, struct task_struct *tracee,
95 * - tracer profile has CAP_SYS_PTRACE 95 * - tracer profile has CAP_SYS_PTRACE
96 */ 96 */
97 97
98 struct aa_profile *tracer_p; 98 struct aa_profile *tracer_p = aa_get_task_profile(tracer);
99 /* cred released below */
100 const struct cred *cred = get_task_cred(tracer);
101 int error = 0; 99 int error = 0;
102 tracer_p = aa_cred_profile(cred);
103 100
104 if (!unconfined(tracer_p)) { 101 if (!unconfined(tracer_p)) {
105 /* lcred released below */ 102 struct aa_profile *tracee_p = aa_get_task_profile(tracee);
106 const struct cred *lcred = get_task_cred(tracee);
107 struct aa_profile *tracee_p = aa_cred_profile(lcred);
108 103
109 error = aa_may_ptrace(tracer, tracer_p, tracee_p, mode); 104 error = aa_may_ptrace(tracer, tracer_p, tracee_p, mode);
110 error = aa_audit_ptrace(tracer_p, tracee_p, error); 105 error = aa_audit_ptrace(tracer_p, tracee_p, error);
111 106
112 put_cred(lcred); 107 aa_put_profile(tracee_p);
113 } 108 }
114 put_cred(cred); 109 aa_put_profile(tracer_p);
115 110
116 return error; 111 return error;
117} 112}
diff --git a/security/apparmor/lib.c b/security/apparmor/lib.c
index 7430298116d6..fcfe0233574c 100644
--- a/security/apparmor/lib.c
+++ b/security/apparmor/lib.c
@@ -45,8 +45,10 @@ char *aa_split_fqname(char *fqname, char **ns_name)
45 *ns_name = skip_spaces(&name[1]); 45 *ns_name = skip_spaces(&name[1]);
46 if (split) { 46 if (split) {
47 /* overwrite ':' with \0 */ 47 /* overwrite ':' with \0 */
48 *split = 0; 48 *split++ = 0;
49 name = skip_spaces(split + 1); 49 if (strncmp(split, "//", 2) == 0)
50 split += 2;
51 name = skip_spaces(split);
50 } else 52 } else
51 /* a ns name without a following profile is allowed */ 53 /* a ns name without a following profile is allowed */
52 name = NULL; 54 name = NULL;
@@ -75,15 +77,16 @@ void aa_info_message(const char *str)
75} 77}
76 78
77/** 79/**
78 * kvmalloc - do allocation preferring kmalloc but falling back to vmalloc 80 * __aa_kvmalloc - do allocation preferring kmalloc but falling back to vmalloc
79 * @size: size of allocation 81 * @size: how many bytes of memory are required
82 * @flags: the type of memory to allocate (see kmalloc).
80 * 83 *
81 * Return: allocated buffer or NULL if failed 84 * Return: allocated buffer or NULL if failed
82 * 85 *
83 * It is possible that policy being loaded from the user is larger than 86 * It is possible that policy being loaded from the user is larger than
84 * what can be allocated by kmalloc, in those cases fall back to vmalloc. 87 * what can be allocated by kmalloc, in those cases fall back to vmalloc.
85 */ 88 */
86void *kvmalloc(size_t size) 89void *__aa_kvmalloc(size_t size, gfp_t flags)
87{ 90{
88 void *buffer = NULL; 91 void *buffer = NULL;
89 92
@@ -92,32 +95,22 @@ void *kvmalloc(size_t size)
92 95
93 /* do not attempt kmalloc if we need more than 16 pages at once */ 96 /* do not attempt kmalloc if we need more than 16 pages at once */
94 if (size <= (16*PAGE_SIZE)) 97 if (size <= (16*PAGE_SIZE))
95 buffer = kmalloc(size, GFP_NOIO | __GFP_NOWARN); 98 buffer = kmalloc(size, flags | GFP_NOIO | __GFP_NOWARN);
96 if (!buffer) { 99 if (!buffer) {
97 /* see kvfree for why size must be at least work_struct size 100 /* see kvfree for why size must be at least work_struct size
98 * when allocated via vmalloc 101 * when allocated via vmalloc
99 */ 102 */
100 if (size < sizeof(struct work_struct)) 103 if (size < sizeof(struct work_struct))
101 size = sizeof(struct work_struct); 104 size = sizeof(struct work_struct);
102 buffer = vmalloc(size); 105 if (flags & __GFP_ZERO)
106 buffer = vzalloc(size);
107 else
108 buffer = vmalloc(size);
103 } 109 }
104 return buffer; 110 return buffer;
105} 111}
106 112
107/** 113/**
108 * do_vfree - workqueue routine for freeing vmalloced memory
109 * @work: data to be freed
110 *
111 * The work_struct is overlaid to the data being freed, as at the point
112 * the work is scheduled the data is no longer valid, be its freeing
113 * needs to be delayed until safe.
114 */
115static void do_vfree(struct work_struct *work)
116{
117 vfree(work);
118}
119
120/**
121 * kvfree - free an allocation do by kvmalloc 114 * kvfree - free an allocation do by kvmalloc
122 * @buffer: buffer to free (MAYBE_NULL) 115 * @buffer: buffer to free (MAYBE_NULL)
123 * 116 *
@@ -125,13 +118,8 @@ static void do_vfree(struct work_struct *work)
125 */ 118 */
126void kvfree(void *buffer) 119void kvfree(void *buffer)
127{ 120{
128 if (is_vmalloc_addr(buffer)) { 121 if (is_vmalloc_addr(buffer))
129 /* Data is no longer valid so just use the allocated space 122 vfree(buffer);
130 * as the work_struct 123 else
131 */
132 struct work_struct *work = (struct work_struct *) buffer;
133 INIT_WORK(work, do_vfree);
134 schedule_work(work);
135 } else
136 kfree(buffer); 124 kfree(buffer);
137} 125}
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index b21830eced41..2e2a0dd4a73f 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -48,8 +48,8 @@ int apparmor_initialized __initdata;
48 */ 48 */
49static void apparmor_cred_free(struct cred *cred) 49static void apparmor_cred_free(struct cred *cred)
50{ 50{
51 aa_free_task_context(cred->security); 51 aa_free_task_context(cred_cxt(cred));
52 cred->security = NULL; 52 cred_cxt(cred) = NULL;
53} 53}
54 54
55/* 55/*
@@ -62,7 +62,7 @@ static int apparmor_cred_alloc_blank(struct cred *cred, gfp_t gfp)
62 if (!cxt) 62 if (!cxt)
63 return -ENOMEM; 63 return -ENOMEM;
64 64
65 cred->security = cxt; 65 cred_cxt(cred) = cxt;
66 return 0; 66 return 0;
67} 67}
68 68
@@ -77,8 +77,8 @@ static int apparmor_cred_prepare(struct cred *new, const struct cred *old,
77 if (!cxt) 77 if (!cxt)
78 return -ENOMEM; 78 return -ENOMEM;
79 79
80 aa_dup_task_context(cxt, old->security); 80 aa_dup_task_context(cxt, cred_cxt(old));
81 new->security = cxt; 81 cred_cxt(new) = cxt;
82 return 0; 82 return 0;
83} 83}
84 84
@@ -87,8 +87,8 @@ static int apparmor_cred_prepare(struct cred *new, const struct cred *old,
87 */ 87 */
88static void apparmor_cred_transfer(struct cred *new, const struct cred *old) 88static void apparmor_cred_transfer(struct cred *new, const struct cred *old)
89{ 89{
90 const struct aa_task_cxt *old_cxt = old->security; 90 const struct aa_task_cxt *old_cxt = cred_cxt(old);
91 struct aa_task_cxt *new_cxt = new->security; 91 struct aa_task_cxt *new_cxt = cred_cxt(new);
92 92
93 aa_dup_task_context(new_cxt, old_cxt); 93 aa_dup_task_context(new_cxt, old_cxt);
94} 94}
@@ -469,7 +469,6 @@ static int apparmor_file_lock(struct file *file, unsigned int cmd)
469static int common_mmap(int op, struct file *file, unsigned long prot, 469static int common_mmap(int op, struct file *file, unsigned long prot,
470 unsigned long flags) 470 unsigned long flags)
471{ 471{
472 struct dentry *dentry;
473 int mask = 0; 472 int mask = 0;
474 473
475 if (!file || !file->f_security) 474 if (!file || !file->f_security)
@@ -486,7 +485,6 @@ static int common_mmap(int op, struct file *file, unsigned long prot,
486 if (prot & PROT_EXEC) 485 if (prot & PROT_EXEC)
487 mask |= AA_EXEC_MMAP; 486 mask |= AA_EXEC_MMAP;
488 487
489 dentry = file->f_path.dentry;
490 return common_file_perm(op, file, mask); 488 return common_file_perm(op, file, mask);
491} 489}
492 490
@@ -507,11 +505,9 @@ static int apparmor_getprocattr(struct task_struct *task, char *name,
507 char **value) 505 char **value)
508{ 506{
509 int error = -ENOENT; 507 int error = -ENOENT;
510 struct aa_profile *profile;
511 /* released below */ 508 /* released below */
512 const struct cred *cred = get_task_cred(task); 509 const struct cred *cred = get_task_cred(task);
513 struct aa_task_cxt *cxt = cred->security; 510 struct aa_task_cxt *cxt = cred_cxt(cred);
514 profile = aa_cred_profile(cred);
515 511
516 if (strcmp(name, "current") == 0) 512 if (strcmp(name, "current") == 0)
517 error = aa_getprocattr(aa_newest_version(cxt->profile), 513 error = aa_getprocattr(aa_newest_version(cxt->profile),
@@ -533,6 +529,8 @@ static int apparmor_getprocattr(struct task_struct *task, char *name,
533static int apparmor_setprocattr(struct task_struct *task, char *name, 529static int apparmor_setprocattr(struct task_struct *task, char *name,
534 void *value, size_t size) 530 void *value, size_t size)
535{ 531{
532 struct common_audit_data sa;
533 struct apparmor_audit_data aad = {0,};
536 char *command, *args = value; 534 char *command, *args = value;
537 size_t arg_size; 535 size_t arg_size;
538 int error; 536 int error;
@@ -576,30 +574,31 @@ static int apparmor_setprocattr(struct task_struct *task, char *name,
576 } else if (strcmp(command, "permprofile") == 0) { 574 } else if (strcmp(command, "permprofile") == 0) {
577 error = aa_setprocattr_changeprofile(args, !AA_ONEXEC, 575 error = aa_setprocattr_changeprofile(args, !AA_ONEXEC,
578 AA_DO_TEST); 576 AA_DO_TEST);
579 } else if (strcmp(command, "permipc") == 0) { 577 } else
580 error = aa_setprocattr_permipc(args); 578 goto fail;
581 } else {
582 struct common_audit_data sa;
583 struct apparmor_audit_data aad = {0,};
584 sa.type = LSM_AUDIT_DATA_NONE;
585 sa.aad = &aad;
586 aad.op = OP_SETPROCATTR;
587 aad.info = name;
588 aad.error = -EINVAL;
589 return aa_audit(AUDIT_APPARMOR_DENIED,
590 __aa_current_profile(), GFP_KERNEL,
591 &sa, NULL);
592 }
593 } else if (strcmp(name, "exec") == 0) { 579 } else if (strcmp(name, "exec") == 0) {
594 error = aa_setprocattr_changeprofile(args, AA_ONEXEC, 580 if (strcmp(command, "exec") == 0)
595 !AA_DO_TEST); 581 error = aa_setprocattr_changeprofile(args, AA_ONEXEC,
596 } else { 582 !AA_DO_TEST);
583 else
584 goto fail;
585 } else
597 /* only support the "current" and "exec" process attributes */ 586 /* only support the "current" and "exec" process attributes */
598 return -EINVAL; 587 return -EINVAL;
599 } 588
600 if (!error) 589 if (!error)
601 error = size; 590 error = size;
602 return error; 591 return error;
592
593fail:
594 sa.type = LSM_AUDIT_DATA_NONE;
595 sa.aad = &aad;
596 aad.profile = aa_current_profile();
597 aad.op = OP_SETPROCATTR;
598 aad.info = name;
599 aad.error = -EINVAL;
600 aa_audit_msg(AUDIT_APPARMOR_DENIED, &sa, NULL);
601 return -EINVAL;
603} 602}
604 603
605static int apparmor_task_setrlimit(struct task_struct *task, 604static int apparmor_task_setrlimit(struct task_struct *task,
@@ -886,7 +885,7 @@ static int __init set_init_cxt(void)
886 return -ENOMEM; 885 return -ENOMEM;
887 886
888 cxt->profile = aa_get_profile(root_ns->unconfined); 887 cxt->profile = aa_get_profile(root_ns->unconfined);
889 cred->security = cxt; 888 cred_cxt(cred) = cxt;
890 889
891 return 0; 890 return 0;
892} 891}
@@ -915,8 +914,11 @@ static int __init apparmor_init(void)
915 914
916 error = register_security(&apparmor_ops); 915 error = register_security(&apparmor_ops);
917 if (error) { 916 if (error) {
917 struct cred *cred = (struct cred *)current->real_cred;
918 aa_free_task_context(cred_cxt(cred));
919 cred_cxt(cred) = NULL;
918 AA_ERROR("Unable to register AppArmor\n"); 920 AA_ERROR("Unable to register AppArmor\n");
919 goto set_init_cxt_out; 921 goto register_security_out;
920 } 922 }
921 923
922 /* Report that AppArmor successfully initialized */ 924 /* Report that AppArmor successfully initialized */
@@ -930,9 +932,6 @@ static int __init apparmor_init(void)
930 932
931 return error; 933 return error;
932 934
933set_init_cxt_out:
934 aa_free_task_context(current->real_cred->security);
935
936register_security_out: 935register_security_out:
937 aa_free_root_ns(); 936 aa_free_root_ns();
938 937
diff --git a/security/apparmor/match.c b/security/apparmor/match.c
index 90971a8c3789..727eb4200d5c 100644
--- a/security/apparmor/match.c
+++ b/security/apparmor/match.c
@@ -4,7 +4,7 @@
4 * This file contains AppArmor dfa based regular expression matching engine 4 * This file contains AppArmor dfa based regular expression matching engine
5 * 5 *
6 * Copyright (C) 1998-2008 Novell/SUSE 6 * Copyright (C) 1998-2008 Novell/SUSE
7 * Copyright 2009-2010 Canonical Ltd. 7 * Copyright 2009-2012 Canonical Ltd.
8 * 8 *
9 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as 10 * modify it under the terms of the GNU General Public License as
@@ -23,6 +23,8 @@
23#include "include/apparmor.h" 23#include "include/apparmor.h"
24#include "include/match.h" 24#include "include/match.h"
25 25
26#define base_idx(X) ((X) & 0xffffff)
27
26/** 28/**
27 * unpack_table - unpack a dfa table (one of accept, default, base, next check) 29 * unpack_table - unpack a dfa table (one of accept, default, base, next check)
28 * @blob: data to unpack (NOT NULL) 30 * @blob: data to unpack (NOT NULL)
@@ -30,7 +32,7 @@
30 * 32 *
31 * Returns: pointer to table else NULL on failure 33 * Returns: pointer to table else NULL on failure
32 * 34 *
33 * NOTE: must be freed by kvfree (not kmalloc) 35 * NOTE: must be freed by kvfree (not kfree)
34 */ 36 */
35static struct table_header *unpack_table(char *blob, size_t bsize) 37static struct table_header *unpack_table(char *blob, size_t bsize)
36{ 38{
@@ -57,7 +59,7 @@ static struct table_header *unpack_table(char *blob, size_t bsize)
57 if (bsize < tsize) 59 if (bsize < tsize)
58 goto out; 60 goto out;
59 61
60 table = kvmalloc(tsize); 62 table = kvzalloc(tsize);
61 if (table) { 63 if (table) {
62 *table = th; 64 *table = th;
63 if (th.td_flags == YYTD_DATA8) 65 if (th.td_flags == YYTD_DATA8)
@@ -137,8 +139,7 @@ static int verify_dfa(struct aa_dfa *dfa, int flags)
137 for (i = 0; i < state_count; i++) { 139 for (i = 0; i < state_count; i++) {
138 if (DEFAULT_TABLE(dfa)[i] >= state_count) 140 if (DEFAULT_TABLE(dfa)[i] >= state_count)
139 goto out; 141 goto out;
140 /* TODO: do check that DEF state recursion terminates */ 142 if (base_idx(BASE_TABLE(dfa)[i]) + 255 >= trans_count) {
141 if (BASE_TABLE(dfa)[i] + 255 >= trans_count) {
142 printk(KERN_ERR "AppArmor DFA next/check upper " 143 printk(KERN_ERR "AppArmor DFA next/check upper "
143 "bounds error\n"); 144 "bounds error\n");
144 goto out; 145 goto out;
@@ -314,7 +315,7 @@ unsigned int aa_dfa_match_len(struct aa_dfa *dfa, unsigned int start,
314 u8 *equiv = EQUIV_TABLE(dfa); 315 u8 *equiv = EQUIV_TABLE(dfa);
315 /* default is direct to next state */ 316 /* default is direct to next state */
316 for (; len; len--) { 317 for (; len; len--) {
317 pos = base[state] + equiv[(u8) *str++]; 318 pos = base_idx(base[state]) + equiv[(u8) *str++];
318 if (check[pos] == state) 319 if (check[pos] == state)
319 state = next[pos]; 320 state = next[pos];
320 else 321 else
@@ -323,7 +324,7 @@ unsigned int aa_dfa_match_len(struct aa_dfa *dfa, unsigned int start,
323 } else { 324 } else {
324 /* default is direct to next state */ 325 /* default is direct to next state */
325 for (; len; len--) { 326 for (; len; len--) {
326 pos = base[state] + (u8) *str++; 327 pos = base_idx(base[state]) + (u8) *str++;
327 if (check[pos] == state) 328 if (check[pos] == state)
328 state = next[pos]; 329 state = next[pos];
329 else 330 else
@@ -364,7 +365,7 @@ unsigned int aa_dfa_match(struct aa_dfa *dfa, unsigned int start,
364 u8 *equiv = EQUIV_TABLE(dfa); 365 u8 *equiv = EQUIV_TABLE(dfa);
365 /* default is direct to next state */ 366 /* default is direct to next state */
366 while (*str) { 367 while (*str) {
367 pos = base[state] + equiv[(u8) *str++]; 368 pos = base_idx(base[state]) + equiv[(u8) *str++];
368 if (check[pos] == state) 369 if (check[pos] == state)
369 state = next[pos]; 370 state = next[pos];
370 else 371 else
@@ -373,7 +374,7 @@ unsigned int aa_dfa_match(struct aa_dfa *dfa, unsigned int start,
373 } else { 374 } else {
374 /* default is direct to next state */ 375 /* default is direct to next state */
375 while (*str) { 376 while (*str) {
376 pos = base[state] + (u8) *str++; 377 pos = base_idx(base[state]) + (u8) *str++;
377 if (check[pos] == state) 378 if (check[pos] == state)
378 state = next[pos]; 379 state = next[pos];
379 else 380 else
@@ -409,14 +410,14 @@ unsigned int aa_dfa_next(struct aa_dfa *dfa, unsigned int state,
409 u8 *equiv = EQUIV_TABLE(dfa); 410 u8 *equiv = EQUIV_TABLE(dfa);
410 /* default is direct to next state */ 411 /* default is direct to next state */
411 412
412 pos = base[state] + equiv[(u8) c]; 413 pos = base_idx(base[state]) + equiv[(u8) c];
413 if (check[pos] == state) 414 if (check[pos] == state)
414 state = next[pos]; 415 state = next[pos];
415 else 416 else
416 state = def[state]; 417 state = def[state];
417 } else { 418 } else {
418 /* default is direct to next state */ 419 /* default is direct to next state */
419 pos = base[state] + (u8) c; 420 pos = base_idx(base[state]) + (u8) c;
420 if (check[pos] == state) 421 if (check[pos] == state)
421 state = next[pos]; 422 state = next[pos];
422 else 423 else
diff --git a/security/apparmor/path.c b/security/apparmor/path.c
index e91ffee80162..35b394a75d76 100644
--- a/security/apparmor/path.c
+++ b/security/apparmor/path.c
@@ -174,7 +174,7 @@ static int get_name_to_buffer(struct path *path, int flags, char *buffer,
174 if (info && error) { 174 if (info && error) {
175 if (error == -ENOENT) 175 if (error == -ENOENT)
176 *info = "Failed name lookup - deleted entry"; 176 *info = "Failed name lookup - deleted entry";
177 else if (error == -ESTALE) 177 else if (error == -EACCES)
178 *info = "Failed name lookup - disconnected path"; 178 *info = "Failed name lookup - disconnected path";
179 else if (error == -ENAMETOOLONG) 179 else if (error == -ENAMETOOLONG)
180 *info = "Failed name lookup - name too long"; 180 *info = "Failed name lookup - name too long";
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
index 813200384d97..0f345c4dee5f 100644
--- a/security/apparmor/policy.c
+++ b/security/apparmor/policy.c
@@ -87,7 +87,6 @@
87#include "include/policy.h" 87#include "include/policy.h"
88#include "include/policy_unpack.h" 88#include "include/policy_unpack.h"
89#include "include/resource.h" 89#include "include/resource.h"
90#include "include/sid.h"
91 90
92 91
93/* root profile namespace */ 92/* root profile namespace */
@@ -292,7 +291,6 @@ static struct aa_namespace *alloc_namespace(const char *prefix,
292 if (!ns->unconfined) 291 if (!ns->unconfined)
293 goto fail_unconfined; 292 goto fail_unconfined;
294 293
295 ns->unconfined->sid = aa_alloc_sid();
296 ns->unconfined->flags = PFLAG_UNCONFINED | PFLAG_IX_ON_NAME_ERROR | 294 ns->unconfined->flags = PFLAG_UNCONFINED | PFLAG_IX_ON_NAME_ERROR |
297 PFLAG_IMMUTABLE; 295 PFLAG_IMMUTABLE;
298 296
@@ -303,6 +301,8 @@ static struct aa_namespace *alloc_namespace(const char *prefix,
303 */ 301 */
304 ns->unconfined->ns = aa_get_namespace(ns); 302 ns->unconfined->ns = aa_get_namespace(ns);
305 303
304 atomic_set(&ns->uniq_null, 0);
305
306 return ns; 306 return ns;
307 307
308fail_unconfined: 308fail_unconfined:
@@ -497,7 +497,6 @@ static void __replace_profile(struct aa_profile *old, struct aa_profile *new)
497 /* released when @new is freed */ 497 /* released when @new is freed */
498 new->parent = aa_get_profile(old->parent); 498 new->parent = aa_get_profile(old->parent);
499 new->ns = aa_get_namespace(old->ns); 499 new->ns = aa_get_namespace(old->ns);
500 new->sid = old->sid;
501 __list_add_profile(&policy->profiles, new); 500 __list_add_profile(&policy->profiles, new);
502 /* inherit children */ 501 /* inherit children */
503 list_for_each_entry_safe(child, tmp, &old->base.profiles, base.list) { 502 list_for_each_entry_safe(child, tmp, &old->base.profiles, base.list) {
@@ -636,83 +635,6 @@ void __init aa_free_root_ns(void)
636} 635}
637 636
638/** 637/**
639 * aa_alloc_profile - allocate, initialize and return a new profile
640 * @hname: name of the profile (NOT NULL)
641 *
642 * Returns: refcount profile or NULL on failure
643 */
644struct aa_profile *aa_alloc_profile(const char *hname)
645{
646 struct aa_profile *profile;
647
648 /* freed by free_profile - usually through aa_put_profile */
649 profile = kzalloc(sizeof(*profile), GFP_KERNEL);
650 if (!profile)
651 return NULL;
652
653 if (!policy_init(&profile->base, NULL, hname)) {
654 kzfree(profile);
655 return NULL;
656 }
657
658 /* refcount released by caller */
659 return profile;
660}
661
662/**
663 * aa_new_null_profile - create a new null-X learning profile
664 * @parent: profile that caused this profile to be created (NOT NULL)
665 * @hat: true if the null- learning profile is a hat
666 *
667 * Create a null- complain mode profile used in learning mode. The name of
668 * the profile is unique and follows the format of parent//null-sid.
669 *
670 * null profiles are added to the profile list but the list does not
671 * hold a count on them so that they are automatically released when
672 * not in use.
673 *
674 * Returns: new refcounted profile else NULL on failure
675 */
676struct aa_profile *aa_new_null_profile(struct aa_profile *parent, int hat)
677{
678 struct aa_profile *profile = NULL;
679 char *name;
680 u32 sid = aa_alloc_sid();
681
682 /* freed below */
683 name = kmalloc(strlen(parent->base.hname) + 2 + 7 + 8, GFP_KERNEL);
684 if (!name)
685 goto fail;
686 sprintf(name, "%s//null-%x", parent->base.hname, sid);
687
688 profile = aa_alloc_profile(name);
689 kfree(name);
690 if (!profile)
691 goto fail;
692
693 profile->sid = sid;
694 profile->mode = APPARMOR_COMPLAIN;
695 profile->flags = PFLAG_NULL;
696 if (hat)
697 profile->flags |= PFLAG_HAT;
698
699 /* released on free_profile */
700 profile->parent = aa_get_profile(parent);
701 profile->ns = aa_get_namespace(parent->ns);
702
703 write_lock(&profile->ns->lock);
704 __list_add_profile(&parent->base.profiles, profile);
705 write_unlock(&profile->ns->lock);
706
707 /* refcount released by caller */
708 return profile;
709
710fail:
711 aa_free_sid(sid);
712 return NULL;
713}
714
715/**
716 * free_profile - free a profile 638 * free_profile - free a profile
717 * @profile: the profile to free (MAYBE NULL) 639 * @profile: the profile to free (MAYBE NULL)
718 * 640 *
@@ -749,7 +671,6 @@ static void free_profile(struct aa_profile *profile)
749 aa_free_cap_rules(&profile->caps); 671 aa_free_cap_rules(&profile->caps);
750 aa_free_rlimit_rules(&profile->rlimits); 672 aa_free_rlimit_rules(&profile->rlimits);
751 673
752 aa_free_sid(profile->sid);
753 aa_put_dfa(profile->xmatch); 674 aa_put_dfa(profile->xmatch);
754 aa_put_dfa(profile->policy.dfa); 675 aa_put_dfa(profile->policy.dfa);
755 676
@@ -790,6 +711,81 @@ void aa_free_profile_kref(struct kref *kref)
790 free_profile(p); 711 free_profile(p);
791} 712}
792 713
714/**
715 * aa_alloc_profile - allocate, initialize and return a new profile
716 * @hname: name of the profile (NOT NULL)
717 *
718 * Returns: refcount profile or NULL on failure
719 */
720struct aa_profile *aa_alloc_profile(const char *hname)
721{
722 struct aa_profile *profile;
723
724 /* freed by free_profile - usually through aa_put_profile */
725 profile = kzalloc(sizeof(*profile), GFP_KERNEL);
726 if (!profile)
727 return NULL;
728
729 if (!policy_init(&profile->base, NULL, hname)) {
730 kzfree(profile);
731 return NULL;
732 }
733
734 /* refcount released by caller */
735 return profile;
736}
737
738/**
739 * aa_new_null_profile - create a new null-X learning profile
740 * @parent: profile that caused this profile to be created (NOT NULL)
741 * @hat: true if the null- learning profile is a hat
742 *
743 * Create a null- complain mode profile used in learning mode. The name of
744 * the profile is unique and follows the format of parent//null-<uniq>.
745 *
746 * null profiles are added to the profile list but the list does not
747 * hold a count on them so that they are automatically released when
748 * not in use.
749 *
750 * Returns: new refcounted profile else NULL on failure
751 */
752struct aa_profile *aa_new_null_profile(struct aa_profile *parent, int hat)
753{
754 struct aa_profile *profile = NULL;
755 char *name;
756 int uniq = atomic_inc_return(&parent->ns->uniq_null);
757
758 /* freed below */
759 name = kmalloc(strlen(parent->base.hname) + 2 + 7 + 8, GFP_KERNEL);
760 if (!name)
761 goto fail;
762 sprintf(name, "%s//null-%x", parent->base.hname, uniq);
763
764 profile = aa_alloc_profile(name);
765 kfree(name);
766 if (!profile)
767 goto fail;
768
769 profile->mode = APPARMOR_COMPLAIN;
770 profile->flags = PFLAG_NULL;
771 if (hat)
772 profile->flags |= PFLAG_HAT;
773
774 /* released on free_profile */
775 profile->parent = aa_get_profile(parent);
776 profile->ns = aa_get_namespace(parent->ns);
777
778 write_lock(&profile->ns->lock);
779 __list_add_profile(&parent->base.profiles, profile);
780 write_unlock(&profile->ns->lock);
781
782 /* refcount released by caller */
783 return profile;
784
785fail:
786 return NULL;
787}
788
793/* TODO: profile accounting - setup in remove */ 789/* TODO: profile accounting - setup in remove */
794 790
795/** 791/**
@@ -972,7 +968,6 @@ static void __add_new_profile(struct aa_namespace *ns, struct aa_policy *policy,
972 profile->parent = aa_get_profile((struct aa_profile *) policy); 968 profile->parent = aa_get_profile((struct aa_profile *) policy);
973 __list_add_profile(&policy->profiles, profile); 969 __list_add_profile(&policy->profiles, profile);
974 /* released on free_profile */ 970 /* released on free_profile */
975 profile->sid = aa_alloc_sid();
976 profile->ns = aa_get_namespace(ns); 971 profile->ns = aa_get_namespace(ns);
977} 972}
978 973
@@ -1110,14 +1105,8 @@ audit:
1110 if (!error) { 1105 if (!error) {
1111 if (rename_profile) 1106 if (rename_profile)
1112 __replace_profile(rename_profile, new_profile); 1107 __replace_profile(rename_profile, new_profile);
1113 if (old_profile) { 1108 if (old_profile)
1114 /* when there are both rename and old profiles
1115 * inherit old profiles sid
1116 */
1117 if (rename_profile)
1118 aa_free_sid(new_profile->sid);
1119 __replace_profile(old_profile, new_profile); 1109 __replace_profile(old_profile, new_profile);
1120 }
1121 if (!(old_profile || rename_profile)) 1110 if (!(old_profile || rename_profile))
1122 __add_new_profile(ns, policy, new_profile); 1111 __add_new_profile(ns, policy, new_profile);
1123 } 1112 }
@@ -1167,14 +1156,12 @@ ssize_t aa_remove_profiles(char *fqname, size_t size)
1167 if (fqname[0] == ':') { 1156 if (fqname[0] == ':') {
1168 char *ns_name; 1157 char *ns_name;
1169 name = aa_split_fqname(fqname, &ns_name); 1158 name = aa_split_fqname(fqname, &ns_name);
1170 if (ns_name) { 1159 /* released below */
1171 /* released below */ 1160 ns = aa_find_namespace(root, ns_name);
1172 ns = aa_find_namespace(root, ns_name); 1161 if (!ns) {
1173 if (!ns) { 1162 info = "namespace does not exist";
1174 info = "namespace does not exist"; 1163 error = -ENOENT;
1175 error = -ENOENT; 1164 goto fail;
1176 goto fail;
1177 }
1178 } 1165 }
1179 } else 1166 } else
1180 /* released below */ 1167 /* released below */
diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
index 329b1fd30749..6dac7d77cb4d 100644
--- a/security/apparmor/policy_unpack.c
+++ b/security/apparmor/policy_unpack.c
@@ -27,7 +27,6 @@
27#include "include/match.h" 27#include "include/match.h"
28#include "include/policy.h" 28#include "include/policy.h"
29#include "include/policy_unpack.h" 29#include "include/policy_unpack.h"
30#include "include/sid.h"
31 30
32/* 31/*
33 * The AppArmor interface treats data as a type byte followed by the 32 * The AppArmor interface treats data as a type byte followed by the
@@ -290,6 +289,9 @@ static int unpack_strdup(struct aa_ext *e, char **string, const char *name)
290 return res; 289 return res;
291} 290}
292 291
292#define DFA_VALID_PERM_MASK 0xffffffff
293#define DFA_VALID_PERM2_MASK 0xffffffff
294
293/** 295/**
294 * verify_accept - verify the accept tables of a dfa 296 * verify_accept - verify the accept tables of a dfa
295 * @dfa: dfa to verify accept tables of (NOT NULL) 297 * @dfa: dfa to verify accept tables of (NOT NULL)
diff --git a/security/apparmor/procattr.c b/security/apparmor/procattr.c
index 1b41c542d376..6c9390179b89 100644
--- a/security/apparmor/procattr.c
+++ b/security/apparmor/procattr.c
@@ -163,9 +163,3 @@ int aa_setprocattr_changeprofile(char *fqname, bool onexec, int test)
163 name = aa_split_fqname(fqname, &ns_name); 163 name = aa_split_fqname(fqname, &ns_name);
164 return aa_change_profile(ns_name, name, onexec, test); 164 return aa_change_profile(ns_name, name, onexec, test);
165} 165}
166
167int aa_setprocattr_permipc(char *fqname)
168{
169 /* TODO: add ipc permission querying */
170 return -ENOTSUPP;
171}
diff --git a/security/apparmor/resource.c b/security/apparmor/resource.c
index e1f3d7ef2c54..748bf0ca6c9f 100644
--- a/security/apparmor/resource.c
+++ b/security/apparmor/resource.c
@@ -15,6 +15,7 @@
15#include <linux/audit.h> 15#include <linux/audit.h>
16 16
17#include "include/audit.h" 17#include "include/audit.h"
18#include "include/context.h"
18#include "include/resource.h" 19#include "include/resource.h"
19#include "include/policy.h" 20#include "include/policy.h"
20 21
@@ -90,17 +91,25 @@ int aa_map_resource(int resource)
90int aa_task_setrlimit(struct aa_profile *profile, struct task_struct *task, 91int aa_task_setrlimit(struct aa_profile *profile, struct task_struct *task,
91 unsigned int resource, struct rlimit *new_rlim) 92 unsigned int resource, struct rlimit *new_rlim)
92{ 93{
94 struct aa_profile *task_profile;
93 int error = 0; 95 int error = 0;
94 96
97 rcu_read_lock();
98 task_profile = aa_get_profile(aa_cred_profile(__task_cred(task)));
99 rcu_read_unlock();
100
95 /* TODO: extend resource control to handle other (non current) 101 /* TODO: extend resource control to handle other (non current)
96 * processes. AppArmor rules currently have the implicit assumption 102 * profiles. AppArmor rules currently have the implicit assumption
97 * that the task is setting the resource of the current process 103 * that the task is setting the resource of a task confined with
104 * the same profile.
98 */ 105 */
99 if ((task != current->group_leader) || 106 if (profile != task_profile ||
100 (profile->rlimits.mask & (1 << resource) && 107 (profile->rlimits.mask & (1 << resource) &&
101 new_rlim->rlim_max > profile->rlimits.limits[resource].rlim_max)) 108 new_rlim->rlim_max > profile->rlimits.limits[resource].rlim_max))
102 error = -EACCES; 109 error = -EACCES;
103 110
111 aa_put_profile(task_profile);
112
104 return audit_resource(profile, resource, new_rlim->rlim_max, error); 113 return audit_resource(profile, resource, new_rlim->rlim_max, error);
105} 114}
106 115
diff --git a/security/capability.c b/security/capability.c
index 1728d4e375db..32b515766df1 100644
--- a/security/capability.c
+++ b/security/capability.c
@@ -91,7 +91,10 @@ static int cap_sb_pivotroot(struct path *old_path, struct path *new_path)
91} 91}
92 92
93static int cap_sb_set_mnt_opts(struct super_block *sb, 93static int cap_sb_set_mnt_opts(struct super_block *sb,
94 struct security_mnt_opts *opts) 94 struct security_mnt_opts *opts,
95 unsigned long kern_flags,
96 unsigned long *set_kern_flags)
97
95{ 98{
96 if (unlikely(opts->num_mnt_opts)) 99 if (unlikely(opts->num_mnt_opts))
97 return -EOPNOTSUPP; 100 return -EOPNOTSUPP;
@@ -109,6 +112,13 @@ static int cap_sb_parse_opts_str(char *options, struct security_mnt_opts *opts)
109 return 0; 112 return 0;
110} 113}
111 114
115static int cap_dentry_init_security(struct dentry *dentry, int mode,
116 struct qstr *name, void **ctx,
117 u32 *ctxlen)
118{
119 return 0;
120}
121
112static int cap_inode_alloc_security(struct inode *inode) 122static int cap_inode_alloc_security(struct inode *inode)
113{ 123{
114 return 0; 124 return 0;
@@ -816,6 +826,11 @@ static int cap_setprocattr(struct task_struct *p, char *name, void *value,
816 return -EINVAL; 826 return -EINVAL;
817} 827}
818 828
829static int cap_ismaclabel(const char *name)
830{
831 return 0;
832}
833
819static int cap_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) 834static int cap_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
820{ 835{
821 return -EOPNOTSUPP; 836 return -EOPNOTSUPP;
@@ -843,7 +858,7 @@ static int cap_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
843 858
844static int cap_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen) 859static int cap_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
845{ 860{
846 return 0; 861 return -EOPNOTSUPP;
847} 862}
848#ifdef CONFIG_KEYS 863#ifdef CONFIG_KEYS
849static int cap_key_alloc(struct key *key, const struct cred *cred, 864static int cap_key_alloc(struct key *key, const struct cred *cred,
@@ -931,6 +946,7 @@ void __init security_fixup_ops(struct security_operations *ops)
931 set_to_cap_if_null(ops, sb_set_mnt_opts); 946 set_to_cap_if_null(ops, sb_set_mnt_opts);
932 set_to_cap_if_null(ops, sb_clone_mnt_opts); 947 set_to_cap_if_null(ops, sb_clone_mnt_opts);
933 set_to_cap_if_null(ops, sb_parse_opts_str); 948 set_to_cap_if_null(ops, sb_parse_opts_str);
949 set_to_cap_if_null(ops, dentry_init_security);
934 set_to_cap_if_null(ops, inode_alloc_security); 950 set_to_cap_if_null(ops, inode_alloc_security);
935 set_to_cap_if_null(ops, inode_free_security); 951 set_to_cap_if_null(ops, inode_free_security);
936 set_to_cap_if_null(ops, inode_init_security); 952 set_to_cap_if_null(ops, inode_init_security);
@@ -1034,6 +1050,7 @@ void __init security_fixup_ops(struct security_operations *ops)
1034 set_to_cap_if_null(ops, d_instantiate); 1050 set_to_cap_if_null(ops, d_instantiate);
1035 set_to_cap_if_null(ops, getprocattr); 1051 set_to_cap_if_null(ops, getprocattr);
1036 set_to_cap_if_null(ops, setprocattr); 1052 set_to_cap_if_null(ops, setprocattr);
1053 set_to_cap_if_null(ops, ismaclabel);
1037 set_to_cap_if_null(ops, secid_to_secctx); 1054 set_to_cap_if_null(ops, secid_to_secctx);
1038 set_to_cap_if_null(ops, secctx_to_secid); 1055 set_to_cap_if_null(ops, secctx_to_secid);
1039 set_to_cap_if_null(ops, release_secctx); 1056 set_to_cap_if_null(ops, release_secctx);
diff --git a/security/device_cgroup.c b/security/device_cgroup.c
index dd0dc574d78d..e8aad69f0d69 100644
--- a/security/device_cgroup.c
+++ b/security/device_cgroup.c
@@ -49,8 +49,6 @@ struct dev_cgroup {
49 struct cgroup_subsys_state css; 49 struct cgroup_subsys_state css;
50 struct list_head exceptions; 50 struct list_head exceptions;
51 enum devcg_behavior behavior; 51 enum devcg_behavior behavior;
52 /* temporary list for pending propagation operations */
53 struct list_head propagate_pending;
54}; 52};
55 53
56static inline struct dev_cgroup *css_to_devcgroup(struct cgroup_subsys_state *s) 54static inline struct dev_cgroup *css_to_devcgroup(struct cgroup_subsys_state *s)
@@ -241,7 +239,6 @@ static struct cgroup_subsys_state *devcgroup_css_alloc(struct cgroup *cgroup)
241 if (!dev_cgroup) 239 if (!dev_cgroup)
242 return ERR_PTR(-ENOMEM); 240 return ERR_PTR(-ENOMEM);
243 INIT_LIST_HEAD(&dev_cgroup->exceptions); 241 INIT_LIST_HEAD(&dev_cgroup->exceptions);
244 INIT_LIST_HEAD(&dev_cgroup->propagate_pending);
245 dev_cgroup->behavior = DEVCG_DEFAULT_NONE; 242 dev_cgroup->behavior = DEVCG_DEFAULT_NONE;
246 243
247 return &dev_cgroup->css; 244 return &dev_cgroup->css;
@@ -445,34 +442,6 @@ static void revalidate_active_exceptions(struct dev_cgroup *devcg)
445} 442}
446 443
447/** 444/**
448 * get_online_devcg - walks the cgroup tree and fills a list with the online
449 * groups
450 * @root: cgroup used as starting point
451 * @online: list that will be filled with online groups
452 *
453 * Must be called with devcgroup_mutex held. Grabs RCU lock.
454 * Because devcgroup_mutex is held, no devcg will become online or offline
455 * during the tree walk (see devcgroup_online, devcgroup_offline)
456 * A separated list is needed because propagate_behavior() and
457 * propagate_exception() need to allocate memory and can block.
458 */
459static void get_online_devcg(struct cgroup *root, struct list_head *online)
460{
461 struct cgroup *pos;
462 struct dev_cgroup *devcg;
463
464 lockdep_assert_held(&devcgroup_mutex);
465
466 rcu_read_lock();
467 cgroup_for_each_descendant_pre(pos, root) {
468 devcg = cgroup_to_devcgroup(pos);
469 if (is_devcg_online(devcg))
470 list_add_tail(&devcg->propagate_pending, online);
471 }
472 rcu_read_unlock();
473}
474
475/**
476 * propagate_exception - propagates a new exception to the children 445 * propagate_exception - propagates a new exception to the children
477 * @devcg_root: device cgroup that added a new exception 446 * @devcg_root: device cgroup that added a new exception
478 * @ex: new exception to be propagated 447 * @ex: new exception to be propagated
@@ -482,15 +451,24 @@ static void get_online_devcg(struct cgroup *root, struct list_head *online)
482static int propagate_exception(struct dev_cgroup *devcg_root, 451static int propagate_exception(struct dev_cgroup *devcg_root,
483 struct dev_exception_item *ex) 452 struct dev_exception_item *ex)
484{ 453{
485 struct cgroup *root = devcg_root->css.cgroup; 454 struct cgroup *root = devcg_root->css.cgroup, *pos;
486 struct dev_cgroup *devcg, *parent, *tmp;
487 int rc = 0; 455 int rc = 0;
488 LIST_HEAD(pending);
489 456
490 get_online_devcg(root, &pending); 457 rcu_read_lock();
491 458
492 list_for_each_entry_safe(devcg, tmp, &pending, propagate_pending) { 459 cgroup_for_each_descendant_pre(pos, root) {
493 parent = cgroup_to_devcgroup(devcg->css.cgroup->parent); 460 struct dev_cgroup *devcg = cgroup_to_devcgroup(pos);
461
462 /*
463 * Because devcgroup_mutex is held, no devcg will become
464 * online or offline during the tree walk (see on/offline
465 * methods), and online ones are safe to access outside RCU
466 * read lock without bumping refcnt.
467 */
468 if (!is_devcg_online(devcg))
469 continue;
470
471 rcu_read_unlock();
494 472
495 /* 473 /*
496 * in case both root's behavior and devcg is allow, a new 474 * in case both root's behavior and devcg is allow, a new
@@ -512,8 +490,10 @@ static int propagate_exception(struct dev_cgroup *devcg_root,
512 } 490 }
513 revalidate_active_exceptions(devcg); 491 revalidate_active_exceptions(devcg);
514 492
515 list_del_init(&devcg->propagate_pending); 493 rcu_read_lock();
516 } 494 }
495
496 rcu_read_unlock();
517 return rc; 497 return rc;
518} 498}
519 499
diff --git a/security/integrity/Kconfig b/security/integrity/Kconfig
index 4bb3a775a996..245c6d92065b 100644
--- a/security/integrity/Kconfig
+++ b/security/integrity/Kconfig
@@ -17,6 +17,21 @@ config INTEGRITY_SIGNATURE
17 This is useful for evm and module keyrings, when keys are 17 This is useful for evm and module keyrings, when keys are
18 usually only added from initramfs. 18 usually only added from initramfs.
19 19
20config INTEGRITY_AUDIT
21 bool "Enables integrity auditing support "
22 depends on INTEGRITY && AUDIT
23 default y
24 help
25 In addition to enabling integrity auditing support, this
26 option adds a kernel parameter 'integrity_audit', which
27 controls the level of integrity auditing messages.
28 0 - basic integrity auditing messages (default)
29 1 - additional integrity auditing messages
30
31 Additional informational integrity auditing messages would
32 be enabled by specifying 'integrity_audit=1' on the kernel
33 command line.
34
20config INTEGRITY_ASYMMETRIC_KEYS 35config INTEGRITY_ASYMMETRIC_KEYS
21 boolean "Enable asymmetric keys support" 36 boolean "Enable asymmetric keys support"
22 depends on INTEGRITY_SIGNATURE 37 depends on INTEGRITY_SIGNATURE
diff --git a/security/integrity/Makefile b/security/integrity/Makefile
index ebb6409b3fcb..0f9cffb1f9ad 100644
--- a/security/integrity/Makefile
+++ b/security/integrity/Makefile
@@ -3,6 +3,7 @@
3# 3#
4 4
5obj-$(CONFIG_INTEGRITY) += integrity.o 5obj-$(CONFIG_INTEGRITY) += integrity.o
6obj-$(CONFIG_INTEGRITY_AUDIT) += integrity_audit.o
6obj-$(CONFIG_INTEGRITY_SIGNATURE) += digsig.o 7obj-$(CONFIG_INTEGRITY_SIGNATURE) += digsig.o
7obj-$(CONFIG_INTEGRITY_ASYMMETRIC_KEYS) += digsig_asymmetric.o 8obj-$(CONFIG_INTEGRITY_ASYMMETRIC_KEYS) += digsig_asymmetric.o
8 9
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
index cdbde1762189..df0fa451a871 100644
--- a/security/integrity/evm/evm_main.c
+++ b/security/integrity/evm/evm_main.c
@@ -16,6 +16,7 @@
16 16
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/crypto.h> 18#include <linux/crypto.h>
19#include <linux/audit.h>
19#include <linux/xattr.h> 20#include <linux/xattr.h>
20#include <linux/integrity.h> 21#include <linux/integrity.h>
21#include <linux/evm.h> 22#include <linux/evm.h>
@@ -24,6 +25,9 @@
24 25
25int evm_initialized; 26int evm_initialized;
26 27
28static char *integrity_status_msg[] = {
29 "pass", "fail", "no_label", "no_xattrs", "unknown"
30};
27char *evm_hmac = "hmac(sha1)"; 31char *evm_hmac = "hmac(sha1)";
28char *evm_hash = "sha1"; 32char *evm_hash = "sha1";
29int evm_hmac_version = CONFIG_EVM_HMAC_VERSION; 33int evm_hmac_version = CONFIG_EVM_HMAC_VERSION;
@@ -262,9 +266,15 @@ static int evm_protect_xattr(struct dentry *dentry, const char *xattr_name,
262 if ((evm_status == INTEGRITY_PASS) || 266 if ((evm_status == INTEGRITY_PASS) ||
263 (evm_status == INTEGRITY_NOXATTRS)) 267 (evm_status == INTEGRITY_NOXATTRS))
264 return 0; 268 return 0;
265 return -EPERM; 269 goto out;
266 } 270 }
267 evm_status = evm_verify_current_integrity(dentry); 271 evm_status = evm_verify_current_integrity(dentry);
272out:
273 if (evm_status != INTEGRITY_PASS)
274 integrity_audit_msg(AUDIT_INTEGRITY_METADATA, dentry->d_inode,
275 dentry->d_name.name, "appraise_metadata",
276 integrity_status_msg[evm_status],
277 -EPERM, 0);
268 return evm_status == INTEGRITY_PASS ? 0 : -EPERM; 278 return evm_status == INTEGRITY_PASS ? 0 : -EPERM;
269} 279}
270 280
@@ -357,6 +367,9 @@ int evm_inode_setattr(struct dentry *dentry, struct iattr *attr)
357 if ((evm_status == INTEGRITY_PASS) || 367 if ((evm_status == INTEGRITY_PASS) ||
358 (evm_status == INTEGRITY_NOXATTRS)) 368 (evm_status == INTEGRITY_NOXATTRS))
359 return 0; 369 return 0;
370 integrity_audit_msg(AUDIT_INTEGRITY_METADATA, dentry->d_inode,
371 dentry->d_name.name, "appraise_metadata",
372 integrity_status_msg[evm_status], -EPERM, 0);
360 return -EPERM; 373 return -EPERM;
361} 374}
362 375
diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
index d232c73647ae..39196abaff0d 100644
--- a/security/integrity/ima/Kconfig
+++ b/security/integrity/ima/Kconfig
@@ -38,18 +38,6 @@ config IMA_MEASURE_PCR_IDX
38 that IMA uses to maintain the integrity aggregate of the 38 that IMA uses to maintain the integrity aggregate of the
39 measurement list. If unsure, use the default 10. 39 measurement list. If unsure, use the default 10.
40 40
41config IMA_AUDIT
42 bool "Enables auditing support"
43 depends on IMA
44 depends on AUDIT
45 default y
46 help
47 This option adds a kernel parameter 'ima_audit', which
48 allows informational auditing messages to be enabled
49 at boot. If this option is selected, informational integrity
50 auditing messages can be enabled with 'ima_audit=1' on
51 the kernel command line.
52
53config IMA_LSM_RULES 41config IMA_LSM_RULES
54 bool 42 bool
55 depends on IMA && AUDIT && (SECURITY_SELINUX || SECURITY_SMACK) 43 depends on IMA && AUDIT && (SECURITY_SELINUX || SECURITY_SMACK)
diff --git a/security/integrity/ima/Makefile b/security/integrity/ima/Makefile
index 3f2ca6bdc384..56dfee7cbf61 100644
--- a/security/integrity/ima/Makefile
+++ b/security/integrity/ima/Makefile
@@ -7,5 +7,4 @@ obj-$(CONFIG_IMA) += ima.o
7 7
8ima-y := ima_fs.o ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o \ 8ima-y := ima_fs.o ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o \
9 ima_policy.o 9 ima_policy.o
10ima-$(CONFIG_IMA_AUDIT) += ima_audit.o
11ima-$(CONFIG_IMA_APPRAISE) += ima_appraise.o 10ima-$(CONFIG_IMA_APPRAISE) += ima_appraise.o
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index a41c9c18e5e0..b3dd616560f7 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -62,20 +62,6 @@ struct ima_queue_entry {
62}; 62};
63extern struct list_head ima_measurements; /* list of all measurements */ 63extern struct list_head ima_measurements; /* list of all measurements */
64 64
65#ifdef CONFIG_IMA_AUDIT
66/* declarations */
67void integrity_audit_msg(int audit_msgno, struct inode *inode,
68 const unsigned char *fname, const char *op,
69 const char *cause, int result, int info);
70#else
71static inline void integrity_audit_msg(int audit_msgno, struct inode *inode,
72 const unsigned char *fname,
73 const char *op, const char *cause,
74 int result, int info)
75{
76}
77#endif
78
79/* Internal IMA function definitions */ 65/* Internal IMA function definitions */
80int ima_init(void); 66int ima_init(void);
81void ima_cleanup(void); 67void ima_cleanup(void);
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 6c491a63128e..e9508d5bbfcf 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -57,7 +57,7 @@ __setup("ima_hash=", hash_setup);
57static void ima_rdwr_violation_check(struct file *file) 57static void ima_rdwr_violation_check(struct file *file)
58{ 58{
59 struct dentry *dentry = file->f_path.dentry; 59 struct dentry *dentry = file->f_path.dentry;
60 struct inode *inode = dentry->d_inode; 60 struct inode *inode = file_inode(file);
61 fmode_t mode = file->f_mode; 61 fmode_t mode = file->f_mode;
62 int must_measure; 62 int must_measure;
63 bool send_tomtou = false, send_writers = false; 63 bool send_tomtou = false, send_writers = false;
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index 84c37c4db914..c42fb7a70dee 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -113,5 +113,19 @@ static inline int asymmetric_verify(struct key *keyring, const char *sig,
113} 113}
114#endif 114#endif
115 115
116#ifdef CONFIG_INTEGRITY_AUDIT
117/* declarations */
118void integrity_audit_msg(int audit_msgno, struct inode *inode,
119 const unsigned char *fname, const char *op,
120 const char *cause, int result, int info);
121#else
122static inline void integrity_audit_msg(int audit_msgno, struct inode *inode,
123 const unsigned char *fname,
124 const char *op, const char *cause,
125 int result, int info)
126{
127}
128#endif
129
116/* set during initialization */ 130/* set during initialization */
117extern int iint_initialized; 131extern int iint_initialized;
diff --git a/security/integrity/ima/ima_audit.c b/security/integrity/integrity_audit.c
index c586faae8fd6..d7efb30404aa 100644
--- a/security/integrity/ima/ima_audit.c
+++ b/security/integrity/integrity_audit.c
@@ -13,20 +13,20 @@
13#include <linux/fs.h> 13#include <linux/fs.h>
14#include <linux/gfp.h> 14#include <linux/gfp.h>
15#include <linux/audit.h> 15#include <linux/audit.h>
16#include "ima.h" 16#include "integrity.h"
17 17
18static int ima_audit; 18static int integrity_audit_info;
19 19
20/* ima_audit_setup - enable informational auditing messages */ 20/* ima_audit_setup - enable informational auditing messages */
21static int __init ima_audit_setup(char *str) 21static int __init integrity_audit_setup(char *str)
22{ 22{
23 unsigned long audit; 23 unsigned long audit;
24 24
25 if (!strict_strtoul(str, 0, &audit)) 25 if (!strict_strtoul(str, 0, &audit))
26 ima_audit = audit ? 1 : 0; 26 integrity_audit_info = audit ? 1 : 0;
27 return 1; 27 return 1;
28} 28}
29__setup("ima_audit=", ima_audit_setup); 29__setup("integrity_audit=", integrity_audit_setup);
30 30
31void integrity_audit_msg(int audit_msgno, struct inode *inode, 31void integrity_audit_msg(int audit_msgno, struct inode *inode,
32 const unsigned char *fname, const char *op, 32 const unsigned char *fname, const char *op,
@@ -34,7 +34,7 @@ void integrity_audit_msg(int audit_msgno, struct inode *inode,
34{ 34{
35 struct audit_buffer *ab; 35 struct audit_buffer *ab;
36 36
37 if (!ima_audit && audit_info == 1) /* Skip informational messages */ 37 if (!integrity_audit_info && audit_info == 1) /* Skip info messages */
38 return; 38 return;
39 39
40 ab = audit_log_start(current->audit_context, GFP_KERNEL, audit_msgno); 40 ab = audit_log_start(current->audit_context, GFP_KERNEL, audit_msgno);
diff --git a/security/security.c b/security/security.c
index a3dce87d1aef..94b35aef6871 100644
--- a/security/security.c
+++ b/security/security.c
@@ -12,6 +12,7 @@
12 */ 12 */
13 13
14#include <linux/capability.h> 14#include <linux/capability.h>
15#include <linux/dcache.h>
15#include <linux/module.h> 16#include <linux/module.h>
16#include <linux/init.h> 17#include <linux/init.h>
17#include <linux/kernel.h> 18#include <linux/kernel.h>
@@ -293,9 +294,12 @@ int security_sb_pivotroot(struct path *old_path, struct path *new_path)
293} 294}
294 295
295int security_sb_set_mnt_opts(struct super_block *sb, 296int security_sb_set_mnt_opts(struct super_block *sb,
296 struct security_mnt_opts *opts) 297 struct security_mnt_opts *opts,
298 unsigned long kern_flags,
299 unsigned long *set_kern_flags)
297{ 300{
298 return security_ops->sb_set_mnt_opts(sb, opts); 301 return security_ops->sb_set_mnt_opts(sb, opts, kern_flags,
302 set_kern_flags);
299} 303}
300EXPORT_SYMBOL(security_sb_set_mnt_opts); 304EXPORT_SYMBOL(security_sb_set_mnt_opts);
301 305
@@ -324,6 +328,15 @@ void security_inode_free(struct inode *inode)
324 security_ops->inode_free_security(inode); 328 security_ops->inode_free_security(inode);
325} 329}
326 330
331int security_dentry_init_security(struct dentry *dentry, int mode,
332 struct qstr *name, void **ctx,
333 u32 *ctxlen)
334{
335 return security_ops->dentry_init_security(dentry, mode, name,
336 ctx, ctxlen);
337}
338EXPORT_SYMBOL(security_dentry_init_security);
339
327int security_inode_init_security(struct inode *inode, struct inode *dir, 340int security_inode_init_security(struct inode *inode, struct inode *dir,
328 const struct qstr *qstr, 341 const struct qstr *qstr,
329 const initxattrs initxattrs, void *fs_data) 342 const initxattrs initxattrs, void *fs_data)
@@ -647,6 +660,7 @@ int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer
647 return 0; 660 return 0;
648 return security_ops->inode_listsecurity(inode, buffer, buffer_size); 661 return security_ops->inode_listsecurity(inode, buffer, buffer_size);
649} 662}
663EXPORT_SYMBOL(security_inode_listsecurity);
650 664
651void security_inode_getsecid(const struct inode *inode, u32 *secid) 665void security_inode_getsecid(const struct inode *inode, u32 *secid)
652{ 666{
@@ -1047,6 +1061,12 @@ int security_netlink_send(struct sock *sk, struct sk_buff *skb)
1047 return security_ops->netlink_send(sk, skb); 1061 return security_ops->netlink_send(sk, skb);
1048} 1062}
1049 1063
1064int security_ismaclabel(const char *name)
1065{
1066 return security_ops->ismaclabel(name);
1067}
1068EXPORT_SYMBOL(security_ismaclabel);
1069
1050int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) 1070int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
1051{ 1071{
1052 return security_ops->secid_to_secctx(secid, secdata, seclen); 1072 return security_ops->secid_to_secctx(secid, secdata, seclen);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 5c6f2cd2d095..c956390a9136 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -81,6 +81,7 @@
81#include <linux/syslog.h> 81#include <linux/syslog.h>
82#include <linux/user_namespace.h> 82#include <linux/user_namespace.h>
83#include <linux/export.h> 83#include <linux/export.h>
84#include <linux/security.h>
84#include <linux/msg.h> 85#include <linux/msg.h>
85#include <linux/shm.h> 86#include <linux/shm.h>
86 87
@@ -284,13 +285,14 @@ static void superblock_free_security(struct super_block *sb)
284 285
285/* The file system's label must be initialized prior to use. */ 286/* The file system's label must be initialized prior to use. */
286 287
287static const char *labeling_behaviors[6] = { 288static const char *labeling_behaviors[7] = {
288 "uses xattr", 289 "uses xattr",
289 "uses transition SIDs", 290 "uses transition SIDs",
290 "uses task SIDs", 291 "uses task SIDs",
291 "uses genfs_contexts", 292 "uses genfs_contexts",
292 "not configured for labeling", 293 "not configured for labeling",
293 "uses mountpoint labeling", 294 "uses mountpoint labeling",
295 "uses native labeling",
294}; 296};
295 297
296static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry); 298static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry);
@@ -552,7 +554,9 @@ static int bad_option(struct superblock_security_struct *sbsec, char flag,
552 * labeling information. 554 * labeling information.
553 */ 555 */
554static int selinux_set_mnt_opts(struct super_block *sb, 556static int selinux_set_mnt_opts(struct super_block *sb,
555 struct security_mnt_opts *opts) 557 struct security_mnt_opts *opts,
558 unsigned long kern_flags,
559 unsigned long *set_kern_flags)
556{ 560{
557 const struct cred *cred = current_cred(); 561 const struct cred *cred = current_cred();
558 int rc = 0, i; 562 int rc = 0, i;
@@ -580,6 +584,12 @@ static int selinux_set_mnt_opts(struct super_block *sb,
580 "before the security server is initialized\n"); 584 "before the security server is initialized\n");
581 goto out; 585 goto out;
582 } 586 }
587 if (kern_flags && !set_kern_flags) {
588 /* Specifying internal flags without providing a place to
589 * place the results is not allowed */
590 rc = -EINVAL;
591 goto out;
592 }
583 593
584 /* 594 /*
585 * Binary mount data FS will come through this function twice. Once 595 * Binary mount data FS will come through this function twice. Once
@@ -670,14 +680,21 @@ static int selinux_set_mnt_opts(struct super_block *sb,
670 if (strcmp(sb->s_type->name, "proc") == 0) 680 if (strcmp(sb->s_type->name, "proc") == 0)
671 sbsec->flags |= SE_SBPROC; 681 sbsec->flags |= SE_SBPROC;
672 682
673 /* Determine the labeling behavior to use for this filesystem type. */ 683 if (!sbsec->behavior) {
674 rc = security_fs_use((sbsec->flags & SE_SBPROC) ? "proc" : sb->s_type->name, &sbsec->behavior, &sbsec->sid); 684 /*
675 if (rc) { 685 * Determine the labeling behavior to use for this
676 printk(KERN_WARNING "%s: security_fs_use(%s) returned %d\n", 686 * filesystem type.
677 __func__, sb->s_type->name, rc); 687 */
678 goto out; 688 rc = security_fs_use((sbsec->flags & SE_SBPROC) ?
689 "proc" : sb->s_type->name,
690 &sbsec->behavior, &sbsec->sid);
691 if (rc) {
692 printk(KERN_WARNING
693 "%s: security_fs_use(%s) returned %d\n",
694 __func__, sb->s_type->name, rc);
695 goto out;
696 }
679 } 697 }
680
681 /* sets the context of the superblock for the fs being mounted. */ 698 /* sets the context of the superblock for the fs being mounted. */
682 if (fscontext_sid) { 699 if (fscontext_sid) {
683 rc = may_context_mount_sb_relabel(fscontext_sid, sbsec, cred); 700 rc = may_context_mount_sb_relabel(fscontext_sid, sbsec, cred);
@@ -692,6 +709,11 @@ static int selinux_set_mnt_opts(struct super_block *sb,
692 * sets the label used on all file below the mountpoint, and will set 709 * sets the label used on all file below the mountpoint, and will set
693 * the superblock context if not already set. 710 * the superblock context if not already set.
694 */ 711 */
712 if (kern_flags & SECURITY_LSM_NATIVE_LABELS && !context_sid) {
713 sbsec->behavior = SECURITY_FS_USE_NATIVE;
714 *set_kern_flags |= SECURITY_LSM_NATIVE_LABELS;
715 }
716
695 if (context_sid) { 717 if (context_sid) {
696 if (!fscontext_sid) { 718 if (!fscontext_sid) {
697 rc = may_context_mount_sb_relabel(context_sid, sbsec, 719 rc = may_context_mount_sb_relabel(context_sid, sbsec,
@@ -723,7 +745,8 @@ static int selinux_set_mnt_opts(struct super_block *sb,
723 } 745 }
724 746
725 if (defcontext_sid) { 747 if (defcontext_sid) {
726 if (sbsec->behavior != SECURITY_FS_USE_XATTR) { 748 if (sbsec->behavior != SECURITY_FS_USE_XATTR &&
749 sbsec->behavior != SECURITY_FS_USE_NATIVE) {
727 rc = -EINVAL; 750 rc = -EINVAL;
728 printk(KERN_WARNING "SELinux: defcontext option is " 751 printk(KERN_WARNING "SELinux: defcontext option is "
729 "invalid for this filesystem type\n"); 752 "invalid for this filesystem type\n");
@@ -980,7 +1003,7 @@ static int superblock_doinit(struct super_block *sb, void *data)
980 goto out_err; 1003 goto out_err;
981 1004
982out: 1005out:
983 rc = selinux_set_mnt_opts(sb, &opts); 1006 rc = selinux_set_mnt_opts(sb, &opts, 0, NULL);
984 1007
985out_err: 1008out_err:
986 security_free_mnt_opts(&opts); 1009 security_free_mnt_opts(&opts);
@@ -1222,6 +1245,8 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
1222 } 1245 }
1223 1246
1224 switch (sbsec->behavior) { 1247 switch (sbsec->behavior) {
1248 case SECURITY_FS_USE_NATIVE:
1249 break;
1225 case SECURITY_FS_USE_XATTR: 1250 case SECURITY_FS_USE_XATTR:
1226 if (!inode->i_op->getxattr) { 1251 if (!inode->i_op->getxattr) {
1227 isec->sid = sbsec->def_sid; 1252 isec->sid = sbsec->def_sid;
@@ -1547,6 +1572,18 @@ static inline int path_has_perm(const struct cred *cred,
1547 return inode_has_perm(cred, inode, av, &ad, 0); 1572 return inode_has_perm(cred, inode, av, &ad, 0);
1548} 1573}
1549 1574
1575/* Same as path_has_perm, but uses the inode from the file struct. */
1576static inline int file_path_has_perm(const struct cred *cred,
1577 struct file *file,
1578 u32 av)
1579{
1580 struct common_audit_data ad;
1581
1582 ad.type = LSM_AUDIT_DATA_PATH;
1583 ad.u.path = file->f_path;
1584 return inode_has_perm(cred, file_inode(file), av, &ad, 0);
1585}
1586
1550/* Check whether a task can use an open file descriptor to 1587/* Check whether a task can use an open file descriptor to
1551 access an inode in a given way. Check access to the 1588 access an inode in a given way. Check access to the
1552 descriptor itself, and then use dentry_has_perm to 1589 descriptor itself, and then use dentry_has_perm to
@@ -2141,14 +2178,14 @@ static inline void flush_unauthorized_files(const struct cred *cred,
2141 struct tty_file_private *file_priv; 2178 struct tty_file_private *file_priv;
2142 2179
2143 /* Revalidate access to controlling tty. 2180 /* Revalidate access to controlling tty.
2144 Use path_has_perm on the tty path directly rather 2181 Use file_path_has_perm on the tty path directly
2145 than using file_has_perm, as this particular open 2182 rather than using file_has_perm, as this particular
2146 file may belong to another process and we are only 2183 open file may belong to another process and we are
2147 interested in the inode-based check here. */ 2184 only interested in the inode-based check here. */
2148 file_priv = list_first_entry(&tty->tty_files, 2185 file_priv = list_first_entry(&tty->tty_files,
2149 struct tty_file_private, list); 2186 struct tty_file_private, list);
2150 file = file_priv->file; 2187 file = file_priv->file;
2151 if (path_has_perm(cred, &file->f_path, FILE__READ | FILE__WRITE)) 2188 if (file_path_has_perm(cred, file, FILE__READ | FILE__WRITE))
2152 drop_tty = 1; 2189 drop_tty = 1;
2153 } 2190 }
2154 spin_unlock(&tty_files_lock); 2191 spin_unlock(&tty_files_lock);
@@ -2515,6 +2552,40 @@ static void selinux_inode_free_security(struct inode *inode)
2515 inode_free_security(inode); 2552 inode_free_security(inode);
2516} 2553}
2517 2554
2555static int selinux_dentry_init_security(struct dentry *dentry, int mode,
2556 struct qstr *name, void **ctx,
2557 u32 *ctxlen)
2558{
2559 const struct cred *cred = current_cred();
2560 struct task_security_struct *tsec;
2561 struct inode_security_struct *dsec;
2562 struct superblock_security_struct *sbsec;
2563 struct inode *dir = dentry->d_parent->d_inode;
2564 u32 newsid;
2565 int rc;
2566
2567 tsec = cred->security;
2568 dsec = dir->i_security;
2569 sbsec = dir->i_sb->s_security;
2570
2571 if (tsec->create_sid && sbsec->behavior != SECURITY_FS_USE_MNTPOINT) {
2572 newsid = tsec->create_sid;
2573 } else {
2574 rc = security_transition_sid(tsec->sid, dsec->sid,
2575 inode_mode_to_security_class(mode),
2576 name,
2577 &newsid);
2578 if (rc) {
2579 printk(KERN_WARNING
2580 "%s: security_transition_sid failed, rc=%d\n",
2581 __func__, -rc);
2582 return rc;
2583 }
2584 }
2585
2586 return security_sid_to_context(newsid, (char **)ctx, ctxlen);
2587}
2588
2518static int selinux_inode_init_security(struct inode *inode, struct inode *dir, 2589static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
2519 const struct qstr *qstr, char **name, 2590 const struct qstr *qstr, char **name,
2520 void **value, size_t *len) 2591 void **value, size_t *len)
@@ -2849,7 +2920,10 @@ static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name,
2849 return; 2920 return;
2850 } 2921 }
2851 2922
2923 isec->sclass = inode_mode_to_security_class(inode->i_mode);
2852 isec->sid = newsid; 2924 isec->sid = newsid;
2925 isec->initialized = 1;
2926
2853 return; 2927 return;
2854} 2928}
2855 2929
@@ -2937,6 +3011,7 @@ static int selinux_inode_setsecurity(struct inode *inode, const char *name,
2937 if (rc) 3011 if (rc)
2938 return rc; 3012 return rc;
2939 3013
3014 isec->sclass = inode_mode_to_security_class(inode->i_mode);
2940 isec->sid = newsid; 3015 isec->sid = newsid;
2941 isec->initialized = 1; 3016 isec->initialized = 1;
2942 return 0; 3017 return 0;
@@ -3259,7 +3334,7 @@ static int selinux_file_open(struct file *file, const struct cred *cred)
3259 * new inode label or new policy. 3334 * new inode label or new policy.
3260 * This check is not redundant - do not remove. 3335 * This check is not redundant - do not remove.
3261 */ 3336 */
3262 return path_has_perm(cred, &file->f_path, open_file_to_av(file)); 3337 return file_path_has_perm(cred, file, open_file_to_av(file));
3263} 3338}
3264 3339
3265/* task security operations */ 3340/* task security operations */
@@ -5420,6 +5495,11 @@ abort_change:
5420 return error; 5495 return error;
5421} 5496}
5422 5497
5498static int selinux_ismaclabel(const char *name)
5499{
5500 return (strcmp(name, XATTR_SELINUX_SUFFIX) == 0);
5501}
5502
5423static int selinux_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) 5503static int selinux_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
5424{ 5504{
5425 return security_sid_to_context(secid, secdata, seclen); 5505 return security_sid_to_context(secid, secdata, seclen);
@@ -5562,6 +5642,7 @@ static struct security_operations selinux_ops = {
5562 .sb_clone_mnt_opts = selinux_sb_clone_mnt_opts, 5642 .sb_clone_mnt_opts = selinux_sb_clone_mnt_opts,
5563 .sb_parse_opts_str = selinux_parse_opts_str, 5643 .sb_parse_opts_str = selinux_parse_opts_str,
5564 5644
5645 .dentry_init_security = selinux_dentry_init_security,
5565 5646
5566 .inode_alloc_security = selinux_inode_alloc_security, 5647 .inode_alloc_security = selinux_inode_alloc_security,
5567 .inode_free_security = selinux_inode_free_security, 5648 .inode_free_security = selinux_inode_free_security,
@@ -5657,6 +5738,7 @@ static struct security_operations selinux_ops = {
5657 .getprocattr = selinux_getprocattr, 5738 .getprocattr = selinux_getprocattr,
5658 .setprocattr = selinux_setprocattr, 5739 .setprocattr = selinux_setprocattr,
5659 5740
5741 .ismaclabel = selinux_ismaclabel,
5660 .secid_to_secctx = selinux_secid_to_secctx, 5742 .secid_to_secctx = selinux_secid_to_secctx,
5661 .secctx_to_secid = selinux_secctx_to_secid, 5743 .secctx_to_secid = selinux_secctx_to_secid,
5662 .release_secctx = selinux_release_secctx, 5744 .release_secctx = selinux_release_secctx,
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index 6d3885165d14..8fd8e18ea340 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -169,6 +169,8 @@ int security_get_allow_unknown(void);
169#define SECURITY_FS_USE_GENFS 4 /* use the genfs support */ 169#define SECURITY_FS_USE_GENFS 4 /* use the genfs support */
170#define SECURITY_FS_USE_NONE 5 /* no labeling support */ 170#define SECURITY_FS_USE_NONE 5 /* no labeling support */
171#define SECURITY_FS_USE_MNTPOINT 6 /* use mountpoint labeling */ 171#define SECURITY_FS_USE_MNTPOINT 6 /* use mountpoint labeling */
172#define SECURITY_FS_USE_NATIVE 7 /* use native label support */
173#define SECURITY_FS_USE_MAX 7 /* Highest SECURITY_FS_USE_XXX */
172 174
173int security_fs_use(const char *fstype, unsigned int *behavior, 175int security_fs_use(const char *fstype, unsigned int *behavior,
174 u32 *sid); 176 u32 *sid);
diff --git a/security/selinux/netif.c b/security/selinux/netif.c
index 47a49d1a6f6a..694e9e43855f 100644
--- a/security/selinux/netif.c
+++ b/security/selinux/netif.c
@@ -264,7 +264,7 @@ static int sel_netif_avc_callback(u32 event)
264static int sel_netif_netdev_notifier_handler(struct notifier_block *this, 264static int sel_netif_netdev_notifier_handler(struct notifier_block *this,
265 unsigned long event, void *ptr) 265 unsigned long event, void *ptr)
266{ 266{
267 struct net_device *dev = ptr; 267 struct net_device *dev = netdev_notifier_info_to_dev(ptr);
268 268
269 if (dev_net(dev) != &init_net) 269 if (dev_net(dev) != &init_net)
270 return NOTIFY_DONE; 270 return NOTIFY_DONE;
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index 9cd9b7c661ec..c8adde3aff8f 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -2168,7 +2168,10 @@ static int ocontext_read(struct policydb *p, struct policydb_compat_info *info,
2168 2168
2169 rc = -EINVAL; 2169 rc = -EINVAL;
2170 c->v.behavior = le32_to_cpu(buf[0]); 2170 c->v.behavior = le32_to_cpu(buf[0]);
2171 if (c->v.behavior > SECURITY_FS_USE_NONE) 2171 /* Determined at runtime, not in policy DB. */
2172 if (c->v.behavior == SECURITY_FS_USE_MNTPOINT)
2173 goto out;
2174 if (c->v.behavior > SECURITY_FS_USE_MAX)
2172 goto out; 2175 goto out;
2173 2176
2174 rc = -ENOMEM; 2177 rc = -ENOMEM;
diff --git a/security/smack/smack.h b/security/smack/smack.h
index 8ad30955e15d..339614c76e63 100644
--- a/security/smack/smack.h
+++ b/security/smack/smack.h
@@ -29,6 +29,38 @@
29#define SMK_LONGLABEL 256 29#define SMK_LONGLABEL 256
30 30
31/* 31/*
32 * This is the repository for labels seen so that it is
33 * not necessary to keep allocating tiny chuncks of memory
34 * and so that they can be shared.
35 *
36 * Labels are never modified in place. Anytime a label
37 * is imported (e.g. xattrset on a file) the list is checked
38 * for it and it is added if it doesn't exist. The address
39 * is passed out in either case. Entries are added, but
40 * never deleted.
41 *
42 * Since labels are hanging around anyway it doesn't
43 * hurt to maintain a secid for those awkward situations
44 * where kernel components that ought to use LSM independent
45 * interfaces don't. The secid should go away when all of
46 * these components have been repaired.
47 *
48 * The cipso value associated with the label gets stored here, too.
49 *
50 * Keep the access rules for this subject label here so that
51 * the entire set of rules does not need to be examined every
52 * time.
53 */
54struct smack_known {
55 struct list_head list;
56 char *smk_known;
57 u32 smk_secid;
58 struct netlbl_lsm_secattr smk_netlabel; /* on wire labels */
59 struct list_head smk_rules; /* access rules */
60 struct mutex smk_rules_lock; /* lock for rules */
61};
62
63/*
32 * Maximum number of bytes for the levels in a CIPSO IP option. 64 * Maximum number of bytes for the levels in a CIPSO IP option.
33 * Why 23? CIPSO is constrained to 30, so a 32 byte buffer is 65 * Why 23? CIPSO is constrained to 30, so a 32 byte buffer is
34 * bigger than can be used, and 24 is the next lower multiple 66 * bigger than can be used, and 24 is the next lower multiple
@@ -46,25 +78,25 @@ struct superblock_smack {
46}; 78};
47 79
48struct socket_smack { 80struct socket_smack {
49 char *smk_out; /* outbound label */ 81 struct smack_known *smk_out; /* outbound label */
50 char *smk_in; /* inbound label */ 82 char *smk_in; /* inbound label */
51 char *smk_packet; /* TCP peer label */ 83 char *smk_packet; /* TCP peer label */
52}; 84};
53 85
54/* 86/*
55 * Inode smack data 87 * Inode smack data
56 */ 88 */
57struct inode_smack { 89struct inode_smack {
58 char *smk_inode; /* label of the fso */ 90 char *smk_inode; /* label of the fso */
59 char *smk_task; /* label of the task */ 91 struct smack_known *smk_task; /* label of the task */
60 char *smk_mmap; /* label of the mmap domain */ 92 struct smack_known *smk_mmap; /* label of the mmap domain */
61 struct mutex smk_lock; /* initialization lock */ 93 struct mutex smk_lock; /* initialization lock */
62 int smk_flags; /* smack inode flags */ 94 int smk_flags; /* smack inode flags */
63}; 95};
64 96
65struct task_smack { 97struct task_smack {
66 char *smk_task; /* label for access control */ 98 struct smack_known *smk_task; /* label for access control */
67 char *smk_forked; /* label when forked */ 99 struct smack_known *smk_forked; /* label when forked */
68 struct list_head smk_rules; /* per task access rules */ 100 struct list_head smk_rules; /* per task access rules */
69 struct mutex smk_rules_lock; /* lock for the rules */ 101 struct mutex smk_rules_lock; /* lock for the rules */
70}; 102};
@@ -78,7 +110,7 @@ struct task_smack {
78 */ 110 */
79struct smack_rule { 111struct smack_rule {
80 struct list_head list; 112 struct list_head list;
81 char *smk_subject; 113 struct smack_known *smk_subject;
82 char *smk_object; 114 char *smk_object;
83 int smk_access; 115 int smk_access;
84}; 116};
@@ -94,35 +126,14 @@ struct smk_netlbladdr {
94}; 126};
95 127
96/* 128/*
97 * This is the repository for labels seen so that it is 129 * An entry in the table identifying ports.
98 * not necessary to keep allocating tiny chuncks of memory
99 * and so that they can be shared.
100 *
101 * Labels are never modified in place. Anytime a label
102 * is imported (e.g. xattrset on a file) the list is checked
103 * for it and it is added if it doesn't exist. The address
104 * is passed out in either case. Entries are added, but
105 * never deleted.
106 *
107 * Since labels are hanging around anyway it doesn't
108 * hurt to maintain a secid for those awkward situations
109 * where kernel components that ought to use LSM independent
110 * interfaces don't. The secid should go away when all of
111 * these components have been repaired.
112 *
113 * The cipso value associated with the label gets stored here, too.
114 *
115 * Keep the access rules for this subject label here so that
116 * the entire set of rules does not need to be examined every
117 * time.
118 */ 130 */
119struct smack_known { 131struct smk_port_label {
120 struct list_head list; 132 struct list_head list;
121 char *smk_known; 133 struct sock *smk_sock; /* socket initialized on */
122 u32 smk_secid; 134 unsigned short smk_port; /* the port number */
123 struct netlbl_lsm_secattr smk_netlabel; /* on wire labels */ 135 char *smk_in; /* incoming label */
124 struct list_head smk_rules; /* access rules */ 136 struct smack_known *smk_out; /* outgoing label */
125 struct mutex smk_rules_lock; /* lock for rules */
126}; 137};
127 138
128/* 139/*
@@ -132,6 +143,7 @@ struct smack_known {
132#define SMK_FSFLOOR "smackfsfloor=" 143#define SMK_FSFLOOR "smackfsfloor="
133#define SMK_FSHAT "smackfshat=" 144#define SMK_FSHAT "smackfshat="
134#define SMK_FSROOT "smackfsroot=" 145#define SMK_FSROOT "smackfsroot="
146#define SMK_FSTRANS "smackfstransmute="
135 147
136#define SMACK_CIPSO_OPTION "-CIPSO" 148#define SMACK_CIPSO_OPTION "-CIPSO"
137 149
@@ -203,9 +215,9 @@ struct inode_smack *new_inode_smack(char *);
203 * These functions are in smack_access.c 215 * These functions are in smack_access.c
204 */ 216 */
205int smk_access_entry(char *, char *, struct list_head *); 217int smk_access_entry(char *, char *, struct list_head *);
206int smk_access(char *, char *, int, struct smk_audit_info *); 218int smk_access(struct smack_known *, char *, int, struct smk_audit_info *);
207int smk_curacc(char *, u32, struct smk_audit_info *); 219int smk_curacc(char *, u32, struct smk_audit_info *);
208char *smack_from_secid(const u32); 220struct smack_known *smack_from_secid(const u32);
209char *smk_parse_smack(const char *string, int len); 221char *smk_parse_smack(const char *string, int len);
210int smk_netlbl_mls(int, char *, struct netlbl_lsm_secattr *, int); 222int smk_netlbl_mls(int, char *, struct netlbl_lsm_secattr *, int);
211char *smk_import(const char *, int); 223char *smk_import(const char *, int);
@@ -218,7 +230,7 @@ u32 smack_to_secid(const char *);
218 */ 230 */
219extern int smack_cipso_direct; 231extern int smack_cipso_direct;
220extern int smack_cipso_mapped; 232extern int smack_cipso_mapped;
221extern char *smack_net_ambient; 233extern struct smack_known *smack_net_ambient;
222extern char *smack_onlycap; 234extern char *smack_onlycap;
223extern const char *smack_cipso_option; 235extern const char *smack_cipso_option;
224 236
@@ -254,17 +266,17 @@ static inline char *smk_of_inode(const struct inode *isp)
254} 266}
255 267
256/* 268/*
257 * Present a pointer to the smack label in an task blob. 269 * Present a pointer to the smack label entry in an task blob.
258 */ 270 */
259static inline char *smk_of_task(const struct task_smack *tsp) 271static inline struct smack_known *smk_of_task(const struct task_smack *tsp)
260{ 272{
261 return tsp->smk_task; 273 return tsp->smk_task;
262} 274}
263 275
264/* 276/*
265 * Present a pointer to the forked smack label in an task blob. 277 * Present a pointer to the forked smack label entry in an task blob.
266 */ 278 */
267static inline char *smk_of_forked(const struct task_smack *tsp) 279static inline struct smack_known *smk_of_forked(const struct task_smack *tsp)
268{ 280{
269 return tsp->smk_forked; 281 return tsp->smk_forked;
270} 282}
@@ -272,7 +284,7 @@ static inline char *smk_of_forked(const struct task_smack *tsp)
272/* 284/*
273 * Present a pointer to the smack label in the current task blob. 285 * Present a pointer to the smack label in the current task blob.
274 */ 286 */
275static inline char *smk_of_current(void) 287static inline struct smack_known *smk_of_current(void)
276{ 288{
277 return smk_of_task(current_security()); 289 return smk_of_task(current_security());
278} 290}
@@ -283,9 +295,11 @@ static inline char *smk_of_current(void)
283 */ 295 */
284static inline int smack_privileged(int cap) 296static inline int smack_privileged(int cap)
285{ 297{
298 struct smack_known *skp = smk_of_current();
299
286 if (!capable(cap)) 300 if (!capable(cap))
287 return 0; 301 return 0;
288 if (smack_onlycap == NULL || smack_onlycap == smk_of_current()) 302 if (smack_onlycap == NULL || smack_onlycap == skp->smk_known)
289 return 1; 303 return 1;
290 return 0; 304 return 0;
291} 305}
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c
index 2e397a88d410..6a0377f38620 100644
--- a/security/smack/smack_access.c
+++ b/security/smack/smack_access.c
@@ -93,7 +93,7 @@ int smk_access_entry(char *subject_label, char *object_label,
93 93
94 list_for_each_entry_rcu(srp, rule_list, list) { 94 list_for_each_entry_rcu(srp, rule_list, list) {
95 if (srp->smk_object == object_label && 95 if (srp->smk_object == object_label &&
96 srp->smk_subject == subject_label) { 96 srp->smk_subject->smk_known == subject_label) {
97 may = srp->smk_access; 97 may = srp->smk_access;
98 break; 98 break;
99 } 99 }
@@ -104,7 +104,7 @@ int smk_access_entry(char *subject_label, char *object_label,
104 104
105/** 105/**
106 * smk_access - determine if a subject has a specific access to an object 106 * smk_access - determine if a subject has a specific access to an object
107 * @subject_label: a pointer to the subject's Smack label 107 * @subject_known: a pointer to the subject's Smack label entry
108 * @object_label: a pointer to the object's Smack label 108 * @object_label: a pointer to the object's Smack label
109 * @request: the access requested, in "MAY" format 109 * @request: the access requested, in "MAY" format
110 * @a : a pointer to the audit data 110 * @a : a pointer to the audit data
@@ -115,10 +115,9 @@ int smk_access_entry(char *subject_label, char *object_label,
115 * 115 *
116 * Smack labels are shared on smack_list 116 * Smack labels are shared on smack_list
117 */ 117 */
118int smk_access(char *subject_label, char *object_label, int request, 118int smk_access(struct smack_known *subject_known, char *object_label,
119 struct smk_audit_info *a) 119 int request, struct smk_audit_info *a)
120{ 120{
121 struct smack_known *skp;
122 int may = MAY_NOT; 121 int may = MAY_NOT;
123 int rc = 0; 122 int rc = 0;
124 123
@@ -127,7 +126,7 @@ int smk_access(char *subject_label, char *object_label, int request,
127 * 126 *
128 * A star subject can't access any object. 127 * A star subject can't access any object.
129 */ 128 */
130 if (subject_label == smack_known_star.smk_known) { 129 if (subject_known == &smack_known_star) {
131 rc = -EACCES; 130 rc = -EACCES;
132 goto out_audit; 131 goto out_audit;
133 } 132 }
@@ -137,7 +136,7 @@ int smk_access(char *subject_label, char *object_label, int request,
137 * An internet subject can access any object. 136 * An internet subject can access any object.
138 */ 137 */
139 if (object_label == smack_known_web.smk_known || 138 if (object_label == smack_known_web.smk_known ||
140 subject_label == smack_known_web.smk_known) 139 subject_known == &smack_known_web)
141 goto out_audit; 140 goto out_audit;
142 /* 141 /*
143 * A star object can be accessed by any subject. 142 * A star object can be accessed by any subject.
@@ -148,7 +147,7 @@ int smk_access(char *subject_label, char *object_label, int request,
148 * An object can be accessed in any way by a subject 147 * An object can be accessed in any way by a subject
149 * with the same label. 148 * with the same label.
150 */ 149 */
151 if (subject_label == object_label) 150 if (subject_known->smk_known == object_label)
152 goto out_audit; 151 goto out_audit;
153 /* 152 /*
154 * A hat subject can read any object. 153 * A hat subject can read any object.
@@ -157,7 +156,7 @@ int smk_access(char *subject_label, char *object_label, int request,
157 if ((request & MAY_ANYREAD) == request) { 156 if ((request & MAY_ANYREAD) == request) {
158 if (object_label == smack_known_floor.smk_known) 157 if (object_label == smack_known_floor.smk_known)
159 goto out_audit; 158 goto out_audit;
160 if (subject_label == smack_known_hat.smk_known) 159 if (subject_known == &smack_known_hat)
161 goto out_audit; 160 goto out_audit;
162 } 161 }
163 /* 162 /*
@@ -167,9 +166,9 @@ int smk_access(char *subject_label, char *object_label, int request,
167 * good. A negative response from smk_access_entry() 166 * good. A negative response from smk_access_entry()
168 * indicates there is no entry for this pair. 167 * indicates there is no entry for this pair.
169 */ 168 */
170 skp = smk_find_entry(subject_label);
171 rcu_read_lock(); 169 rcu_read_lock();
172 may = smk_access_entry(subject_label, object_label, &skp->smk_rules); 170 may = smk_access_entry(subject_known->smk_known, object_label,
171 &subject_known->smk_rules);
173 rcu_read_unlock(); 172 rcu_read_unlock();
174 173
175 if (may > 0 && (request & may) == request) 174 if (may > 0 && (request & may) == request)
@@ -179,7 +178,8 @@ int smk_access(char *subject_label, char *object_label, int request,
179out_audit: 178out_audit:
180#ifdef CONFIG_AUDIT 179#ifdef CONFIG_AUDIT
181 if (a) 180 if (a)
182 smack_log(subject_label, object_label, request, rc, a); 181 smack_log(subject_known->smk_known, object_label, request,
182 rc, a);
183#endif 183#endif
184 return rc; 184 return rc;
185} 185}
@@ -198,20 +198,21 @@ out_audit:
198int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a) 198int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a)
199{ 199{
200 struct task_smack *tsp = current_security(); 200 struct task_smack *tsp = current_security();
201 char *sp = smk_of_task(tsp); 201 struct smack_known *skp = smk_of_task(tsp);
202 int may; 202 int may;
203 int rc; 203 int rc;
204 204
205 /* 205 /*
206 * Check the global rule list 206 * Check the global rule list
207 */ 207 */
208 rc = smk_access(sp, obj_label, mode, NULL); 208 rc = smk_access(skp, obj_label, mode, NULL);
209 if (rc == 0) { 209 if (rc == 0) {
210 /* 210 /*
211 * If there is an entry in the task's rule list 211 * If there is an entry in the task's rule list
212 * it can further restrict access. 212 * it can further restrict access.
213 */ 213 */
214 may = smk_access_entry(sp, obj_label, &tsp->smk_rules); 214 may = smk_access_entry(skp->smk_known, obj_label,
215 &tsp->smk_rules);
215 if (may < 0) 216 if (may < 0)
216 goto out_audit; 217 goto out_audit;
217 if ((mode & may) == mode) 218 if ((mode & may) == mode)
@@ -228,7 +229,7 @@ int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a)
228out_audit: 229out_audit:
229#ifdef CONFIG_AUDIT 230#ifdef CONFIG_AUDIT
230 if (a) 231 if (a)
231 smack_log(sp, obj_label, mode, rc, a); 232 smack_log(skp->smk_known, obj_label, mode, rc, a);
232#endif 233#endif
233 return rc; 234 return rc;
234} 235}
@@ -402,6 +403,8 @@ int smk_netlbl_mls(int level, char *catset, struct netlbl_lsm_secattr *sap,
402 sap->flags |= NETLBL_SECATTR_MLS_CAT; 403 sap->flags |= NETLBL_SECATTR_MLS_CAT;
403 sap->attr.mls.lvl = level; 404 sap->attr.mls.lvl = level;
404 sap->attr.mls.cat = netlbl_secattr_catmap_alloc(GFP_ATOMIC); 405 sap->attr.mls.cat = netlbl_secattr_catmap_alloc(GFP_ATOMIC);
406 if (!sap->attr.mls.cat)
407 return -ENOMEM;
405 sap->attr.mls.cat->startbit = 0; 408 sap->attr.mls.cat->startbit = 0;
406 409
407 for (cat = 1, cp = catset, byte = 0; byte < len; cp++, byte++) 410 for (cat = 1, cp = catset, byte = 0; byte < len; cp++, byte++)
@@ -513,10 +516,10 @@ char *smk_import(const char *string, int len)
513 * smack_from_secid - find the Smack label associated with a secid 516 * smack_from_secid - find the Smack label associated with a secid
514 * @secid: an integer that might be associated with a Smack label 517 * @secid: an integer that might be associated with a Smack label
515 * 518 *
516 * Returns a pointer to the appropriate Smack label if there is one, 519 * Returns a pointer to the appropriate Smack label entry if there is one,
517 * otherwise a pointer to the invalid Smack label. 520 * otherwise a pointer to the invalid Smack label.
518 */ 521 */
519char *smack_from_secid(const u32 secid) 522struct smack_known *smack_from_secid(const u32 secid)
520{ 523{
521 struct smack_known *skp; 524 struct smack_known *skp;
522 525
@@ -524,7 +527,7 @@ char *smack_from_secid(const u32 secid)
524 list_for_each_entry_rcu(skp, &smack_known_list, list) { 527 list_for_each_entry_rcu(skp, &smack_known_list, list) {
525 if (skp->smk_secid == secid) { 528 if (skp->smk_secid == secid) {
526 rcu_read_unlock(); 529 rcu_read_unlock();
527 return skp->smk_known; 530 return skp;
528 } 531 }
529 } 532 }
530 533
@@ -533,7 +536,7 @@ char *smack_from_secid(const u32 secid)
533 * of a secid that is not on the list. 536 * of a secid that is not on the list.
534 */ 537 */
535 rcu_read_unlock(); 538 rcu_read_unlock();
536 return smack_known_invalid.smk_known; 539 return &smack_known_invalid;
537} 540}
538 541
539/** 542/**
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index d52c780bdb78..eefbd10e408f 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -27,10 +27,13 @@
27#include <linux/ip.h> 27#include <linux/ip.h>
28#include <linux/tcp.h> 28#include <linux/tcp.h>
29#include <linux/udp.h> 29#include <linux/udp.h>
30#include <linux/dccp.h>
30#include <linux/slab.h> 31#include <linux/slab.h>
31#include <linux/mutex.h> 32#include <linux/mutex.h>
32#include <linux/pipe_fs_i.h> 33#include <linux/pipe_fs_i.h>
33#include <net/cipso_ipv4.h> 34#include <net/cipso_ipv4.h>
35#include <net/ip.h>
36#include <net/ipv6.h>
34#include <linux/audit.h> 37#include <linux/audit.h>
35#include <linux/magic.h> 38#include <linux/magic.h>
36#include <linux/dcache.h> 39#include <linux/dcache.h>
@@ -45,6 +48,12 @@
45#define TRANS_TRUE "TRUE" 48#define TRANS_TRUE "TRUE"
46#define TRANS_TRUE_SIZE 4 49#define TRANS_TRUE_SIZE 4
47 50
51#define SMK_CONNECTING 0
52#define SMK_RECEIVING 1
53#define SMK_SENDING 2
54
55LIST_HEAD(smk_ipv6_port_list);
56
48/** 57/**
49 * smk_fetch - Fetch the smack label from a file. 58 * smk_fetch - Fetch the smack label from a file.
50 * @ip: a pointer to the inode 59 * @ip: a pointer to the inode
@@ -53,11 +62,12 @@
53 * Returns a pointer to the master list entry for the Smack label 62 * Returns a pointer to the master list entry for the Smack label
54 * or NULL if there was no label to fetch. 63 * or NULL if there was no label to fetch.
55 */ 64 */
56static char *smk_fetch(const char *name, struct inode *ip, struct dentry *dp) 65static struct smack_known *smk_fetch(const char *name, struct inode *ip,
66 struct dentry *dp)
57{ 67{
58 int rc; 68 int rc;
59 char *buffer; 69 char *buffer;
60 char *result = NULL; 70 struct smack_known *skp = NULL;
61 71
62 if (ip->i_op->getxattr == NULL) 72 if (ip->i_op->getxattr == NULL)
63 return NULL; 73 return NULL;
@@ -68,11 +78,11 @@ static char *smk_fetch(const char *name, struct inode *ip, struct dentry *dp)
68 78
69 rc = ip->i_op->getxattr(dp, name, buffer, SMK_LONGLABEL); 79 rc = ip->i_op->getxattr(dp, name, buffer, SMK_LONGLABEL);
70 if (rc > 0) 80 if (rc > 0)
71 result = smk_import(buffer, rc); 81 skp = smk_import_entry(buffer, rc);
72 82
73 kfree(buffer); 83 kfree(buffer);
74 84
75 return result; 85 return skp;
76} 86}
77 87
78/** 88/**
@@ -102,7 +112,8 @@ struct inode_smack *new_inode_smack(char *smack)
102 * 112 *
103 * Returns the new blob or NULL if there's no memory available 113 * Returns the new blob or NULL if there's no memory available
104 */ 114 */
105static struct task_smack *new_task_smack(char *task, char *forked, gfp_t gfp) 115static struct task_smack *new_task_smack(struct smack_known *task,
116 struct smack_known *forked, gfp_t gfp)
106{ 117{
107 struct task_smack *tsp; 118 struct task_smack *tsp;
108 119
@@ -164,17 +175,17 @@ static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode)
164{ 175{
165 int rc; 176 int rc;
166 struct smk_audit_info ad; 177 struct smk_audit_info ad;
167 char *tsp; 178 struct smack_known *skp;
168 179
169 rc = cap_ptrace_access_check(ctp, mode); 180 rc = cap_ptrace_access_check(ctp, mode);
170 if (rc != 0) 181 if (rc != 0)
171 return rc; 182 return rc;
172 183
173 tsp = smk_of_task(task_security(ctp)); 184 skp = smk_of_task(task_security(ctp));
174 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); 185 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
175 smk_ad_setfield_u_tsk(&ad, ctp); 186 smk_ad_setfield_u_tsk(&ad, ctp);
176 187
177 rc = smk_curacc(tsp, MAY_READWRITE, &ad); 188 rc = smk_curacc(skp->smk_known, MAY_READWRITE, &ad);
178 return rc; 189 return rc;
179} 190}
180 191
@@ -190,17 +201,17 @@ static int smack_ptrace_traceme(struct task_struct *ptp)
190{ 201{
191 int rc; 202 int rc;
192 struct smk_audit_info ad; 203 struct smk_audit_info ad;
193 char *tsp; 204 struct smack_known *skp;
194 205
195 rc = cap_ptrace_traceme(ptp); 206 rc = cap_ptrace_traceme(ptp);
196 if (rc != 0) 207 if (rc != 0)
197 return rc; 208 return rc;
198 209
199 tsp = smk_of_task(task_security(ptp)); 210 skp = smk_of_task(task_security(ptp));
200 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); 211 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
201 smk_ad_setfield_u_tsk(&ad, ptp); 212 smk_ad_setfield_u_tsk(&ad, ptp);
202 213
203 rc = smk_curacc(tsp, MAY_READWRITE, &ad); 214 rc = smk_curacc(skp->smk_known, MAY_READWRITE, &ad);
204 return rc; 215 return rc;
205} 216}
206 217
@@ -215,12 +226,12 @@ static int smack_ptrace_traceme(struct task_struct *ptp)
215static int smack_syslog(int typefrom_file) 226static int smack_syslog(int typefrom_file)
216{ 227{
217 int rc = 0; 228 int rc = 0;
218 char *sp = smk_of_current(); 229 struct smack_known *skp = smk_of_current();
219 230
220 if (smack_privileged(CAP_MAC_OVERRIDE)) 231 if (smack_privileged(CAP_MAC_OVERRIDE))
221 return 0; 232 return 0;
222 233
223 if (sp != smack_known_floor.smk_known) 234 if (skp != &smack_known_floor)
224 rc = -EACCES; 235 rc = -EACCES;
225 236
226 return rc; 237 return rc;
@@ -250,8 +261,9 @@ static int smack_sb_alloc_security(struct super_block *sb)
250 sbsp->smk_default = smack_known_floor.smk_known; 261 sbsp->smk_default = smack_known_floor.smk_known;
251 sbsp->smk_floor = smack_known_floor.smk_known; 262 sbsp->smk_floor = smack_known_floor.smk_known;
252 sbsp->smk_hat = smack_known_hat.smk_known; 263 sbsp->smk_hat = smack_known_hat.smk_known;
253 sbsp->smk_initialized = 0; 264 /*
254 265 * smk_initialized will be zero from kzalloc.
266 */
255 sb->s_security = sbsp; 267 sb->s_security = sbsp;
256 268
257 return 0; 269 return 0;
@@ -295,6 +307,8 @@ static int smack_sb_copy_data(char *orig, char *smackopts)
295 dp = smackopts; 307 dp = smackopts;
296 else if (strstr(cp, SMK_FSROOT) == cp) 308 else if (strstr(cp, SMK_FSROOT) == cp)
297 dp = smackopts; 309 dp = smackopts;
310 else if (strstr(cp, SMK_FSTRANS) == cp)
311 dp = smackopts;
298 else 312 else
299 dp = otheropts; 313 dp = otheropts;
300 314
@@ -330,8 +344,9 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data)
330 char *op; 344 char *op;
331 char *commap; 345 char *commap;
332 char *nsp; 346 char *nsp;
347 int transmute = 0;
333 348
334 if (sp->smk_initialized != 0) 349 if (sp->smk_initialized)
335 return 0; 350 return 0;
336 351
337 sp->smk_initialized = 1; 352 sp->smk_initialized = 1;
@@ -362,6 +377,13 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data)
362 nsp = smk_import(op, 0); 377 nsp = smk_import(op, 0);
363 if (nsp != NULL) 378 if (nsp != NULL)
364 sp->smk_root = nsp; 379 sp->smk_root = nsp;
380 } else if (strncmp(op, SMK_FSTRANS, strlen(SMK_FSTRANS)) == 0) {
381 op += strlen(SMK_FSTRANS);
382 nsp = smk_import(op, 0);
383 if (nsp != NULL) {
384 sp->smk_root = nsp;
385 transmute = 1;
386 }
365 } 387 }
366 } 388 }
367 389
@@ -369,11 +391,15 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data)
369 * Initialize the root inode. 391 * Initialize the root inode.
370 */ 392 */
371 isp = inode->i_security; 393 isp = inode->i_security;
372 if (isp == NULL) 394 if (inode->i_security == NULL) {
373 inode->i_security = new_inode_smack(sp->smk_root); 395 inode->i_security = new_inode_smack(sp->smk_root);
374 else 396 isp = inode->i_security;
397 } else
375 isp->smk_inode = sp->smk_root; 398 isp->smk_inode = sp->smk_root;
376 399
400 if (transmute)
401 isp->smk_flags |= SMK_INODE_TRANSMUTE;
402
377 return 0; 403 return 0;
378} 404}
379 405
@@ -524,7 +550,9 @@ static int smack_bprm_secureexec(struct linux_binprm *bprm)
524 */ 550 */
525static int smack_inode_alloc_security(struct inode *inode) 551static int smack_inode_alloc_security(struct inode *inode)
526{ 552{
527 inode->i_security = new_inode_smack(smk_of_current()); 553 struct smack_known *skp = smk_of_current();
554
555 inode->i_security = new_inode_smack(skp->smk_known);
528 if (inode->i_security == NULL) 556 if (inode->i_security == NULL)
529 return -ENOMEM; 557 return -ENOMEM;
530 return 0; 558 return 0;
@@ -557,9 +585,8 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir,
557 const struct qstr *qstr, char **name, 585 const struct qstr *qstr, char **name,
558 void **value, size_t *len) 586 void **value, size_t *len)
559{ 587{
560 struct smack_known *skp;
561 struct inode_smack *issp = inode->i_security; 588 struct inode_smack *issp = inode->i_security;
562 char *csp = smk_of_current(); 589 struct smack_known *skp = smk_of_current();
563 char *isp = smk_of_inode(inode); 590 char *isp = smk_of_inode(inode);
564 char *dsp = smk_of_inode(dir); 591 char *dsp = smk_of_inode(dir);
565 int may; 592 int may;
@@ -571,9 +598,8 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir,
571 } 598 }
572 599
573 if (value) { 600 if (value) {
574 skp = smk_find_entry(csp);
575 rcu_read_lock(); 601 rcu_read_lock();
576 may = smk_access_entry(csp, dsp, &skp->smk_rules); 602 may = smk_access_entry(skp->smk_known, dsp, &skp->smk_rules);
577 rcu_read_unlock(); 603 rcu_read_unlock();
578 604
579 /* 605 /*
@@ -862,29 +888,31 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name,
862static void smack_inode_post_setxattr(struct dentry *dentry, const char *name, 888static void smack_inode_post_setxattr(struct dentry *dentry, const char *name,
863 const void *value, size_t size, int flags) 889 const void *value, size_t size, int flags)
864{ 890{
865 char *nsp; 891 struct smack_known *skp;
866 struct inode_smack *isp = dentry->d_inode->i_security; 892 struct inode_smack *isp = dentry->d_inode->i_security;
867 893
894 if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) {
895 isp->smk_flags |= SMK_INODE_TRANSMUTE;
896 return;
897 }
898
899 skp = smk_import_entry(value, size);
868 if (strcmp(name, XATTR_NAME_SMACK) == 0) { 900 if (strcmp(name, XATTR_NAME_SMACK) == 0) {
869 nsp = smk_import(value, size); 901 if (skp != NULL)
870 if (nsp != NULL) 902 isp->smk_inode = skp->smk_known;
871 isp->smk_inode = nsp;
872 else 903 else
873 isp->smk_inode = smack_known_invalid.smk_known; 904 isp->smk_inode = smack_known_invalid.smk_known;
874 } else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0) { 905 } else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0) {
875 nsp = smk_import(value, size); 906 if (skp != NULL)
876 if (nsp != NULL) 907 isp->smk_task = skp;
877 isp->smk_task = nsp;
878 else 908 else
879 isp->smk_task = smack_known_invalid.smk_known; 909 isp->smk_task = &smack_known_invalid;
880 } else if (strcmp(name, XATTR_NAME_SMACKMMAP) == 0) { 910 } else if (strcmp(name, XATTR_NAME_SMACKMMAP) == 0) {
881 nsp = smk_import(value, size); 911 if (skp != NULL)
882 if (nsp != NULL) 912 isp->smk_mmap = skp;
883 isp->smk_mmap = nsp;
884 else 913 else
885 isp->smk_mmap = smack_known_invalid.smk_known; 914 isp->smk_mmap = &smack_known_invalid;
886 } else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) 915 }
887 isp->smk_flags |= SMK_INODE_TRANSMUTE;
888 916
889 return; 917 return;
890} 918}
@@ -990,7 +1018,7 @@ static int smack_inode_getsecurity(const struct inode *inode,
990 if (strcmp(name, XATTR_SMACK_IPIN) == 0) 1018 if (strcmp(name, XATTR_SMACK_IPIN) == 0)
991 isp = ssp->smk_in; 1019 isp = ssp->smk_in;
992 else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) 1020 else if (strcmp(name, XATTR_SMACK_IPOUT) == 0)
993 isp = ssp->smk_out; 1021 isp = ssp->smk_out->smk_known;
994 else 1022 else
995 return -EOPNOTSUPP; 1023 return -EOPNOTSUPP;
996 1024
@@ -1070,7 +1098,9 @@ static int smack_file_permission(struct file *file, int mask)
1070 */ 1098 */
1071static int smack_file_alloc_security(struct file *file) 1099static int smack_file_alloc_security(struct file *file)
1072{ 1100{
1073 file->f_security = smk_of_current(); 1101 struct smack_known *skp = smk_of_current();
1102
1103 file->f_security = skp->smk_known;
1074 return 0; 1104 return 0;
1075} 1105}
1076 1106
@@ -1181,10 +1211,9 @@ static int smack_mmap_file(struct file *file,
1181 unsigned long flags) 1211 unsigned long flags)
1182{ 1212{
1183 struct smack_known *skp; 1213 struct smack_known *skp;
1214 struct smack_known *mkp;
1184 struct smack_rule *srp; 1215 struct smack_rule *srp;
1185 struct task_smack *tsp; 1216 struct task_smack *tsp;
1186 char *sp;
1187 char *msmack;
1188 char *osmack; 1217 char *osmack;
1189 struct inode_smack *isp; 1218 struct inode_smack *isp;
1190 int may; 1219 int may;
@@ -1198,11 +1227,10 @@ static int smack_mmap_file(struct file *file,
1198 isp = file_inode(file)->i_security; 1227 isp = file_inode(file)->i_security;
1199 if (isp->smk_mmap == NULL) 1228 if (isp->smk_mmap == NULL)
1200 return 0; 1229 return 0;
1201 msmack = isp->smk_mmap; 1230 mkp = isp->smk_mmap;
1202 1231
1203 tsp = current_security(); 1232 tsp = current_security();
1204 sp = smk_of_current(); 1233 skp = smk_of_current();
1205 skp = smk_find_entry(sp);
1206 rc = 0; 1234 rc = 0;
1207 1235
1208 rcu_read_lock(); 1236 rcu_read_lock();
@@ -1216,13 +1244,13 @@ static int smack_mmap_file(struct file *file,
1216 /* 1244 /*
1217 * Matching labels always allows access. 1245 * Matching labels always allows access.
1218 */ 1246 */
1219 if (msmack == osmack) 1247 if (mkp->smk_known == osmack)
1220 continue; 1248 continue;
1221 /* 1249 /*
1222 * If there is a matching local rule take 1250 * If there is a matching local rule take
1223 * that into account as well. 1251 * that into account as well.
1224 */ 1252 */
1225 may = smk_access_entry(srp->smk_subject, osmack, 1253 may = smk_access_entry(srp->smk_subject->smk_known, osmack,
1226 &tsp->smk_rules); 1254 &tsp->smk_rules);
1227 if (may == -ENOENT) 1255 if (may == -ENOENT)
1228 may = srp->smk_access; 1256 may = srp->smk_access;
@@ -1240,8 +1268,8 @@ static int smack_mmap_file(struct file *file,
1240 * If there isn't one a SMACK64MMAP subject 1268 * If there isn't one a SMACK64MMAP subject
1241 * can't have as much access as current. 1269 * can't have as much access as current.
1242 */ 1270 */
1243 skp = smk_find_entry(msmack); 1271 mmay = smk_access_entry(mkp->smk_known, osmack,
1244 mmay = smk_access_entry(msmack, osmack, &skp->smk_rules); 1272 &mkp->smk_rules);
1245 if (mmay == -ENOENT) { 1273 if (mmay == -ENOENT) {
1246 rc = -EACCES; 1274 rc = -EACCES;
1247 break; 1275 break;
@@ -1250,7 +1278,8 @@ static int smack_mmap_file(struct file *file,
1250 * If there is a local entry it modifies the 1278 * If there is a local entry it modifies the
1251 * potential access, too. 1279 * potential access, too.
1252 */ 1280 */
1253 tmay = smk_access_entry(msmack, osmack, &tsp->smk_rules); 1281 tmay = smk_access_entry(mkp->smk_known, osmack,
1282 &tsp->smk_rules);
1254 if (tmay != -ENOENT) 1283 if (tmay != -ENOENT)
1255 mmay &= tmay; 1284 mmay &= tmay;
1256 1285
@@ -1279,7 +1308,9 @@ static int smack_mmap_file(struct file *file,
1279 */ 1308 */
1280static int smack_file_set_fowner(struct file *file) 1309static int smack_file_set_fowner(struct file *file)
1281{ 1310{
1282 file->f_security = smk_of_current(); 1311 struct smack_known *skp = smk_of_current();
1312
1313 file->f_security = skp->smk_known;
1283 return 0; 1314 return 0;
1284} 1315}
1285 1316
@@ -1297,9 +1328,10 @@ static int smack_file_set_fowner(struct file *file)
1297static int smack_file_send_sigiotask(struct task_struct *tsk, 1328static int smack_file_send_sigiotask(struct task_struct *tsk,
1298 struct fown_struct *fown, int signum) 1329 struct fown_struct *fown, int signum)
1299{ 1330{
1331 struct smack_known *skp;
1332 struct smack_known *tkp = smk_of_task(tsk->cred->security);
1300 struct file *file; 1333 struct file *file;
1301 int rc; 1334 int rc;
1302 char *tsp = smk_of_task(tsk->cred->security);
1303 struct smk_audit_info ad; 1335 struct smk_audit_info ad;
1304 1336
1305 /* 1337 /*
@@ -1308,13 +1340,14 @@ static int smack_file_send_sigiotask(struct task_struct *tsk,
1308 file = container_of(fown, struct file, f_owner); 1340 file = container_of(fown, struct file, f_owner);
1309 1341
1310 /* we don't log here as rc can be overriden */ 1342 /* we don't log here as rc can be overriden */
1311 rc = smk_access(file->f_security, tsp, MAY_WRITE, NULL); 1343 skp = smk_find_entry(file->f_security);
1344 rc = smk_access(skp, tkp->smk_known, MAY_WRITE, NULL);
1312 if (rc != 0 && has_capability(tsk, CAP_MAC_OVERRIDE)) 1345 if (rc != 0 && has_capability(tsk, CAP_MAC_OVERRIDE))
1313 rc = 0; 1346 rc = 0;
1314 1347
1315 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); 1348 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
1316 smk_ad_setfield_u_tsk(&ad, tsk); 1349 smk_ad_setfield_u_tsk(&ad, tsk);
1317 smack_log(file->f_security, tsp, MAY_WRITE, rc, &ad); 1350 smack_log(file->f_security, tkp->smk_known, MAY_WRITE, rc, &ad);
1318 return rc; 1351 return rc;
1319} 1352}
1320 1353
@@ -1469,12 +1502,12 @@ static void smack_cred_transfer(struct cred *new, const struct cred *old)
1469static int smack_kernel_act_as(struct cred *new, u32 secid) 1502static int smack_kernel_act_as(struct cred *new, u32 secid)
1470{ 1503{
1471 struct task_smack *new_tsp = new->security; 1504 struct task_smack *new_tsp = new->security;
1472 char *smack = smack_from_secid(secid); 1505 struct smack_known *skp = smack_from_secid(secid);
1473 1506
1474 if (smack == NULL) 1507 if (skp == NULL)
1475 return -EINVAL; 1508 return -EINVAL;
1476 1509
1477 new_tsp->smk_task = smack; 1510 new_tsp->smk_task = skp;
1478 return 0; 1511 return 0;
1479} 1512}
1480 1513
@@ -1492,8 +1525,8 @@ static int smack_kernel_create_files_as(struct cred *new,
1492 struct inode_smack *isp = inode->i_security; 1525 struct inode_smack *isp = inode->i_security;
1493 struct task_smack *tsp = new->security; 1526 struct task_smack *tsp = new->security;
1494 1527
1495 tsp->smk_forked = isp->smk_inode; 1528 tsp->smk_forked = smk_find_entry(isp->smk_inode);
1496 tsp->smk_task = isp->smk_inode; 1529 tsp->smk_task = tsp->smk_forked;
1497 return 0; 1530 return 0;
1498} 1531}
1499 1532
@@ -1509,10 +1542,11 @@ static int smk_curacc_on_task(struct task_struct *p, int access,
1509 const char *caller) 1542 const char *caller)
1510{ 1543{
1511 struct smk_audit_info ad; 1544 struct smk_audit_info ad;
1545 struct smack_known *skp = smk_of_task(task_security(p));
1512 1546
1513 smk_ad_init(&ad, caller, LSM_AUDIT_DATA_TASK); 1547 smk_ad_init(&ad, caller, LSM_AUDIT_DATA_TASK);
1514 smk_ad_setfield_u_tsk(&ad, p); 1548 smk_ad_setfield_u_tsk(&ad, p);
1515 return smk_curacc(smk_of_task(task_security(p)), access, &ad); 1549 return smk_curacc(skp->smk_known, access, &ad);
1516} 1550}
1517 1551
1518/** 1552/**
@@ -1558,7 +1592,9 @@ static int smack_task_getsid(struct task_struct *p)
1558 */ 1592 */
1559static void smack_task_getsecid(struct task_struct *p, u32 *secid) 1593static void smack_task_getsecid(struct task_struct *p, u32 *secid)
1560{ 1594{
1561 *secid = smack_to_secid(smk_of_task(task_security(p))); 1595 struct smack_known *skp = smk_of_task(task_security(p));
1596
1597 *secid = skp->smk_secid;
1562} 1598}
1563 1599
1564/** 1600/**
@@ -1662,6 +1698,8 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info,
1662 int sig, u32 secid) 1698 int sig, u32 secid)
1663{ 1699{
1664 struct smk_audit_info ad; 1700 struct smk_audit_info ad;
1701 struct smack_known *skp;
1702 struct smack_known *tkp = smk_of_task(task_security(p));
1665 1703
1666 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); 1704 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
1667 smk_ad_setfield_u_tsk(&ad, p); 1705 smk_ad_setfield_u_tsk(&ad, p);
@@ -1670,15 +1708,14 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info,
1670 * can write the receiver. 1708 * can write the receiver.
1671 */ 1709 */
1672 if (secid == 0) 1710 if (secid == 0)
1673 return smk_curacc(smk_of_task(task_security(p)), MAY_WRITE, 1711 return smk_curacc(tkp->smk_known, MAY_WRITE, &ad);
1674 &ad);
1675 /* 1712 /*
1676 * If the secid isn't 0 we're dealing with some USB IO 1713 * If the secid isn't 0 we're dealing with some USB IO
1677 * specific behavior. This is not clean. For one thing 1714 * specific behavior. This is not clean. For one thing
1678 * we can't take privilege into account. 1715 * we can't take privilege into account.
1679 */ 1716 */
1680 return smk_access(smack_from_secid(secid), 1717 skp = smack_from_secid(secid);
1681 smk_of_task(task_security(p)), MAY_WRITE, &ad); 1718 return smk_access(skp, tkp->smk_known, MAY_WRITE, &ad);
1682} 1719}
1683 1720
1684/** 1721/**
@@ -1710,7 +1747,9 @@ static int smack_task_wait(struct task_struct *p)
1710static void smack_task_to_inode(struct task_struct *p, struct inode *inode) 1747static void smack_task_to_inode(struct task_struct *p, struct inode *inode)
1711{ 1748{
1712 struct inode_smack *isp = inode->i_security; 1749 struct inode_smack *isp = inode->i_security;
1713 isp->smk_inode = smk_of_task(task_security(p)); 1750 struct smack_known *skp = smk_of_task(task_security(p));
1751
1752 isp->smk_inode = skp->smk_known;
1714} 1753}
1715 1754
1716/* 1755/*
@@ -1729,15 +1768,15 @@ static void smack_task_to_inode(struct task_struct *p, struct inode *inode)
1729 */ 1768 */
1730static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags) 1769static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags)
1731{ 1770{
1732 char *csp = smk_of_current(); 1771 struct smack_known *skp = smk_of_current();
1733 struct socket_smack *ssp; 1772 struct socket_smack *ssp;
1734 1773
1735 ssp = kzalloc(sizeof(struct socket_smack), gfp_flags); 1774 ssp = kzalloc(sizeof(struct socket_smack), gfp_flags);
1736 if (ssp == NULL) 1775 if (ssp == NULL)
1737 return -ENOMEM; 1776 return -ENOMEM;
1738 1777
1739 ssp->smk_in = csp; 1778 ssp->smk_in = skp->smk_known;
1740 ssp->smk_out = csp; 1779 ssp->smk_out = skp;
1741 ssp->smk_packet = NULL; 1780 ssp->smk_packet = NULL;
1742 1781
1743 sk->sk_security = ssp; 1782 sk->sk_security = ssp;
@@ -1824,7 +1863,7 @@ static int smack_netlabel(struct sock *sk, int labeled)
1824 labeled == SMACK_UNLABELED_SOCKET) 1863 labeled == SMACK_UNLABELED_SOCKET)
1825 netlbl_sock_delattr(sk); 1864 netlbl_sock_delattr(sk);
1826 else { 1865 else {
1827 skp = smk_find_entry(ssp->smk_out); 1866 skp = ssp->smk_out;
1828 rc = netlbl_sock_setattr(sk, sk->sk_family, &skp->smk_netlabel); 1867 rc = netlbl_sock_setattr(sk, sk->sk_family, &skp->smk_netlabel);
1829 } 1868 }
1830 1869
@@ -1847,6 +1886,7 @@ static int smack_netlabel(struct sock *sk, int labeled)
1847 */ 1886 */
1848static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap) 1887static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap)
1849{ 1888{
1889 struct smack_known *skp;
1850 int rc; 1890 int rc;
1851 int sk_lbl; 1891 int sk_lbl;
1852 char *hostsp; 1892 char *hostsp;
@@ -1865,7 +1905,8 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap)
1865 ad.a.u.net->v4info.daddr = sap->sin_addr.s_addr; 1905 ad.a.u.net->v4info.daddr = sap->sin_addr.s_addr;
1866#endif 1906#endif
1867 sk_lbl = SMACK_UNLABELED_SOCKET; 1907 sk_lbl = SMACK_UNLABELED_SOCKET;
1868 rc = smk_access(ssp->smk_out, hostsp, MAY_WRITE, &ad); 1908 skp = ssp->smk_out;
1909 rc = smk_access(skp, hostsp, MAY_WRITE, &ad);
1869 } else { 1910 } else {
1870 sk_lbl = SMACK_CIPSO_SOCKET; 1911 sk_lbl = SMACK_CIPSO_SOCKET;
1871 rc = 0; 1912 rc = 0;
@@ -1878,6 +1919,153 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap)
1878} 1919}
1879 1920
1880/** 1921/**
1922 * smk_ipv6_port_label - Smack port access table management
1923 * @sock: socket
1924 * @address: address
1925 *
1926 * Create or update the port list entry
1927 */
1928static void smk_ipv6_port_label(struct socket *sock, struct sockaddr *address)
1929{
1930 struct sock *sk = sock->sk;
1931 struct sockaddr_in6 *addr6;
1932 struct socket_smack *ssp = sock->sk->sk_security;
1933 struct smk_port_label *spp;
1934 unsigned short port = 0;
1935
1936 if (address == NULL) {
1937 /*
1938 * This operation is changing the Smack information
1939 * on the bound socket. Take the changes to the port
1940 * as well.
1941 */
1942 list_for_each_entry(spp, &smk_ipv6_port_list, list) {
1943 if (sk != spp->smk_sock)
1944 continue;
1945 spp->smk_in = ssp->smk_in;
1946 spp->smk_out = ssp->smk_out;
1947 return;
1948 }
1949 /*
1950 * A NULL address is only used for updating existing
1951 * bound entries. If there isn't one, it's OK.
1952 */
1953 return;
1954 }
1955
1956 addr6 = (struct sockaddr_in6 *)address;
1957 port = ntohs(addr6->sin6_port);
1958 /*
1959 * This is a special case that is safely ignored.
1960 */
1961 if (port == 0)
1962 return;
1963
1964 /*
1965 * Look for an existing port list entry.
1966 * This is an indication that a port is getting reused.
1967 */
1968 list_for_each_entry(spp, &smk_ipv6_port_list, list) {
1969 if (spp->smk_port != port)
1970 continue;
1971 spp->smk_port = port;
1972 spp->smk_sock = sk;
1973 spp->smk_in = ssp->smk_in;
1974 spp->smk_out = ssp->smk_out;
1975 return;
1976 }
1977
1978 /*
1979 * A new port entry is required.
1980 */
1981 spp = kzalloc(sizeof(*spp), GFP_KERNEL);
1982 if (spp == NULL)
1983 return;
1984
1985 spp->smk_port = port;
1986 spp->smk_sock = sk;
1987 spp->smk_in = ssp->smk_in;
1988 spp->smk_out = ssp->smk_out;
1989
1990 list_add(&spp->list, &smk_ipv6_port_list);
1991 return;
1992}
1993
1994/**
1995 * smk_ipv6_port_check - check Smack port access
1996 * @sock: socket
1997 * @address: address
1998 *
1999 * Create or update the port list entry
2000 */
2001static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address,
2002 int act)
2003{
2004 __be16 *bep;
2005 __be32 *be32p;
2006 struct smk_port_label *spp;
2007 struct socket_smack *ssp = sk->sk_security;
2008 struct smack_known *skp;
2009 unsigned short port = 0;
2010 char *object;
2011 struct smk_audit_info ad;
2012#ifdef CONFIG_AUDIT
2013 struct lsm_network_audit net;
2014#endif
2015
2016 if (act == SMK_RECEIVING) {
2017 skp = smack_net_ambient;
2018 object = ssp->smk_in;
2019 } else {
2020 skp = ssp->smk_out;
2021 object = smack_net_ambient->smk_known;
2022 }
2023
2024 /*
2025 * Get the IP address and port from the address.
2026 */
2027 port = ntohs(address->sin6_port);
2028 bep = (__be16 *)(&address->sin6_addr);
2029 be32p = (__be32 *)(&address->sin6_addr);
2030
2031 /*
2032 * It's remote, so port lookup does no good.
2033 */
2034 if (be32p[0] || be32p[1] || be32p[2] || bep[6] || ntohs(bep[7]) != 1)
2035 goto auditout;
2036
2037 /*
2038 * It's local so the send check has to have passed.
2039 */
2040 if (act == SMK_RECEIVING) {
2041 skp = &smack_known_web;
2042 goto auditout;
2043 }
2044
2045 list_for_each_entry(spp, &smk_ipv6_port_list, list) {
2046 if (spp->smk_port != port)
2047 continue;
2048 object = spp->smk_in;
2049 if (act == SMK_CONNECTING)
2050 ssp->smk_packet = spp->smk_out->smk_known;
2051 break;
2052 }
2053
2054auditout:
2055
2056#ifdef CONFIG_AUDIT
2057 smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
2058 ad.a.u.net->family = sk->sk_family;
2059 ad.a.u.net->dport = port;
2060 if (act == SMK_RECEIVING)
2061 ad.a.u.net->v6info.saddr = address->sin6_addr;
2062 else
2063 ad.a.u.net->v6info.daddr = address->sin6_addr;
2064#endif
2065 return smk_access(skp, object, MAY_WRITE, &ad);
2066}
2067
2068/**
1881 * smack_inode_setsecurity - set smack xattrs 2069 * smack_inode_setsecurity - set smack xattrs
1882 * @inode: the object 2070 * @inode: the object
1883 * @name: attribute name 2071 * @name: attribute name
@@ -1892,7 +2080,7 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap)
1892static int smack_inode_setsecurity(struct inode *inode, const char *name, 2080static int smack_inode_setsecurity(struct inode *inode, const char *name,
1893 const void *value, size_t size, int flags) 2081 const void *value, size_t size, int flags)
1894{ 2082{
1895 char *sp; 2083 struct smack_known *skp;
1896 struct inode_smack *nsp = inode->i_security; 2084 struct inode_smack *nsp = inode->i_security;
1897 struct socket_smack *ssp; 2085 struct socket_smack *ssp;
1898 struct socket *sock; 2086 struct socket *sock;
@@ -1901,12 +2089,12 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
1901 if (value == NULL || size > SMK_LONGLABEL || size == 0) 2089 if (value == NULL || size > SMK_LONGLABEL || size == 0)
1902 return -EACCES; 2090 return -EACCES;
1903 2091
1904 sp = smk_import(value, size); 2092 skp = smk_import_entry(value, size);
1905 if (sp == NULL) 2093 if (skp == NULL)
1906 return -EINVAL; 2094 return -EINVAL;
1907 2095
1908 if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) { 2096 if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) {
1909 nsp->smk_inode = sp; 2097 nsp->smk_inode = skp->smk_known;
1910 nsp->smk_flags |= SMK_INODE_INSTANT; 2098 nsp->smk_flags |= SMK_INODE_INSTANT;
1911 return 0; 2099 return 0;
1912 } 2100 }
@@ -1923,10 +2111,10 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
1923 ssp = sock->sk->sk_security; 2111 ssp = sock->sk->sk_security;
1924 2112
1925 if (strcmp(name, XATTR_SMACK_IPIN) == 0) 2113 if (strcmp(name, XATTR_SMACK_IPIN) == 0)
1926 ssp->smk_in = sp; 2114 ssp->smk_in = skp->smk_known;
1927 else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) { 2115 else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) {
1928 ssp->smk_out = sp; 2116 ssp->smk_out = skp;
1929 if (sock->sk->sk_family != PF_UNIX) { 2117 if (sock->sk->sk_family == PF_INET) {
1930 rc = smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET); 2118 rc = smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET);
1931 if (rc != 0) 2119 if (rc != 0)
1932 printk(KERN_WARNING 2120 printk(KERN_WARNING
@@ -1936,6 +2124,9 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
1936 } else 2124 } else
1937 return -EOPNOTSUPP; 2125 return -EOPNOTSUPP;
1938 2126
2127 if (sock->sk->sk_family == PF_INET6)
2128 smk_ipv6_port_label(sock, NULL);
2129
1939 return 0; 2130 return 0;
1940} 2131}
1941 2132
@@ -1963,6 +2154,25 @@ static int smack_socket_post_create(struct socket *sock, int family,
1963} 2154}
1964 2155
1965/** 2156/**
2157 * smack_socket_bind - record port binding information.
2158 * @sock: the socket
2159 * @address: the port address
2160 * @addrlen: size of the address
2161 *
2162 * Records the label bound to a port.
2163 *
2164 * Returns 0
2165 */
2166static int smack_socket_bind(struct socket *sock, struct sockaddr *address,
2167 int addrlen)
2168{
2169 if (sock->sk != NULL && sock->sk->sk_family == PF_INET6)
2170 smk_ipv6_port_label(sock, address);
2171
2172 return 0;
2173}
2174
2175/**
1966 * smack_socket_connect - connect access check 2176 * smack_socket_connect - connect access check
1967 * @sock: the socket 2177 * @sock: the socket
1968 * @sap: the other end 2178 * @sap: the other end
@@ -1975,12 +2185,25 @@ static int smack_socket_post_create(struct socket *sock, int family,
1975static int smack_socket_connect(struct socket *sock, struct sockaddr *sap, 2185static int smack_socket_connect(struct socket *sock, struct sockaddr *sap,
1976 int addrlen) 2186 int addrlen)
1977{ 2187{
1978 if (sock->sk == NULL || sock->sk->sk_family != PF_INET) 2188 int rc = 0;
2189
2190 if (sock->sk == NULL)
1979 return 0; 2191 return 0;
1980 if (addrlen < sizeof(struct sockaddr_in))
1981 return -EINVAL;
1982 2192
1983 return smack_netlabel_send(sock->sk, (struct sockaddr_in *)sap); 2193 switch (sock->sk->sk_family) {
2194 case PF_INET:
2195 if (addrlen < sizeof(struct sockaddr_in))
2196 return -EINVAL;
2197 rc = smack_netlabel_send(sock->sk, (struct sockaddr_in *)sap);
2198 break;
2199 case PF_INET6:
2200 if (addrlen < sizeof(struct sockaddr_in6))
2201 return -EINVAL;
2202 rc = smk_ipv6_port_check(sock->sk, (struct sockaddr_in6 *)sap,
2203 SMK_CONNECTING);
2204 break;
2205 }
2206 return rc;
1984} 2207}
1985 2208
1986/** 2209/**
@@ -2011,7 +2234,9 @@ static int smack_flags_to_may(int flags)
2011 */ 2234 */
2012static int smack_msg_msg_alloc_security(struct msg_msg *msg) 2235static int smack_msg_msg_alloc_security(struct msg_msg *msg)
2013{ 2236{
2014 msg->security = smk_of_current(); 2237 struct smack_known *skp = smk_of_current();
2238
2239 msg->security = skp->smk_known;
2015 return 0; 2240 return 0;
2016} 2241}
2017 2242
@@ -2046,8 +2271,9 @@ static char *smack_of_shm(struct shmid_kernel *shp)
2046static int smack_shm_alloc_security(struct shmid_kernel *shp) 2271static int smack_shm_alloc_security(struct shmid_kernel *shp)
2047{ 2272{
2048 struct kern_ipc_perm *isp = &shp->shm_perm; 2273 struct kern_ipc_perm *isp = &shp->shm_perm;
2274 struct smack_known *skp = smk_of_current();
2049 2275
2050 isp->security = smk_of_current(); 2276 isp->security = skp->smk_known;
2051 return 0; 2277 return 0;
2052} 2278}
2053 2279
@@ -2169,8 +2395,9 @@ static char *smack_of_sem(struct sem_array *sma)
2169static int smack_sem_alloc_security(struct sem_array *sma) 2395static int smack_sem_alloc_security(struct sem_array *sma)
2170{ 2396{
2171 struct kern_ipc_perm *isp = &sma->sem_perm; 2397 struct kern_ipc_perm *isp = &sma->sem_perm;
2398 struct smack_known *skp = smk_of_current();
2172 2399
2173 isp->security = smk_of_current(); 2400 isp->security = skp->smk_known;
2174 return 0; 2401 return 0;
2175} 2402}
2176 2403
@@ -2287,8 +2514,9 @@ static int smack_sem_semop(struct sem_array *sma, struct sembuf *sops,
2287static int smack_msg_queue_alloc_security(struct msg_queue *msq) 2514static int smack_msg_queue_alloc_security(struct msg_queue *msq)
2288{ 2515{
2289 struct kern_ipc_perm *kisp = &msq->q_perm; 2516 struct kern_ipc_perm *kisp = &msq->q_perm;
2517 struct smack_known *skp = smk_of_current();
2290 2518
2291 kisp->security = smk_of_current(); 2519 kisp->security = skp->smk_known;
2292 return 0; 2520 return 0;
2293} 2521}
2294 2522
@@ -2460,8 +2688,8 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
2460 struct super_block *sbp; 2688 struct super_block *sbp;
2461 struct superblock_smack *sbsp; 2689 struct superblock_smack *sbsp;
2462 struct inode_smack *isp; 2690 struct inode_smack *isp;
2463 char *csp = smk_of_current(); 2691 struct smack_known *skp;
2464 char *fetched; 2692 struct smack_known *ckp = smk_of_current();
2465 char *final; 2693 char *final;
2466 char trattr[TRANS_TRUE_SIZE]; 2694 char trattr[TRANS_TRUE_SIZE];
2467 int transflag = 0; 2695 int transflag = 0;
@@ -2528,7 +2756,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
2528 * Programs that change smack have to treat the 2756 * Programs that change smack have to treat the
2529 * pty with respect. 2757 * pty with respect.
2530 */ 2758 */
2531 final = csp; 2759 final = ckp->smk_known;
2532 break; 2760 break;
2533 case SOCKFS_MAGIC: 2761 case SOCKFS_MAGIC:
2534 /* 2762 /*
@@ -2583,9 +2811,9 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
2583 * Get the dentry for xattr. 2811 * Get the dentry for xattr.
2584 */ 2812 */
2585 dp = dget(opt_dentry); 2813 dp = dget(opt_dentry);
2586 fetched = smk_fetch(XATTR_NAME_SMACK, inode, dp); 2814 skp = smk_fetch(XATTR_NAME_SMACK, inode, dp);
2587 if (fetched != NULL) 2815 if (skp != NULL)
2588 final = fetched; 2816 final = skp->smk_known;
2589 2817
2590 /* 2818 /*
2591 * Transmuting directory 2819 * Transmuting directory
@@ -2625,7 +2853,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
2625 } 2853 }
2626 2854
2627 if (final == NULL) 2855 if (final == NULL)
2628 isp->smk_inode = csp; 2856 isp->smk_inode = ckp->smk_known;
2629 else 2857 else
2630 isp->smk_inode = final; 2858 isp->smk_inode = final;
2631 2859
@@ -2648,13 +2876,14 @@ unlockandout:
2648 */ 2876 */
2649static int smack_getprocattr(struct task_struct *p, char *name, char **value) 2877static int smack_getprocattr(struct task_struct *p, char *name, char **value)
2650{ 2878{
2879 struct smack_known *skp = smk_of_task(task_security(p));
2651 char *cp; 2880 char *cp;
2652 int slen; 2881 int slen;
2653 2882
2654 if (strcmp(name, "current") != 0) 2883 if (strcmp(name, "current") != 0)
2655 return -EINVAL; 2884 return -EINVAL;
2656 2885
2657 cp = kstrdup(smk_of_task(task_security(p)), GFP_KERNEL); 2886 cp = kstrdup(skp->smk_known, GFP_KERNEL);
2658 if (cp == NULL) 2887 if (cp == NULL)
2659 return -ENOMEM; 2888 return -ENOMEM;
2660 2889
@@ -2680,7 +2909,7 @@ static int smack_setprocattr(struct task_struct *p, char *name,
2680{ 2909{
2681 struct task_smack *tsp; 2910 struct task_smack *tsp;
2682 struct cred *new; 2911 struct cred *new;
2683 char *newsmack; 2912 struct smack_known *skp;
2684 2913
2685 /* 2914 /*
2686 * Changing another process' Smack value is too dangerous 2915 * Changing another process' Smack value is too dangerous
@@ -2698,14 +2927,14 @@ static int smack_setprocattr(struct task_struct *p, char *name,
2698 if (strcmp(name, "current") != 0) 2927 if (strcmp(name, "current") != 0)
2699 return -EINVAL; 2928 return -EINVAL;
2700 2929
2701 newsmack = smk_import(value, size); 2930 skp = smk_import_entry(value, size);
2702 if (newsmack == NULL) 2931 if (skp == NULL)
2703 return -EINVAL; 2932 return -EINVAL;
2704 2933
2705 /* 2934 /*
2706 * No process is ever allowed the web ("@") label. 2935 * No process is ever allowed the web ("@") label.
2707 */ 2936 */
2708 if (newsmack == smack_known_web.smk_known) 2937 if (skp == &smack_known_web)
2709 return -EPERM; 2938 return -EPERM;
2710 2939
2711 new = prepare_creds(); 2940 new = prepare_creds();
@@ -2713,7 +2942,7 @@ static int smack_setprocattr(struct task_struct *p, char *name,
2713 return -ENOMEM; 2942 return -ENOMEM;
2714 2943
2715 tsp = new->security; 2944 tsp = new->security;
2716 tsp->smk_task = newsmack; 2945 tsp->smk_task = skp;
2717 2946
2718 commit_creds(new); 2947 commit_creds(new);
2719 return size; 2948 return size;
@@ -2731,6 +2960,7 @@ static int smack_setprocattr(struct task_struct *p, char *name,
2731static int smack_unix_stream_connect(struct sock *sock, 2960static int smack_unix_stream_connect(struct sock *sock,
2732 struct sock *other, struct sock *newsk) 2961 struct sock *other, struct sock *newsk)
2733{ 2962{
2963 struct smack_known *skp;
2734 struct socket_smack *ssp = sock->sk_security; 2964 struct socket_smack *ssp = sock->sk_security;
2735 struct socket_smack *osp = other->sk_security; 2965 struct socket_smack *osp = other->sk_security;
2736 struct socket_smack *nsp = newsk->sk_security; 2966 struct socket_smack *nsp = newsk->sk_security;
@@ -2744,15 +2974,17 @@ static int smack_unix_stream_connect(struct sock *sock,
2744 smk_ad_setfield_u_net_sk(&ad, other); 2974 smk_ad_setfield_u_net_sk(&ad, other);
2745#endif 2975#endif
2746 2976
2747 if (!smack_privileged(CAP_MAC_OVERRIDE)) 2977 if (!smack_privileged(CAP_MAC_OVERRIDE)) {
2748 rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad); 2978 skp = ssp->smk_out;
2979 rc = smk_access(skp, osp->smk_in, MAY_WRITE, &ad);
2980 }
2749 2981
2750 /* 2982 /*
2751 * Cross reference the peer labels for SO_PEERSEC. 2983 * Cross reference the peer labels for SO_PEERSEC.
2752 */ 2984 */
2753 if (rc == 0) { 2985 if (rc == 0) {
2754 nsp->smk_packet = ssp->smk_out; 2986 nsp->smk_packet = ssp->smk_out->smk_known;
2755 ssp->smk_packet = osp->smk_out; 2987 ssp->smk_packet = osp->smk_out->smk_known;
2756 } 2988 }
2757 2989
2758 return rc; 2990 return rc;
@@ -2770,8 +3002,8 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other)
2770{ 3002{
2771 struct socket_smack *ssp = sock->sk->sk_security; 3003 struct socket_smack *ssp = sock->sk->sk_security;
2772 struct socket_smack *osp = other->sk->sk_security; 3004 struct socket_smack *osp = other->sk->sk_security;
3005 struct smack_known *skp;
2773 struct smk_audit_info ad; 3006 struct smk_audit_info ad;
2774 int rc = 0;
2775 3007
2776#ifdef CONFIG_AUDIT 3008#ifdef CONFIG_AUDIT
2777 struct lsm_network_audit net; 3009 struct lsm_network_audit net;
@@ -2780,10 +3012,11 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other)
2780 smk_ad_setfield_u_net_sk(&ad, other->sk); 3012 smk_ad_setfield_u_net_sk(&ad, other->sk);
2781#endif 3013#endif
2782 3014
2783 if (!smack_privileged(CAP_MAC_OVERRIDE)) 3015 if (smack_privileged(CAP_MAC_OVERRIDE))
2784 rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad); 3016 return 0;
2785 3017
2786 return rc; 3018 skp = ssp->smk_out;
3019 return smk_access(skp, osp->smk_in, MAY_WRITE, &ad);
2787} 3020}
2788 3021
2789/** 3022/**
@@ -2792,22 +3025,32 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other)
2792 * @msg: the message 3025 * @msg: the message
2793 * @size: the size of the message 3026 * @size: the size of the message
2794 * 3027 *
2795 * Return 0 if the current subject can write to the destination 3028 * Return 0 if the current subject can write to the destination host.
2796 * host. This is only a question if the destination is a single 3029 * For IPv4 this is only a question if the destination is a single label host.
2797 * label host. 3030 * For IPv6 this is a check against the label of the port.
2798 */ 3031 */
2799static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg, 3032static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg,
2800 int size) 3033 int size)
2801{ 3034{
2802 struct sockaddr_in *sip = (struct sockaddr_in *) msg->msg_name; 3035 struct sockaddr_in *sip = (struct sockaddr_in *) msg->msg_name;
3036 struct sockaddr_in6 *sap = (struct sockaddr_in6 *) msg->msg_name;
3037 int rc = 0;
2803 3038
2804 /* 3039 /*
2805 * Perfectly reasonable for this to be NULL 3040 * Perfectly reasonable for this to be NULL
2806 */ 3041 */
2807 if (sip == NULL || sip->sin_family != AF_INET) 3042 if (sip == NULL)
2808 return 0; 3043 return 0;
2809 3044
2810 return smack_netlabel_send(sock->sk, sip); 3045 switch (sip->sin_family) {
3046 case AF_INET:
3047 rc = smack_netlabel_send(sock->sk, sip);
3048 break;
3049 case AF_INET6:
3050 rc = smk_ipv6_port_check(sock->sk, sap, SMK_SENDING);
3051 break;
3052 }
3053 return rc;
2811} 3054}
2812 3055
2813/** 3056/**
@@ -2815,13 +3058,12 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg,
2815 * @sap: netlabel secattr 3058 * @sap: netlabel secattr
2816 * @ssp: socket security information 3059 * @ssp: socket security information
2817 * 3060 *
2818 * Returns a pointer to a Smack label found on the label list. 3061 * Returns a pointer to a Smack label entry found on the label list.
2819 */ 3062 */
2820static char *smack_from_secattr(struct netlbl_lsm_secattr *sap, 3063static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap,
2821 struct socket_smack *ssp) 3064 struct socket_smack *ssp)
2822{ 3065{
2823 struct smack_known *kp; 3066 struct smack_known *skp;
2824 char *sp;
2825 int found = 0; 3067 int found = 0;
2826 3068
2827 if ((sap->flags & NETLBL_SECATTR_MLS_LVL) != 0) { 3069 if ((sap->flags & NETLBL_SECATTR_MLS_LVL) != 0) {
@@ -2836,11 +3078,11 @@ static char *smack_from_secattr(struct netlbl_lsm_secattr *sap,
2836 * ambient value. 3078 * ambient value.
2837 */ 3079 */
2838 rcu_read_lock(); 3080 rcu_read_lock();
2839 list_for_each_entry(kp, &smack_known_list, list) { 3081 list_for_each_entry(skp, &smack_known_list, list) {
2840 if (sap->attr.mls.lvl != kp->smk_netlabel.attr.mls.lvl) 3082 if (sap->attr.mls.lvl != skp->smk_netlabel.attr.mls.lvl)
2841 continue; 3083 continue;
2842 if (memcmp(sap->attr.mls.cat, 3084 if (memcmp(sap->attr.mls.cat,
2843 kp->smk_netlabel.attr.mls.cat, 3085 skp->smk_netlabel.attr.mls.cat,
2844 SMK_CIPSOLEN) != 0) 3086 SMK_CIPSOLEN) != 0)
2845 continue; 3087 continue;
2846 found = 1; 3088 found = 1;
@@ -2849,17 +3091,17 @@ static char *smack_from_secattr(struct netlbl_lsm_secattr *sap,
2849 rcu_read_unlock(); 3091 rcu_read_unlock();
2850 3092
2851 if (found) 3093 if (found)
2852 return kp->smk_known; 3094 return skp;
2853 3095
2854 if (ssp != NULL && ssp->smk_in == smack_known_star.smk_known) 3096 if (ssp != NULL && ssp->smk_in == smack_known_star.smk_known)
2855 return smack_known_web.smk_known; 3097 return &smack_known_web;
2856 return smack_known_star.smk_known; 3098 return &smack_known_star;
2857 } 3099 }
2858 if ((sap->flags & NETLBL_SECATTR_SECID) != 0) { 3100 if ((sap->flags & NETLBL_SECATTR_SECID) != 0) {
2859 /* 3101 /*
2860 * Looks like a fallback, which gives us a secid. 3102 * Looks like a fallback, which gives us a secid.
2861 */ 3103 */
2862 sp = smack_from_secid(sap->attr.secid); 3104 skp = smack_from_secid(sap->attr.secid);
2863 /* 3105 /*
2864 * This has got to be a bug because it is 3106 * This has got to be a bug because it is
2865 * impossible to specify a fallback without 3107 * impossible to specify a fallback without
@@ -2867,8 +3109,8 @@ static char *smack_from_secattr(struct netlbl_lsm_secattr *sap,
2867 * it has a secid, and the only way to get a 3109 * it has a secid, and the only way to get a
2868 * secid is from a fallback. 3110 * secid is from a fallback.
2869 */ 3111 */
2870 BUG_ON(sp == NULL); 3112 BUG_ON(skp == NULL);
2871 return sp; 3113 return skp;
2872 } 3114 }
2873 /* 3115 /*
2874 * Without guidance regarding the smack value 3116 * Without guidance regarding the smack value
@@ -2878,6 +3120,53 @@ static char *smack_from_secattr(struct netlbl_lsm_secattr *sap,
2878 return smack_net_ambient; 3120 return smack_net_ambient;
2879} 3121}
2880 3122
3123static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr_in6 *sip)
3124{
3125 u8 nexthdr;
3126 int offset;
3127 int proto = -EINVAL;
3128 struct ipv6hdr _ipv6h;
3129 struct ipv6hdr *ip6;
3130 __be16 frag_off;
3131 struct tcphdr _tcph, *th;
3132 struct udphdr _udph, *uh;
3133 struct dccp_hdr _dccph, *dh;
3134
3135 sip->sin6_port = 0;
3136
3137 offset = skb_network_offset(skb);
3138 ip6 = skb_header_pointer(skb, offset, sizeof(_ipv6h), &_ipv6h);
3139 if (ip6 == NULL)
3140 return -EINVAL;
3141 sip->sin6_addr = ip6->saddr;
3142
3143 nexthdr = ip6->nexthdr;
3144 offset += sizeof(_ipv6h);
3145 offset = ipv6_skip_exthdr(skb, offset, &nexthdr, &frag_off);
3146 if (offset < 0)
3147 return -EINVAL;
3148
3149 proto = nexthdr;
3150 switch (proto) {
3151 case IPPROTO_TCP:
3152 th = skb_header_pointer(skb, offset, sizeof(_tcph), &_tcph);
3153 if (th != NULL)
3154 sip->sin6_port = th->source;
3155 break;
3156 case IPPROTO_UDP:
3157 uh = skb_header_pointer(skb, offset, sizeof(_udph), &_udph);
3158 if (uh != NULL)
3159 sip->sin6_port = uh->source;
3160 break;
3161 case IPPROTO_DCCP:
3162 dh = skb_header_pointer(skb, offset, sizeof(_dccph), &_dccph);
3163 if (dh != NULL)
3164 sip->sin6_port = dh->dccph_sport;
3165 break;
3166 }
3167 return proto;
3168}
3169
2881/** 3170/**
2882 * smack_socket_sock_rcv_skb - Smack packet delivery access check 3171 * smack_socket_sock_rcv_skb - Smack packet delivery access check
2883 * @sk: socket 3172 * @sk: socket
@@ -2889,43 +3178,52 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
2889{ 3178{
2890 struct netlbl_lsm_secattr secattr; 3179 struct netlbl_lsm_secattr secattr;
2891 struct socket_smack *ssp = sk->sk_security; 3180 struct socket_smack *ssp = sk->sk_security;
2892 char *csp; 3181 struct smack_known *skp;
2893 int rc; 3182 struct sockaddr_in6 sadd;
3183 int rc = 0;
2894 struct smk_audit_info ad; 3184 struct smk_audit_info ad;
2895#ifdef CONFIG_AUDIT 3185#ifdef CONFIG_AUDIT
2896 struct lsm_network_audit net; 3186 struct lsm_network_audit net;
2897#endif 3187#endif
2898 if (sk->sk_family != PF_INET && sk->sk_family != PF_INET6) 3188 switch (sk->sk_family) {
2899 return 0; 3189 case PF_INET:
2900 3190 /*
2901 /* 3191 * Translate what netlabel gave us.
2902 * Translate what netlabel gave us. 3192 */
2903 */ 3193 netlbl_secattr_init(&secattr);
2904 netlbl_secattr_init(&secattr);
2905 3194
2906 rc = netlbl_skbuff_getattr(skb, sk->sk_family, &secattr); 3195 rc = netlbl_skbuff_getattr(skb, sk->sk_family, &secattr);
2907 if (rc == 0) 3196 if (rc == 0)
2908 csp = smack_from_secattr(&secattr, ssp); 3197 skp = smack_from_secattr(&secattr, ssp);
2909 else 3198 else
2910 csp = smack_net_ambient; 3199 skp = smack_net_ambient;
2911 3200
2912 netlbl_secattr_destroy(&secattr); 3201 netlbl_secattr_destroy(&secattr);
2913 3202
2914#ifdef CONFIG_AUDIT 3203#ifdef CONFIG_AUDIT
2915 smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); 3204 smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
2916 ad.a.u.net->family = sk->sk_family; 3205 ad.a.u.net->family = sk->sk_family;
2917 ad.a.u.net->netif = skb->skb_iif; 3206 ad.a.u.net->netif = skb->skb_iif;
2918 ipv4_skb_to_auditdata(skb, &ad.a, NULL); 3207 ipv4_skb_to_auditdata(skb, &ad.a, NULL);
2919#endif 3208#endif
2920 /* 3209 /*
2921 * Receiving a packet requires that the other end 3210 * Receiving a packet requires that the other end
2922 * be able to write here. Read access is not required. 3211 * be able to write here. Read access is not required.
2923 * This is the simplist possible security model 3212 * This is the simplist possible security model
2924 * for networking. 3213 * for networking.
2925 */ 3214 */
2926 rc = smk_access(csp, ssp->smk_in, MAY_WRITE, &ad); 3215 rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad);
2927 if (rc != 0) 3216 if (rc != 0)
2928 netlbl_skbuff_err(skb, rc, 0); 3217 netlbl_skbuff_err(skb, rc, 0);
3218 break;
3219 case PF_INET6:
3220 rc = smk_skb_to_addr_ipv6(skb, &sadd);
3221 if (rc == IPPROTO_UDP || rc == IPPROTO_TCP)
3222 rc = smk_ipv6_port_check(sk, &sadd, SMK_RECEIVING);
3223 else
3224 rc = 0;
3225 break;
3226 }
2929 return rc; 3227 return rc;
2930} 3228}
2931 3229
@@ -2979,7 +3277,7 @@ static int smack_socket_getpeersec_dgram(struct socket *sock,
2979{ 3277{
2980 struct netlbl_lsm_secattr secattr; 3278 struct netlbl_lsm_secattr secattr;
2981 struct socket_smack *ssp = NULL; 3279 struct socket_smack *ssp = NULL;
2982 char *sp; 3280 struct smack_known *skp;
2983 int family = PF_UNSPEC; 3281 int family = PF_UNSPEC;
2984 u32 s = 0; /* 0 is the invalid secid */ 3282 u32 s = 0; /* 0 is the invalid secid */
2985 int rc; 3283 int rc;
@@ -2995,7 +3293,7 @@ static int smack_socket_getpeersec_dgram(struct socket *sock,
2995 3293
2996 if (family == PF_UNIX) { 3294 if (family == PF_UNIX) {
2997 ssp = sock->sk->sk_security; 3295 ssp = sock->sk->sk_security;
2998 s = smack_to_secid(ssp->smk_out); 3296 s = ssp->smk_out->smk_secid;
2999 } else if (family == PF_INET || family == PF_INET6) { 3297 } else if (family == PF_INET || family == PF_INET6) {
3000 /* 3298 /*
3001 * Translate what netlabel gave us. 3299 * Translate what netlabel gave us.
@@ -3005,8 +3303,8 @@ static int smack_socket_getpeersec_dgram(struct socket *sock,
3005 netlbl_secattr_init(&secattr); 3303 netlbl_secattr_init(&secattr);
3006 rc = netlbl_skbuff_getattr(skb, family, &secattr); 3304 rc = netlbl_skbuff_getattr(skb, family, &secattr);
3007 if (rc == 0) { 3305 if (rc == 0) {
3008 sp = smack_from_secattr(&secattr, ssp); 3306 skp = smack_from_secattr(&secattr, ssp);
3009 s = smack_to_secid(sp); 3307 s = skp->smk_secid;
3010 } 3308 }
3011 netlbl_secattr_destroy(&secattr); 3309 netlbl_secattr_destroy(&secattr);
3012 } 3310 }
@@ -3027,13 +3325,15 @@ static int smack_socket_getpeersec_dgram(struct socket *sock,
3027static void smack_sock_graft(struct sock *sk, struct socket *parent) 3325static void smack_sock_graft(struct sock *sk, struct socket *parent)
3028{ 3326{
3029 struct socket_smack *ssp; 3327 struct socket_smack *ssp;
3328 struct smack_known *skp = smk_of_current();
3030 3329
3031 if (sk == NULL || 3330 if (sk == NULL ||
3032 (sk->sk_family != PF_INET && sk->sk_family != PF_INET6)) 3331 (sk->sk_family != PF_INET && sk->sk_family != PF_INET6))
3033 return; 3332 return;
3034 3333
3035 ssp = sk->sk_security; 3334 ssp = sk->sk_security;
3036 ssp->smk_in = ssp->smk_out = smk_of_current(); 3335 ssp->smk_in = skp->smk_known;
3336 ssp->smk_out = skp;
3037 /* cssp->smk_packet is already set in smack_inet_csk_clone() */ 3337 /* cssp->smk_packet is already set in smack_inet_csk_clone() */
3038} 3338}
3039 3339
@@ -3055,7 +3355,6 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
3055 struct netlbl_lsm_secattr secattr; 3355 struct netlbl_lsm_secattr secattr;
3056 struct sockaddr_in addr; 3356 struct sockaddr_in addr;
3057 struct iphdr *hdr; 3357 struct iphdr *hdr;
3058 char *sp;
3059 char *hsp; 3358 char *hsp;
3060 int rc; 3359 int rc;
3061 struct smk_audit_info ad; 3360 struct smk_audit_info ad;
@@ -3063,16 +3362,24 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
3063 struct lsm_network_audit net; 3362 struct lsm_network_audit net;
3064#endif 3363#endif
3065 3364
3066 /* handle mapped IPv4 packets arriving via IPv6 sockets */ 3365 if (family == PF_INET6) {
3067 if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP)) 3366 /*
3068 family = PF_INET; 3367 * Handle mapped IPv4 packets arriving
3368 * via IPv6 sockets. Don't set up netlabel
3369 * processing on IPv6.
3370 */
3371 if (skb->protocol == htons(ETH_P_IP))
3372 family = PF_INET;
3373 else
3374 return 0;
3375 }
3069 3376
3070 netlbl_secattr_init(&secattr); 3377 netlbl_secattr_init(&secattr);
3071 rc = netlbl_skbuff_getattr(skb, family, &secattr); 3378 rc = netlbl_skbuff_getattr(skb, family, &secattr);
3072 if (rc == 0) 3379 if (rc == 0)
3073 sp = smack_from_secattr(&secattr, ssp); 3380 skp = smack_from_secattr(&secattr, ssp);
3074 else 3381 else
3075 sp = smack_known_huh.smk_known; 3382 skp = &smack_known_huh;
3076 netlbl_secattr_destroy(&secattr); 3383 netlbl_secattr_destroy(&secattr);
3077 3384
3078#ifdef CONFIG_AUDIT 3385#ifdef CONFIG_AUDIT
@@ -3085,7 +3392,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
3085 * Receiving a packet requires that the other end be able to write 3392 * Receiving a packet requires that the other end be able to write
3086 * here. Read access is not required. 3393 * here. Read access is not required.
3087 */ 3394 */
3088 rc = smk_access(sp, ssp->smk_in, MAY_WRITE, &ad); 3395 rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad);
3089 if (rc != 0) 3396 if (rc != 0)
3090 return rc; 3397 return rc;
3091 3398
@@ -3093,7 +3400,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
3093 * Save the peer's label in the request_sock so we can later setup 3400 * Save the peer's label in the request_sock so we can later setup
3094 * smk_packet in the child socket so that SO_PEERCRED can report it. 3401 * smk_packet in the child socket so that SO_PEERCRED can report it.
3095 */ 3402 */
3096 req->peer_secid = smack_to_secid(sp); 3403 req->peer_secid = skp->smk_secid;
3097 3404
3098 /* 3405 /*
3099 * We need to decide if we want to label the incoming connection here 3406 * We need to decide if we want to label the incoming connection here
@@ -3106,10 +3413,9 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
3106 hsp = smack_host_label(&addr); 3413 hsp = smack_host_label(&addr);
3107 rcu_read_unlock(); 3414 rcu_read_unlock();
3108 3415
3109 if (hsp == NULL) { 3416 if (hsp == NULL)
3110 skp = smk_find_entry(sp);
3111 rc = netlbl_req_setattr(req, &skp->smk_netlabel); 3417 rc = netlbl_req_setattr(req, &skp->smk_netlabel);
3112 } else 3418 else
3113 netlbl_req_delattr(req); 3419 netlbl_req_delattr(req);
3114 3420
3115 return rc; 3421 return rc;
@@ -3126,10 +3432,12 @@ static void smack_inet_csk_clone(struct sock *sk,
3126 const struct request_sock *req) 3432 const struct request_sock *req)
3127{ 3433{
3128 struct socket_smack *ssp = sk->sk_security; 3434 struct socket_smack *ssp = sk->sk_security;
3435 struct smack_known *skp;
3129 3436
3130 if (req->peer_secid != 0) 3437 if (req->peer_secid != 0) {
3131 ssp->smk_packet = smack_from_secid(req->peer_secid); 3438 skp = smack_from_secid(req->peer_secid);
3132 else 3439 ssp->smk_packet = skp->smk_known;
3440 } else
3133 ssp->smk_packet = NULL; 3441 ssp->smk_packet = NULL;
3134} 3442}
3135 3443
@@ -3155,7 +3463,9 @@ static void smack_inet_csk_clone(struct sock *sk,
3155static int smack_key_alloc(struct key *key, const struct cred *cred, 3463static int smack_key_alloc(struct key *key, const struct cred *cred,
3156 unsigned long flags) 3464 unsigned long flags)
3157{ 3465{
3158 key->security = smk_of_task(cred->security); 3466 struct smack_known *skp = smk_of_task(cred->security);
3467
3468 key->security = skp->smk_known;
3159 return 0; 3469 return 0;
3160} 3470}
3161 3471
@@ -3184,7 +3494,7 @@ static int smack_key_permission(key_ref_t key_ref,
3184{ 3494{
3185 struct key *keyp; 3495 struct key *keyp;
3186 struct smk_audit_info ad; 3496 struct smk_audit_info ad;
3187 char *tsp = smk_of_task(cred->security); 3497 struct smack_known *tkp = smk_of_task(cred->security);
3188 3498
3189 keyp = key_ref_to_ptr(key_ref); 3499 keyp = key_ref_to_ptr(key_ref);
3190 if (keyp == NULL) 3500 if (keyp == NULL)
@@ -3198,15 +3508,14 @@ static int smack_key_permission(key_ref_t key_ref,
3198 /* 3508 /*
3199 * This should not occur 3509 * This should not occur
3200 */ 3510 */
3201 if (tsp == NULL) 3511 if (tkp == NULL)
3202 return -EACCES; 3512 return -EACCES;
3203#ifdef CONFIG_AUDIT 3513#ifdef CONFIG_AUDIT
3204 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_KEY); 3514 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_KEY);
3205 ad.a.u.key_struct.key = keyp->serial; 3515 ad.a.u.key_struct.key = keyp->serial;
3206 ad.a.u.key_struct.key_desc = keyp->description; 3516 ad.a.u.key_struct.key_desc = keyp->description;
3207#endif 3517#endif
3208 return smk_access(tsp, keyp->security, 3518 return smk_access(tkp, keyp->security, MAY_READWRITE, &ad);
3209 MAY_READWRITE, &ad);
3210} 3519}
3211#endif /* CONFIG_KEYS */ 3520#endif /* CONFIG_KEYS */
3212 3521
@@ -3288,7 +3597,7 @@ static int smack_audit_rule_known(struct audit_krule *krule)
3288static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule, 3597static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule,
3289 struct audit_context *actx) 3598 struct audit_context *actx)
3290{ 3599{
3291 char *smack; 3600 struct smack_known *skp;
3292 char *rule = vrule; 3601 char *rule = vrule;
3293 3602
3294 if (!rule) { 3603 if (!rule) {
@@ -3300,7 +3609,7 @@ static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule,
3300 if (field != AUDIT_SUBJ_USER && field != AUDIT_OBJ_USER) 3609 if (field != AUDIT_SUBJ_USER && field != AUDIT_OBJ_USER)
3301 return 0; 3610 return 0;
3302 3611
3303 smack = smack_from_secid(secid); 3612 skp = smack_from_secid(secid);
3304 3613
3305 /* 3614 /*
3306 * No need to do string comparisons. If a match occurs, 3615 * No need to do string comparisons. If a match occurs,
@@ -3308,9 +3617,9 @@ static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule,
3308 * label. 3617 * label.
3309 */ 3618 */
3310 if (op == Audit_equal) 3619 if (op == Audit_equal)
3311 return (rule == smack); 3620 return (rule == skp->smk_known);
3312 if (op == Audit_not_equal) 3621 if (op == Audit_not_equal)
3313 return (rule != smack); 3622 return (rule != skp->smk_known);
3314 3623
3315 return 0; 3624 return 0;
3316} 3625}
@@ -3329,6 +3638,16 @@ static void smack_audit_rule_free(void *vrule)
3329#endif /* CONFIG_AUDIT */ 3638#endif /* CONFIG_AUDIT */
3330 3639
3331/** 3640/**
3641 * smack_ismaclabel - check if xattr @name references a smack MAC label
3642 * @name: Full xattr name to check.
3643 */
3644static int smack_ismaclabel(const char *name)
3645{
3646 return (strcmp(name, XATTR_SMACK_SUFFIX) == 0);
3647}
3648
3649
3650/**
3332 * smack_secid_to_secctx - return the smack label for a secid 3651 * smack_secid_to_secctx - return the smack label for a secid
3333 * @secid: incoming integer 3652 * @secid: incoming integer
3334 * @secdata: destination 3653 * @secdata: destination
@@ -3338,11 +3657,11 @@ static void smack_audit_rule_free(void *vrule)
3338 */ 3657 */
3339static int smack_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) 3658static int smack_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
3340{ 3659{
3341 char *sp = smack_from_secid(secid); 3660 struct smack_known *skp = smack_from_secid(secid);
3342 3661
3343 if (secdata) 3662 if (secdata)
3344 *secdata = sp; 3663 *secdata = skp->smk_known;
3345 *seclen = strlen(sp); 3664 *seclen = strlen(skp->smk_known);
3346 return 0; 3665 return 0;
3347} 3666}
3348 3667
@@ -3498,6 +3817,7 @@ struct security_operations smack_ops = {
3498 .unix_may_send = smack_unix_may_send, 3817 .unix_may_send = smack_unix_may_send,
3499 3818
3500 .socket_post_create = smack_socket_post_create, 3819 .socket_post_create = smack_socket_post_create,
3820 .socket_bind = smack_socket_bind,
3501 .socket_connect = smack_socket_connect, 3821 .socket_connect = smack_socket_connect,
3502 .socket_sendmsg = smack_socket_sendmsg, 3822 .socket_sendmsg = smack_socket_sendmsg,
3503 .socket_sock_rcv_skb = smack_socket_sock_rcv_skb, 3823 .socket_sock_rcv_skb = smack_socket_sock_rcv_skb,
@@ -3524,6 +3844,7 @@ struct security_operations smack_ops = {
3524 .audit_rule_free = smack_audit_rule_free, 3844 .audit_rule_free = smack_audit_rule_free,
3525#endif /* CONFIG_AUDIT */ 3845#endif /* CONFIG_AUDIT */
3526 3846
3847 .ismaclabel = smack_ismaclabel,
3527 .secid_to_secctx = smack_secid_to_secctx, 3848 .secid_to_secctx = smack_secid_to_secctx,
3528 .secctx_to_secid = smack_secctx_to_secid, 3849 .secctx_to_secid = smack_secctx_to_secid,
3529 .release_secctx = smack_release_secctx, 3850 .release_secctx = smack_release_secctx,
@@ -3577,8 +3898,8 @@ static __init int smack_init(void)
3577 if (!security_module_enable(&smack_ops)) 3898 if (!security_module_enable(&smack_ops))
3578 return 0; 3899 return 0;
3579 3900
3580 tsp = new_task_smack(smack_known_floor.smk_known, 3901 tsp = new_task_smack(&smack_known_floor, &smack_known_floor,
3581 smack_known_floor.smk_known, GFP_KERNEL); 3902 GFP_KERNEL);
3582 if (tsp == NULL) 3903 if (tsp == NULL)
3583 return -ENOMEM; 3904 return -ENOMEM;
3584 3905
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index 53a08b85bda4..ab167037b2dd 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -66,7 +66,7 @@ static DEFINE_MUTEX(smk_netlbladdr_lock);
66 * If it isn't somehow marked, use this. 66 * If it isn't somehow marked, use this.
67 * It can be reset via smackfs/ambient 67 * It can be reset via smackfs/ambient
68 */ 68 */
69char *smack_net_ambient; 69struct smack_known *smack_net_ambient;
70 70
71/* 71/*
72 * This is the level in a CIPSO header that indicates a 72 * This is the level in a CIPSO header that indicates a
@@ -112,7 +112,7 @@ struct smack_master_list {
112LIST_HEAD(smack_rule_list); 112LIST_HEAD(smack_rule_list);
113 113
114struct smack_parsed_rule { 114struct smack_parsed_rule {
115 char *smk_subject; 115 struct smack_known *smk_subject;
116 char *smk_object; 116 char *smk_object;
117 int smk_access1; 117 int smk_access1;
118 int smk_access2; 118 int smk_access2;
@@ -163,9 +163,11 @@ static inline void smack_catset_bit(unsigned int cat, char *catsetp)
163 */ 163 */
164static void smk_netlabel_audit_set(struct netlbl_audit *nap) 164static void smk_netlabel_audit_set(struct netlbl_audit *nap)
165{ 165{
166 struct smack_known *skp = smk_of_current();
167
166 nap->loginuid = audit_get_loginuid(current); 168 nap->loginuid = audit_get_loginuid(current);
167 nap->sessionid = audit_get_sessionid(current); 169 nap->sessionid = audit_get_sessionid(current);
168 nap->secid = smack_to_secid(smk_of_current()); 170 nap->secid = skp->smk_secid;
169} 171}
170 172
171/* 173/*
@@ -306,7 +308,7 @@ static int smk_fill_rule(const char *subject, const char *object,
306 struct smack_known *skp; 308 struct smack_known *skp;
307 309
308 if (import) { 310 if (import) {
309 rule->smk_subject = smk_import(subject, len); 311 rule->smk_subject = smk_import_entry(subject, len);
310 if (rule->smk_subject == NULL) 312 if (rule->smk_subject == NULL)
311 return -1; 313 return -1;
312 314
@@ -321,7 +323,7 @@ static int smk_fill_rule(const char *subject, const char *object,
321 kfree(cp); 323 kfree(cp);
322 if (skp == NULL) 324 if (skp == NULL)
323 return -1; 325 return -1;
324 rule->smk_subject = skp->smk_known; 326 rule->smk_subject = skp;
325 327
326 cp = smk_parse_smack(object, len); 328 cp = smk_parse_smack(object, len);
327 if (cp == NULL) 329 if (cp == NULL)
@@ -445,7 +447,6 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf,
445 struct list_head *rule_list, 447 struct list_head *rule_list,
446 struct mutex *rule_lock, int format) 448 struct mutex *rule_lock, int format)
447{ 449{
448 struct smack_known *skp;
449 struct smack_parsed_rule *rule; 450 struct smack_parsed_rule *rule;
450 char *data; 451 char *data;
451 int datalen; 452 int datalen;
@@ -505,12 +506,10 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf,
505 goto out_free_rule; 506 goto out_free_rule;
506 } 507 }
507 508
508
509 if (rule_list == NULL) { 509 if (rule_list == NULL) {
510 load = 1; 510 load = 1;
511 skp = smk_find_entry(rule->smk_subject); 511 rule_list = &rule->smk_subject->smk_rules;
512 rule_list = &skp->smk_rules; 512 rule_lock = &rule->smk_subject->smk_rules_lock;
513 rule_lock = &skp->smk_rules_lock;
514 } 513 }
515 514
516 rc = smk_set_access(rule, rule_list, rule_lock, load); 515 rc = smk_set_access(rule, rule_list, rule_lock, load);
@@ -579,13 +578,14 @@ static void smk_rule_show(struct seq_file *s, struct smack_rule *srp, int max)
579 * because you should expect to be able to write 578 * because you should expect to be able to write
580 * anything you read back. 579 * anything you read back.
581 */ 580 */
582 if (strlen(srp->smk_subject) >= max || strlen(srp->smk_object) >= max) 581 if (strlen(srp->smk_subject->smk_known) >= max ||
582 strlen(srp->smk_object) >= max)
583 return; 583 return;
584 584
585 if (srp->smk_access == 0) 585 if (srp->smk_access == 0)
586 return; 586 return;
587 587
588 seq_printf(s, "%s %s", srp->smk_subject, srp->smk_object); 588 seq_printf(s, "%s %s", srp->smk_subject->smk_known, srp->smk_object);
589 589
590 seq_putc(s, ' '); 590 seq_putc(s, ' ');
591 591
@@ -738,9 +738,9 @@ static void smk_unlbl_ambient(char *oldambient)
738 __func__, __LINE__, rc); 738 __func__, __LINE__, rc);
739 } 739 }
740 if (smack_net_ambient == NULL) 740 if (smack_net_ambient == NULL)
741 smack_net_ambient = smack_known_floor.smk_known; 741 smack_net_ambient = &smack_known_floor;
742 742
743 rc = netlbl_cfg_unlbl_map_add(smack_net_ambient, PF_INET, 743 rc = netlbl_cfg_unlbl_map_add(smack_net_ambient->smk_known, PF_INET,
744 NULL, NULL, &nai); 744 NULL, NULL, &nai);
745 if (rc != 0) 745 if (rc != 0)
746 printk(KERN_WARNING "%s:%d add rc = %d\n", 746 printk(KERN_WARNING "%s:%d add rc = %d\n",
@@ -881,7 +881,7 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf,
881 if (format == SMK_FIXED24_FMT) 881 if (format == SMK_FIXED24_FMT)
882 rule += SMK_LABELLEN; 882 rule += SMK_LABELLEN;
883 else 883 else
884 rule += strlen(skp->smk_known); 884 rule += strlen(skp->smk_known) + 1;
885 885
886 ret = sscanf(rule, "%d", &maplevel); 886 ret = sscanf(rule, "%d", &maplevel);
887 if (ret != 1 || maplevel > SMACK_CIPSO_MAXLEVEL) 887 if (ret != 1 || maplevel > SMACK_CIPSO_MAXLEVEL)
@@ -1535,11 +1535,12 @@ static ssize_t smk_read_ambient(struct file *filp, char __user *buf,
1535 */ 1535 */
1536 mutex_lock(&smack_ambient_lock); 1536 mutex_lock(&smack_ambient_lock);
1537 1537
1538 asize = strlen(smack_net_ambient) + 1; 1538 asize = strlen(smack_net_ambient->smk_known) + 1;
1539 1539
1540 if (cn >= asize) 1540 if (cn >= asize)
1541 rc = simple_read_from_buffer(buf, cn, ppos, 1541 rc = simple_read_from_buffer(buf, cn, ppos,
1542 smack_net_ambient, asize); 1542 smack_net_ambient->smk_known,
1543 asize);
1543 else 1544 else
1544 rc = -EINVAL; 1545 rc = -EINVAL;
1545 1546
@@ -1560,8 +1561,8 @@ static ssize_t smk_read_ambient(struct file *filp, char __user *buf,
1560static ssize_t smk_write_ambient(struct file *file, const char __user *buf, 1561static ssize_t smk_write_ambient(struct file *file, const char __user *buf,
1561 size_t count, loff_t *ppos) 1562 size_t count, loff_t *ppos)
1562{ 1563{
1564 struct smack_known *skp;
1563 char *oldambient; 1565 char *oldambient;
1564 char *smack = NULL;
1565 char *data; 1566 char *data;
1566 int rc = count; 1567 int rc = count;
1567 1568
@@ -1577,16 +1578,16 @@ static ssize_t smk_write_ambient(struct file *file, const char __user *buf,
1577 goto out; 1578 goto out;
1578 } 1579 }
1579 1580
1580 smack = smk_import(data, count); 1581 skp = smk_import_entry(data, count);
1581 if (smack == NULL) { 1582 if (skp == NULL) {
1582 rc = -EINVAL; 1583 rc = -EINVAL;
1583 goto out; 1584 goto out;
1584 } 1585 }
1585 1586
1586 mutex_lock(&smack_ambient_lock); 1587 mutex_lock(&smack_ambient_lock);
1587 1588
1588 oldambient = smack_net_ambient; 1589 oldambient = smack_net_ambient->smk_known;
1589 smack_net_ambient = smack; 1590 smack_net_ambient = skp;
1590 smk_unlbl_ambient(oldambient); 1591 smk_unlbl_ambient(oldambient);
1591 1592
1592 mutex_unlock(&smack_ambient_lock); 1593 mutex_unlock(&smack_ambient_lock);
@@ -1645,7 +1646,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf,
1645 size_t count, loff_t *ppos) 1646 size_t count, loff_t *ppos)
1646{ 1647{
1647 char *data; 1648 char *data;
1648 char *sp = smk_of_task(current->cred->security); 1649 struct smack_known *skp = smk_of_task(current->cred->security);
1649 int rc = count; 1650 int rc = count;
1650 1651
1651 if (!smack_privileged(CAP_MAC_ADMIN)) 1652 if (!smack_privileged(CAP_MAC_ADMIN))
@@ -1656,7 +1657,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf,
1656 * explicitly for clarity. The smk_access() implementation 1657 * explicitly for clarity. The smk_access() implementation
1657 * would use smk_access(smack_onlycap, MAY_WRITE) 1658 * would use smk_access(smack_onlycap, MAY_WRITE)
1658 */ 1659 */
1659 if (smack_onlycap != NULL && smack_onlycap != sp) 1660 if (smack_onlycap != NULL && smack_onlycap != skp->smk_known)
1660 return -EPERM; 1661 return -EPERM;
1661 1662
1662 data = kzalloc(count, GFP_KERNEL); 1663 data = kzalloc(count, GFP_KERNEL);
@@ -1866,8 +1867,8 @@ static ssize_t smk_user_access(struct file *file, const char __user *buf,
1866 if (res) 1867 if (res)
1867 return -EINVAL; 1868 return -EINVAL;
1868 1869
1869 res = smk_access(rule.smk_subject, rule.smk_object, rule.smk_access1, 1870 res = smk_access(rule.smk_subject, rule.smk_object,
1870 NULL); 1871 rule.smk_access1, NULL);
1871 data[0] = res == 0 ? '1' : '0'; 1872 data[0] = res == 0 ? '1' : '0';
1872 data[1] = '\0'; 1873 data[1] = '\0';
1873 1874