aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/Kconfig1
-rw-r--r--security/lsm_audit.c15
-rw-r--r--security/selinux/avc.c6
-rw-r--r--security/selinux/nlmsgtab.c13
-rw-r--r--security/selinux/ss/avtab.c72
-rw-r--r--security/selinux/ss/avtab.h8
-rw-r--r--security/selinux/ss/mls.c10
-rw-r--r--security/selinux/ss/services.c6
-rw-r--r--security/smack/smack.h8
-rw-r--r--security/smack/smack_access.c43
-rw-r--r--security/smack/smack_lsm.c99
-rw-r--r--security/smack/smackfs.c97
-rw-r--r--security/tomoyo/.gitignore2
-rw-r--r--security/tomoyo/Kconfig1
-rw-r--r--security/tomoyo/Makefile55
-rw-r--r--security/tomoyo/policy/exception_policy.conf.default2
-rw-r--r--security/tomoyo/util.c13
-rw-r--r--security/yama/Kconfig2
-rw-r--r--security/yama/yama_lsm.c13
19 files changed, 346 insertions, 120 deletions
diff --git a/security/Kconfig b/security/Kconfig
index beb86b500adf..bf4ec46474b6 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -21,6 +21,7 @@ config SECURITY_DMESG_RESTRICT
21config SECURITY 21config SECURITY
22 bool "Enable different security models" 22 bool "Enable different security models"
23 depends on SYSFS 23 depends on SYSFS
24 depends on MULTIUSER
24 help 25 help
25 This allows you to choose different security modules to be 26 This allows you to choose different security modules to be
26 configured into your kernel. 27 configured into your kernel.
diff --git a/security/lsm_audit.c b/security/lsm_audit.c
index 3b27e9928238..1d34277dc402 100644
--- a/security/lsm_audit.c
+++ b/security/lsm_audit.c
@@ -211,7 +211,7 @@ static inline void print_ipv4_addr(struct audit_buffer *ab, __be32 addr,
211static void dump_common_audit_data(struct audit_buffer *ab, 211static void dump_common_audit_data(struct audit_buffer *ab,
212 struct common_audit_data *a) 212 struct common_audit_data *a)
213{ 213{
214 struct task_struct *tsk = current; 214 char comm[sizeof(current->comm)];
215 215
216 /* 216 /*
217 * To keep stack sizes in check force programers to notice if they 217 * To keep stack sizes in check force programers to notice if they
@@ -220,8 +220,8 @@ static void dump_common_audit_data(struct audit_buffer *ab,
220 */ 220 */
221 BUILD_BUG_ON(sizeof(a->u) > sizeof(void *)*2); 221 BUILD_BUG_ON(sizeof(a->u) > sizeof(void *)*2);
222 222
223 audit_log_format(ab, " pid=%d comm=", task_pid_nr(tsk)); 223 audit_log_format(ab, " pid=%d comm=", task_pid_nr(current));
224 audit_log_untrustedstring(ab, tsk->comm); 224 audit_log_untrustedstring(ab, memcpy(comm, current->comm, sizeof(comm)));
225 225
226 switch (a->type) { 226 switch (a->type) {
227 case LSM_AUDIT_DATA_NONE: 227 case LSM_AUDIT_DATA_NONE:
@@ -276,16 +276,19 @@ static void dump_common_audit_data(struct audit_buffer *ab,
276 audit_log_format(ab, " ino=%lu", inode->i_ino); 276 audit_log_format(ab, " ino=%lu", inode->i_ino);
277 break; 277 break;
278 } 278 }
279 case LSM_AUDIT_DATA_TASK: 279 case LSM_AUDIT_DATA_TASK: {
280 tsk = a->u.tsk; 280 struct task_struct *tsk = a->u.tsk;
281 if (tsk) { 281 if (tsk) {
282 pid_t pid = task_pid_nr(tsk); 282 pid_t pid = task_pid_nr(tsk);
283 if (pid) { 283 if (pid) {
284 char comm[sizeof(tsk->comm)];
284 audit_log_format(ab, " pid=%d comm=", pid); 285 audit_log_format(ab, " pid=%d comm=", pid);
285 audit_log_untrustedstring(ab, tsk->comm); 286 audit_log_untrustedstring(ab,
287 memcpy(comm, tsk->comm, sizeof(comm)));
286 } 288 }
287 } 289 }
288 break; 290 break;
291 }
289 case LSM_AUDIT_DATA_NET: 292 case LSM_AUDIT_DATA_NET:
290 if (a->u.net->sk) { 293 if (a->u.net->sk) {
291 struct sock *sk = a->u.net->sk; 294 struct sock *sk = a->u.net->sk;
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index afcc0aed9393..3c17dda9571d 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -724,12 +724,10 @@ inline int avc_has_perm_noaudit(u32 ssid, u32 tsid,
724 rcu_read_lock(); 724 rcu_read_lock();
725 725
726 node = avc_lookup(ssid, tsid, tclass); 726 node = avc_lookup(ssid, tsid, tclass);
727 if (unlikely(!node)) { 727 if (unlikely(!node))
728 node = avc_compute_av(ssid, tsid, tclass, avd); 728 node = avc_compute_av(ssid, tsid, tclass, avd);
729 } else { 729 else
730 memcpy(avd, &node->ae.avd, sizeof(*avd)); 730 memcpy(avd, &node->ae.avd, sizeof(*avd));
731 avd = &node->ae.avd;
732 }
733 731
734 denied = requested & ~(avd->allowed); 732 denied = requested & ~(avd->allowed);
735 if (unlikely(denied)) 733 if (unlikely(denied))
diff --git a/security/selinux/nlmsgtab.c b/security/selinux/nlmsgtab.c
index 2df7b900e259..2bbb41822d8e 100644
--- a/security/selinux/nlmsgtab.c
+++ b/security/selinux/nlmsgtab.c
@@ -73,6 +73,9 @@ static struct nlmsg_perm nlmsg_route_perms[] =
73 { RTM_NEWMDB, NETLINK_ROUTE_SOCKET__NLMSG_WRITE }, 73 { RTM_NEWMDB, NETLINK_ROUTE_SOCKET__NLMSG_WRITE },
74 { RTM_DELMDB, NETLINK_ROUTE_SOCKET__NLMSG_WRITE }, 74 { RTM_DELMDB, NETLINK_ROUTE_SOCKET__NLMSG_WRITE },
75 { RTM_GETMDB, NETLINK_ROUTE_SOCKET__NLMSG_READ }, 75 { RTM_GETMDB, NETLINK_ROUTE_SOCKET__NLMSG_READ },
76 { RTM_NEWNSID, NETLINK_ROUTE_SOCKET__NLMSG_WRITE },
77 { RTM_DELNSID, NETLINK_ROUTE_SOCKET__NLMSG_READ },
78 { RTM_GETNSID, NETLINK_ROUTE_SOCKET__NLMSG_READ },
76}; 79};
77 80
78static struct nlmsg_perm nlmsg_tcpdiag_perms[] = 81static struct nlmsg_perm nlmsg_tcpdiag_perms[] =
@@ -100,6 +103,13 @@ static struct nlmsg_perm nlmsg_xfrm_perms[] =
100 { XFRM_MSG_FLUSHPOLICY, NETLINK_XFRM_SOCKET__NLMSG_WRITE }, 103 { XFRM_MSG_FLUSHPOLICY, NETLINK_XFRM_SOCKET__NLMSG_WRITE },
101 { XFRM_MSG_NEWAE, NETLINK_XFRM_SOCKET__NLMSG_WRITE }, 104 { XFRM_MSG_NEWAE, NETLINK_XFRM_SOCKET__NLMSG_WRITE },
102 { XFRM_MSG_GETAE, NETLINK_XFRM_SOCKET__NLMSG_READ }, 105 { XFRM_MSG_GETAE, NETLINK_XFRM_SOCKET__NLMSG_READ },
106 { XFRM_MSG_REPORT, NETLINK_XFRM_SOCKET__NLMSG_READ },
107 { XFRM_MSG_MIGRATE, NETLINK_XFRM_SOCKET__NLMSG_WRITE },
108 { XFRM_MSG_NEWSADINFO, NETLINK_XFRM_SOCKET__NLMSG_READ },
109 { XFRM_MSG_GETSADINFO, NETLINK_XFRM_SOCKET__NLMSG_READ },
110 { XFRM_MSG_NEWSPDINFO, NETLINK_XFRM_SOCKET__NLMSG_WRITE },
111 { XFRM_MSG_GETSPDINFO, NETLINK_XFRM_SOCKET__NLMSG_READ },
112 { XFRM_MSG_MAPPING, NETLINK_XFRM_SOCKET__NLMSG_READ },
103}; 113};
104 114
105static struct nlmsg_perm nlmsg_audit_perms[] = 115static struct nlmsg_perm nlmsg_audit_perms[] =
@@ -143,6 +153,8 @@ int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm)
143 153
144 switch (sclass) { 154 switch (sclass) {
145 case SECCLASS_NETLINK_ROUTE_SOCKET: 155 case SECCLASS_NETLINK_ROUTE_SOCKET:
156 /* RTM_MAX always point to RTM_SETxxxx, ie RTM_NEWxxx + 3 */
157 BUILD_BUG_ON(RTM_MAX != (RTM_NEWNSID + 3));
146 err = nlmsg_perm(nlmsg_type, perm, nlmsg_route_perms, 158 err = nlmsg_perm(nlmsg_type, perm, nlmsg_route_perms,
147 sizeof(nlmsg_route_perms)); 159 sizeof(nlmsg_route_perms));
148 break; 160 break;
@@ -153,6 +165,7 @@ int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm)
153 break; 165 break;
154 166
155 case SECCLASS_NETLINK_XFRM_SOCKET: 167 case SECCLASS_NETLINK_XFRM_SOCKET:
168 BUILD_BUG_ON(XFRM_MSG_MAX != XFRM_MSG_MAPPING);
156 err = nlmsg_perm(nlmsg_type, perm, nlmsg_xfrm_perms, 169 err = nlmsg_perm(nlmsg_type, perm, nlmsg_xfrm_perms,
157 sizeof(nlmsg_xfrm_perms)); 170 sizeof(nlmsg_xfrm_perms));
158 break; 171 break;
diff --git a/security/selinux/ss/avtab.c b/security/selinux/ss/avtab.c
index a3dd9faa19c0..b64f2772b030 100644
--- a/security/selinux/ss/avtab.c
+++ b/security/selinux/ss/avtab.c
@@ -25,10 +25,43 @@
25 25
26static struct kmem_cache *avtab_node_cachep; 26static struct kmem_cache *avtab_node_cachep;
27 27
28static inline int avtab_hash(struct avtab_key *keyp, u16 mask) 28/* Based on MurmurHash3, written by Austin Appleby and placed in the
29 * public domain.
30 */
31static inline int avtab_hash(struct avtab_key *keyp, u32 mask)
29{ 32{
30 return ((keyp->target_class + (keyp->target_type << 2) + 33 static const u32 c1 = 0xcc9e2d51;
31 (keyp->source_type << 9)) & mask); 34 static const u32 c2 = 0x1b873593;
35 static const u32 r1 = 15;
36 static const u32 r2 = 13;
37 static const u32 m = 5;
38 static const u32 n = 0xe6546b64;
39
40 u32 hash = 0;
41
42#define mix(input) { \
43 u32 v = input; \
44 v *= c1; \
45 v = (v << r1) | (v >> (32 - r1)); \
46 v *= c2; \
47 hash ^= v; \
48 hash = (hash << r2) | (hash >> (32 - r2)); \
49 hash = hash * m + n; \
50}
51
52 mix(keyp->target_class);
53 mix(keyp->target_type);
54 mix(keyp->source_type);
55
56#undef mix
57
58 hash ^= hash >> 16;
59 hash *= 0x85ebca6b;
60 hash ^= hash >> 13;
61 hash *= 0xc2b2ae35;
62 hash ^= hash >> 16;
63
64 return hash & mask;
32} 65}
33 66
34static struct avtab_node* 67static struct avtab_node*
@@ -46,8 +79,12 @@ avtab_insert_node(struct avtab *h, int hvalue,
46 newnode->next = prev->next; 79 newnode->next = prev->next;
47 prev->next = newnode; 80 prev->next = newnode;
48 } else { 81 } else {
49 newnode->next = h->htable[hvalue]; 82 newnode->next = flex_array_get_ptr(h->htable, hvalue);
50 h->htable[hvalue] = newnode; 83 if (flex_array_put_ptr(h->htable, hvalue, newnode,
84 GFP_KERNEL|__GFP_ZERO)) {
85 kmem_cache_free(avtab_node_cachep, newnode);
86 return NULL;
87 }
51 } 88 }
52 89
53 h->nel++; 90 h->nel++;
@@ -64,7 +101,7 @@ static int avtab_insert(struct avtab *h, struct avtab_key *key, struct avtab_dat
64 return -EINVAL; 101 return -EINVAL;
65 102
66 hvalue = avtab_hash(key, h->mask); 103 hvalue = avtab_hash(key, h->mask);
67 for (prev = NULL, cur = h->htable[hvalue]; 104 for (prev = NULL, cur = flex_array_get_ptr(h->htable, hvalue);
68 cur; 105 cur;
69 prev = cur, cur = cur->next) { 106 prev = cur, cur = cur->next) {
70 if (key->source_type == cur->key.source_type && 107 if (key->source_type == cur->key.source_type &&
@@ -104,7 +141,7 @@ avtab_insert_nonunique(struct avtab *h, struct avtab_key *key, struct avtab_datu
104 if (!h || !h->htable) 141 if (!h || !h->htable)
105 return NULL; 142 return NULL;
106 hvalue = avtab_hash(key, h->mask); 143 hvalue = avtab_hash(key, h->mask);
107 for (prev = NULL, cur = h->htable[hvalue]; 144 for (prev = NULL, cur = flex_array_get_ptr(h->htable, hvalue);
108 cur; 145 cur;
109 prev = cur, cur = cur->next) { 146 prev = cur, cur = cur->next) {
110 if (key->source_type == cur->key.source_type && 147 if (key->source_type == cur->key.source_type &&
@@ -135,7 +172,8 @@ struct avtab_datum *avtab_search(struct avtab *h, struct avtab_key *key)
135 return NULL; 172 return NULL;
136 173
137 hvalue = avtab_hash(key, h->mask); 174 hvalue = avtab_hash(key, h->mask);
138 for (cur = h->htable[hvalue]; cur; cur = cur->next) { 175 for (cur = flex_array_get_ptr(h->htable, hvalue); cur;
176 cur = cur->next) {
139 if (key->source_type == cur->key.source_type && 177 if (key->source_type == cur->key.source_type &&
140 key->target_type == cur->key.target_type && 178 key->target_type == cur->key.target_type &&
141 key->target_class == cur->key.target_class && 179 key->target_class == cur->key.target_class &&
@@ -170,7 +208,8 @@ avtab_search_node(struct avtab *h, struct avtab_key *key)
170 return NULL; 208 return NULL;
171 209
172 hvalue = avtab_hash(key, h->mask); 210 hvalue = avtab_hash(key, h->mask);
173 for (cur = h->htable[hvalue]; cur; cur = cur->next) { 211 for (cur = flex_array_get_ptr(h->htable, hvalue); cur;
212 cur = cur->next) {
174 if (key->source_type == cur->key.source_type && 213 if (key->source_type == cur->key.source_type &&
175 key->target_type == cur->key.target_type && 214 key->target_type == cur->key.target_type &&
176 key->target_class == cur->key.target_class && 215 key->target_class == cur->key.target_class &&
@@ -228,15 +267,14 @@ void avtab_destroy(struct avtab *h)
228 return; 267 return;
229 268
230 for (i = 0; i < h->nslot; i++) { 269 for (i = 0; i < h->nslot; i++) {
231 cur = h->htable[i]; 270 cur = flex_array_get_ptr(h->htable, i);
232 while (cur) { 271 while (cur) {
233 temp = cur; 272 temp = cur;
234 cur = cur->next; 273 cur = cur->next;
235 kmem_cache_free(avtab_node_cachep, temp); 274 kmem_cache_free(avtab_node_cachep, temp);
236 } 275 }
237 h->htable[i] = NULL;
238 } 276 }
239 kfree(h->htable); 277 flex_array_free(h->htable);
240 h->htable = NULL; 278 h->htable = NULL;
241 h->nslot = 0; 279 h->nslot = 0;
242 h->mask = 0; 280 h->mask = 0;
@@ -251,7 +289,7 @@ int avtab_init(struct avtab *h)
251 289
252int avtab_alloc(struct avtab *h, u32 nrules) 290int avtab_alloc(struct avtab *h, u32 nrules)
253{ 291{
254 u16 mask = 0; 292 u32 mask = 0;
255 u32 shift = 0; 293 u32 shift = 0;
256 u32 work = nrules; 294 u32 work = nrules;
257 u32 nslot = 0; 295 u32 nslot = 0;
@@ -270,7 +308,8 @@ int avtab_alloc(struct avtab *h, u32 nrules)
270 nslot = MAX_AVTAB_HASH_BUCKETS; 308 nslot = MAX_AVTAB_HASH_BUCKETS;
271 mask = nslot - 1; 309 mask = nslot - 1;
272 310
273 h->htable = kcalloc(nslot, sizeof(*(h->htable)), GFP_KERNEL); 311 h->htable = flex_array_alloc(sizeof(struct avtab_node *), nslot,
312 GFP_KERNEL | __GFP_ZERO);
274 if (!h->htable) 313 if (!h->htable)
275 return -ENOMEM; 314 return -ENOMEM;
276 315
@@ -293,7 +332,7 @@ void avtab_hash_eval(struct avtab *h, char *tag)
293 max_chain_len = 0; 332 max_chain_len = 0;
294 chain2_len_sum = 0; 333 chain2_len_sum = 0;
295 for (i = 0; i < h->nslot; i++) { 334 for (i = 0; i < h->nslot; i++) {
296 cur = h->htable[i]; 335 cur = flex_array_get_ptr(h->htable, i);
297 if (cur) { 336 if (cur) {
298 slots_used++; 337 slots_used++;
299 chain_len = 0; 338 chain_len = 0;
@@ -534,7 +573,8 @@ int avtab_write(struct policydb *p, struct avtab *a, void *fp)
534 return rc; 573 return rc;
535 574
536 for (i = 0; i < a->nslot; i++) { 575 for (i = 0; i < a->nslot; i++) {
537 for (cur = a->htable[i]; cur; cur = cur->next) { 576 for (cur = flex_array_get_ptr(a->htable, i); cur;
577 cur = cur->next) {
538 rc = avtab_write_item(p, cur, fp); 578 rc = avtab_write_item(p, cur, fp);
539 if (rc) 579 if (rc)
540 return rc; 580 return rc;
diff --git a/security/selinux/ss/avtab.h b/security/selinux/ss/avtab.h
index 63ce2f9e441d..adb451cd44f9 100644
--- a/security/selinux/ss/avtab.h
+++ b/security/selinux/ss/avtab.h
@@ -23,6 +23,8 @@
23#ifndef _SS_AVTAB_H_ 23#ifndef _SS_AVTAB_H_
24#define _SS_AVTAB_H_ 24#define _SS_AVTAB_H_
25 25
26#include <linux/flex_array.h>
27
26struct avtab_key { 28struct avtab_key {
27 u16 source_type; /* source type */ 29 u16 source_type; /* source type */
28 u16 target_type; /* target type */ 30 u16 target_type; /* target type */
@@ -51,10 +53,10 @@ struct avtab_node {
51}; 53};
52 54
53struct avtab { 55struct avtab {
54 struct avtab_node **htable; 56 struct flex_array *htable;
55 u32 nel; /* number of elements */ 57 u32 nel; /* number of elements */
56 u32 nslot; /* number of hash slots */ 58 u32 nslot; /* number of hash slots */
57 u16 mask; /* mask to compute hash func */ 59 u32 mask; /* mask to compute hash func */
58 60
59}; 61};
60 62
@@ -84,7 +86,7 @@ struct avtab_node *avtab_search_node_next(struct avtab_node *node, int specified
84void avtab_cache_init(void); 86void avtab_cache_init(void);
85void avtab_cache_destroy(void); 87void avtab_cache_destroy(void);
86 88
87#define MAX_AVTAB_HASH_BITS 11 89#define MAX_AVTAB_HASH_BITS 16
88#define MAX_AVTAB_HASH_BUCKETS (1 << MAX_AVTAB_HASH_BITS) 90#define MAX_AVTAB_HASH_BUCKETS (1 << MAX_AVTAB_HASH_BITS)
89 91
90#endif /* _SS_AVTAB_H_ */ 92#endif /* _SS_AVTAB_H_ */
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c
index d307b37ddc2b..e1088842232c 100644
--- a/security/selinux/ss/mls.c
+++ b/security/selinux/ss/mls.c
@@ -654,19 +654,15 @@ int mls_import_netlbl_cat(struct context *context,
654 654
655 rc = ebitmap_netlbl_import(&context->range.level[0].cat, 655 rc = ebitmap_netlbl_import(&context->range.level[0].cat,
656 secattr->attr.mls.cat); 656 secattr->attr.mls.cat);
657 if (rc != 0) 657 if (rc)
658 goto import_netlbl_cat_failure;
659
660 rc = ebitmap_cpy(&context->range.level[1].cat,
661 &context->range.level[0].cat);
662 if (rc != 0)
663 goto import_netlbl_cat_failure; 658 goto import_netlbl_cat_failure;
659 memcpy(&context->range.level[1].cat, &context->range.level[0].cat,
660 sizeof(context->range.level[0].cat));
664 661
665 return 0; 662 return 0;
666 663
667import_netlbl_cat_failure: 664import_netlbl_cat_failure:
668 ebitmap_destroy(&context->range.level[0].cat); 665 ebitmap_destroy(&context->range.level[0].cat);
669 ebitmap_destroy(&context->range.level[1].cat);
670 return rc; 666 return rc;
671} 667}
672#endif /* CONFIG_NETLABEL */ 668#endif /* CONFIG_NETLABEL */
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index a1d3944751b9..9e2d82070915 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -3179,13 +3179,9 @@ int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr,
3179 ctx_new.type = ctx->type; 3179 ctx_new.type = ctx->type;
3180 mls_import_netlbl_lvl(&ctx_new, secattr); 3180 mls_import_netlbl_lvl(&ctx_new, secattr);
3181 if (secattr->flags & NETLBL_SECATTR_MLS_CAT) { 3181 if (secattr->flags & NETLBL_SECATTR_MLS_CAT) {
3182 rc = ebitmap_netlbl_import(&ctx_new.range.level[0].cat, 3182 rc = mls_import_netlbl_cat(&ctx_new, secattr);
3183 secattr->attr.mls.cat);
3184 if (rc) 3183 if (rc)
3185 goto out; 3184 goto out;
3186 memcpy(&ctx_new.range.level[1].cat,
3187 &ctx_new.range.level[0].cat,
3188 sizeof(ctx_new.range.level[0].cat));
3189 } 3185 }
3190 rc = -EIDRM; 3186 rc = -EIDRM;
3191 if (!mls_context_isvalid(&policydb, &ctx_new)) 3187 if (!mls_context_isvalid(&policydb, &ctx_new))
diff --git a/security/smack/smack.h b/security/smack/smack.h
index 67ccb7b2b89b..49eada6266ec 100644
--- a/security/smack/smack.h
+++ b/security/smack/smack.h
@@ -105,6 +105,7 @@ struct task_smack {
105#define SMK_INODE_INSTANT 0x01 /* inode is instantiated */ 105#define SMK_INODE_INSTANT 0x01 /* inode is instantiated */
106#define SMK_INODE_TRANSMUTE 0x02 /* directory is transmuting */ 106#define SMK_INODE_TRANSMUTE 0x02 /* directory is transmuting */
107#define SMK_INODE_CHANGED 0x04 /* smack was transmuted */ 107#define SMK_INODE_CHANGED 0x04 /* smack was transmuted */
108#define SMK_INODE_IMPURE 0x08 /* involved in an impure transaction */
108 109
109/* 110/*
110 * A label access rule. 111 * A label access rule.
@@ -193,6 +194,10 @@ struct smk_port_label {
193#define MAY_LOCK 0x00002000 /* Locks should be writes, but ... */ 194#define MAY_LOCK 0x00002000 /* Locks should be writes, but ... */
194#define MAY_BRINGUP 0x00004000 /* Report use of this rule */ 195#define MAY_BRINGUP 0x00004000 /* Report use of this rule */
195 196
197#define SMACK_BRINGUP_ALLOW 1 /* Allow bringup mode */
198#define SMACK_UNCONFINED_SUBJECT 2 /* Allow unconfined label */
199#define SMACK_UNCONFINED_OBJECT 3 /* Allow unconfined label */
200
196/* 201/*
197 * Just to make the common cases easier to deal with 202 * Just to make the common cases easier to deal with
198 */ 203 */
@@ -254,6 +259,9 @@ extern int smack_cipso_mapped;
254extern struct smack_known *smack_net_ambient; 259extern struct smack_known *smack_net_ambient;
255extern struct smack_known *smack_onlycap; 260extern struct smack_known *smack_onlycap;
256extern struct smack_known *smack_syslog_label; 261extern struct smack_known *smack_syslog_label;
262#ifdef CONFIG_SECURITY_SMACK_BRINGUP
263extern struct smack_known *smack_unconfined;
264#endif
257extern struct smack_known smack_cipso_option; 265extern struct smack_known smack_cipso_option;
258extern int smack_ptrace_rule; 266extern int smack_ptrace_rule;
259 267
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c
index 1158430f5bb9..0f410fc56e33 100644
--- a/security/smack/smack_access.c
+++ b/security/smack/smack_access.c
@@ -130,7 +130,8 @@ int smk_access(struct smack_known *subject, struct smack_known *object,
130 130
131 /* 131 /*
132 * Hardcoded comparisons. 132 * Hardcoded comparisons.
133 * 133 */
134 /*
134 * A star subject can't access any object. 135 * A star subject can't access any object.
135 */ 136 */
136 if (subject == &smack_known_star) { 137 if (subject == &smack_known_star) {
@@ -189,10 +190,20 @@ int smk_access(struct smack_known *subject, struct smack_known *object,
189 * succeed because of "b" rules. 190 * succeed because of "b" rules.
190 */ 191 */
191 if (may & MAY_BRINGUP) 192 if (may & MAY_BRINGUP)
192 rc = MAY_BRINGUP; 193 rc = SMACK_BRINGUP_ALLOW;
193#endif 194#endif
194 195
195out_audit: 196out_audit:
197
198#ifdef CONFIG_SECURITY_SMACK_BRINGUP
199 if (rc < 0) {
200 if (object == smack_unconfined)
201 rc = SMACK_UNCONFINED_OBJECT;
202 if (subject == smack_unconfined)
203 rc = SMACK_UNCONFINED_SUBJECT;
204 }
205#endif
206
196#ifdef CONFIG_AUDIT 207#ifdef CONFIG_AUDIT
197 if (a) 208 if (a)
198 smack_log(subject->smk_known, object->smk_known, 209 smack_log(subject->smk_known, object->smk_known,
@@ -338,19 +349,16 @@ static void smack_log_callback(struct audit_buffer *ab, void *a)
338void smack_log(char *subject_label, char *object_label, int request, 349void smack_log(char *subject_label, char *object_label, int request,
339 int result, struct smk_audit_info *ad) 350 int result, struct smk_audit_info *ad)
340{ 351{
352#ifdef CONFIG_SECURITY_SMACK_BRINGUP
353 char request_buffer[SMK_NUM_ACCESS_TYPE + 5];
354#else
341 char request_buffer[SMK_NUM_ACCESS_TYPE + 1]; 355 char request_buffer[SMK_NUM_ACCESS_TYPE + 1];
356#endif
342 struct smack_audit_data *sad; 357 struct smack_audit_data *sad;
343 struct common_audit_data *a = &ad->a; 358 struct common_audit_data *a = &ad->a;
344 359
345#ifdef CONFIG_SECURITY_SMACK_BRINGUP
346 /*
347 * The result may be positive in bringup mode.
348 */
349 if (result > 0)
350 result = 0;
351#endif
352 /* check if we have to log the current event */ 360 /* check if we have to log the current event */
353 if (result != 0 && (log_policy & SMACK_AUDIT_DENIED) == 0) 361 if (result < 0 && (log_policy & SMACK_AUDIT_DENIED) == 0)
354 return; 362 return;
355 if (result == 0 && (log_policy & SMACK_AUDIT_ACCEPT) == 0) 363 if (result == 0 && (log_policy & SMACK_AUDIT_ACCEPT) == 0)
356 return; 364 return;
@@ -364,6 +372,21 @@ void smack_log(char *subject_label, char *object_label, int request,
364 smack_str_from_perm(request_buffer, request); 372 smack_str_from_perm(request_buffer, request);
365 sad->subject = subject_label; 373 sad->subject = subject_label;
366 sad->object = object_label; 374 sad->object = object_label;
375#ifdef CONFIG_SECURITY_SMACK_BRINGUP
376 /*
377 * The result may be positive in bringup mode.
378 * A positive result is an allow, but not for normal reasons.
379 * Mark it as successful, but don't filter it out even if
380 * the logging policy says to do so.
381 */
382 if (result == SMACK_UNCONFINED_SUBJECT)
383 strcat(request_buffer, "(US)");
384 else if (result == SMACK_UNCONFINED_OBJECT)
385 strcat(request_buffer, "(UO)");
386
387 if (result > 0)
388 result = 0;
389#endif
367 sad->request = request_buffer; 390 sad->request = request_buffer;
368 sad->result = result; 391 sad->result = result;
369 392
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 14b316f60fc5..b644757886bc 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -57,6 +57,13 @@ static struct kmem_cache *smack_inode_cache;
57int smack_enabled; 57int smack_enabled;
58 58
59#ifdef CONFIG_SECURITY_SMACK_BRINGUP 59#ifdef CONFIG_SECURITY_SMACK_BRINGUP
60static char *smk_bu_mess[] = {
61 "Bringup Error", /* Unused */
62 "Bringup", /* SMACK_BRINGUP_ALLOW */
63 "Unconfined Subject", /* SMACK_UNCONFINED_SUBJECT */
64 "Unconfined Object", /* SMACK_UNCONFINED_OBJECT */
65};
66
60static void smk_bu_mode(int mode, char *s) 67static void smk_bu_mode(int mode, char *s)
61{ 68{
62 int i = 0; 69 int i = 0;
@@ -87,9 +94,11 @@ static int smk_bu_note(char *note, struct smack_known *sskp,
87 94
88 if (rc <= 0) 95 if (rc <= 0)
89 return rc; 96 return rc;
97 if (rc > SMACK_UNCONFINED_OBJECT)
98 rc = 0;
90 99
91 smk_bu_mode(mode, acc); 100 smk_bu_mode(mode, acc);
92 pr_info("Smack Bringup: (%s %s %s) %s\n", 101 pr_info("Smack %s: (%s %s %s) %s\n", smk_bu_mess[rc],
93 sskp->smk_known, oskp->smk_known, acc, note); 102 sskp->smk_known, oskp->smk_known, acc, note);
94 return 0; 103 return 0;
95} 104}
@@ -106,9 +115,11 @@ static int smk_bu_current(char *note, struct smack_known *oskp,
106 115
107 if (rc <= 0) 116 if (rc <= 0)
108 return rc; 117 return rc;
118 if (rc > SMACK_UNCONFINED_OBJECT)
119 rc = 0;
109 120
110 smk_bu_mode(mode, acc); 121 smk_bu_mode(mode, acc);
111 pr_info("Smack Bringup: (%s %s %s) %s %s\n", 122 pr_info("Smack %s: (%s %s %s) %s %s\n", smk_bu_mess[rc],
112 tsp->smk_task->smk_known, oskp->smk_known, 123 tsp->smk_task->smk_known, oskp->smk_known,
113 acc, current->comm, note); 124 acc, current->comm, note);
114 return 0; 125 return 0;
@@ -126,9 +137,11 @@ static int smk_bu_task(struct task_struct *otp, int mode, int rc)
126 137
127 if (rc <= 0) 138 if (rc <= 0)
128 return rc; 139 return rc;
140 if (rc > SMACK_UNCONFINED_OBJECT)
141 rc = 0;
129 142
130 smk_bu_mode(mode, acc); 143 smk_bu_mode(mode, acc);
131 pr_info("Smack Bringup: (%s %s %s) %s to %s\n", 144 pr_info("Smack %s: (%s %s %s) %s to %s\n", smk_bu_mess[rc],
132 tsp->smk_task->smk_known, smk_task->smk_known, acc, 145 tsp->smk_task->smk_known, smk_task->smk_known, acc,
133 current->comm, otp->comm); 146 current->comm, otp->comm);
134 return 0; 147 return 0;
@@ -141,14 +154,25 @@ static int smk_bu_task(struct task_struct *otp, int mode, int rc)
141static int smk_bu_inode(struct inode *inode, int mode, int rc) 154static int smk_bu_inode(struct inode *inode, int mode, int rc)
142{ 155{
143 struct task_smack *tsp = current_security(); 156 struct task_smack *tsp = current_security();
157 struct inode_smack *isp = inode->i_security;
144 char acc[SMK_NUM_ACCESS_TYPE + 1]; 158 char acc[SMK_NUM_ACCESS_TYPE + 1];
145 159
160 if (isp->smk_flags & SMK_INODE_IMPURE)
161 pr_info("Smack Unconfined Corruption: inode=(%s %ld) %s\n",
162 inode->i_sb->s_id, inode->i_ino, current->comm);
163
146 if (rc <= 0) 164 if (rc <= 0)
147 return rc; 165 return rc;
166 if (rc > SMACK_UNCONFINED_OBJECT)
167 rc = 0;
168 if (rc == SMACK_UNCONFINED_SUBJECT &&
169 (mode & (MAY_WRITE | MAY_APPEND)))
170 isp->smk_flags |= SMK_INODE_IMPURE;
148 171
149 smk_bu_mode(mode, acc); 172 smk_bu_mode(mode, acc);
150 pr_info("Smack Bringup: (%s %s %s) inode=(%s %ld) %s\n", 173
151 tsp->smk_task->smk_known, smk_of_inode(inode)->smk_known, acc, 174 pr_info("Smack %s: (%s %s %s) inode=(%s %ld) %s\n", smk_bu_mess[rc],
175 tsp->smk_task->smk_known, isp->smk_inode->smk_known, acc,
152 inode->i_sb->s_id, inode->i_ino, current->comm); 176 inode->i_sb->s_id, inode->i_ino, current->comm);
153 return 0; 177 return 0;
154} 178}
@@ -162,13 +186,20 @@ static int smk_bu_file(struct file *file, int mode, int rc)
162 struct task_smack *tsp = current_security(); 186 struct task_smack *tsp = current_security();
163 struct smack_known *sskp = tsp->smk_task; 187 struct smack_known *sskp = tsp->smk_task;
164 struct inode *inode = file_inode(file); 188 struct inode *inode = file_inode(file);
189 struct inode_smack *isp = inode->i_security;
165 char acc[SMK_NUM_ACCESS_TYPE + 1]; 190 char acc[SMK_NUM_ACCESS_TYPE + 1];
166 191
192 if (isp->smk_flags & SMK_INODE_IMPURE)
193 pr_info("Smack Unconfined Corruption: inode=(%s %ld) %s\n",
194 inode->i_sb->s_id, inode->i_ino, current->comm);
195
167 if (rc <= 0) 196 if (rc <= 0)
168 return rc; 197 return rc;
198 if (rc > SMACK_UNCONFINED_OBJECT)
199 rc = 0;
169 200
170 smk_bu_mode(mode, acc); 201 smk_bu_mode(mode, acc);
171 pr_info("Smack Bringup: (%s %s %s) file=(%s %ld %pD) %s\n", 202 pr_info("Smack %s: (%s %s %s) file=(%s %ld %pD) %s\n", smk_bu_mess[rc],
172 sskp->smk_known, smk_of_inode(inode)->smk_known, acc, 203 sskp->smk_known, smk_of_inode(inode)->smk_known, acc,
173 inode->i_sb->s_id, inode->i_ino, file, 204 inode->i_sb->s_id, inode->i_ino, file,
174 current->comm); 205 current->comm);
@@ -185,13 +216,20 @@ static int smk_bu_credfile(const struct cred *cred, struct file *file,
185 struct task_smack *tsp = cred->security; 216 struct task_smack *tsp = cred->security;
186 struct smack_known *sskp = tsp->smk_task; 217 struct smack_known *sskp = tsp->smk_task;
187 struct inode *inode = file->f_inode; 218 struct inode *inode = file->f_inode;
219 struct inode_smack *isp = inode->i_security;
188 char acc[SMK_NUM_ACCESS_TYPE + 1]; 220 char acc[SMK_NUM_ACCESS_TYPE + 1];
189 221
222 if (isp->smk_flags & SMK_INODE_IMPURE)
223 pr_info("Smack Unconfined Corruption: inode=(%s %ld) %s\n",
224 inode->i_sb->s_id, inode->i_ino, current->comm);
225
190 if (rc <= 0) 226 if (rc <= 0)
191 return rc; 227 return rc;
228 if (rc > SMACK_UNCONFINED_OBJECT)
229 rc = 0;
192 230
193 smk_bu_mode(mode, acc); 231 smk_bu_mode(mode, acc);
194 pr_info("Smack Bringup: (%s %s %s) file=(%s %ld %pD) %s\n", 232 pr_info("Smack %s: (%s %s %s) file=(%s %ld %pD) %s\n", smk_bu_mess[rc],
195 sskp->smk_known, smk_of_inode(inode)->smk_known, acc, 233 sskp->smk_known, smk_of_inode(inode)->smk_known, acc,
196 inode->i_sb->s_id, inode->i_ino, file, 234 inode->i_sb->s_id, inode->i_ino, file,
197 current->comm); 235 current->comm);
@@ -2449,7 +2487,21 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
2449static int smack_socket_post_create(struct socket *sock, int family, 2487static int smack_socket_post_create(struct socket *sock, int family,
2450 int type, int protocol, int kern) 2488 int type, int protocol, int kern)
2451{ 2489{
2452 if (family != PF_INET || sock->sk == NULL) 2490 struct socket_smack *ssp;
2491
2492 if (sock->sk == NULL)
2493 return 0;
2494
2495 /*
2496 * Sockets created by kernel threads receive web label.
2497 */
2498 if (unlikely(current->flags & PF_KTHREAD)) {
2499 ssp = sock->sk->sk_security;
2500 ssp->smk_in = &smack_known_web;
2501 ssp->smk_out = &smack_known_web;
2502 }
2503
2504 if (family != PF_INET)
2453 return 0; 2505 return 0;
2454 /* 2506 /*
2455 * Set the outbound netlbl. 2507 * Set the outbound netlbl.
@@ -3983,6 +4035,36 @@ static int smack_key_permission(key_ref_t key_ref,
3983 rc = smk_bu_note("key access", tkp, keyp->security, request, rc); 4035 rc = smk_bu_note("key access", tkp, keyp->security, request, rc);
3984 return rc; 4036 return rc;
3985} 4037}
4038
4039/*
4040 * smack_key_getsecurity - Smack label tagging the key
4041 * @key points to the key to be queried
4042 * @_buffer points to a pointer that should be set to point to the
4043 * resulting string (if no label or an error occurs).
4044 * Return the length of the string (including terminating NUL) or -ve if
4045 * an error.
4046 * May also return 0 (and a NULL buffer pointer) if there is no label.
4047 */
4048static int smack_key_getsecurity(struct key *key, char **_buffer)
4049{
4050 struct smack_known *skp = key->security;
4051 size_t length;
4052 char *copy;
4053
4054 if (key->security == NULL) {
4055 *_buffer = NULL;
4056 return 0;
4057 }
4058
4059 copy = kstrdup(skp->smk_known, GFP_KERNEL);
4060 if (copy == NULL)
4061 return -ENOMEM;
4062 length = strlen(copy) + 1;
4063
4064 *_buffer = copy;
4065 return length;
4066}
4067
3986#endif /* CONFIG_KEYS */ 4068#endif /* CONFIG_KEYS */
3987 4069
3988/* 4070/*
@@ -4307,6 +4389,7 @@ struct security_operations smack_ops = {
4307 .key_alloc = smack_key_alloc, 4389 .key_alloc = smack_key_alloc,
4308 .key_free = smack_key_free, 4390 .key_free = smack_key_free,
4309 .key_permission = smack_key_permission, 4391 .key_permission = smack_key_permission,
4392 .key_getsecurity = smack_key_getsecurity,
4310#endif /* CONFIG_KEYS */ 4393#endif /* CONFIG_KEYS */
4311 4394
4312 /* Audit hooks */ 4395 /* Audit hooks */
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index 2611a651c344..d9682985349e 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -54,6 +54,9 @@ enum smk_inos {
54 SMK_CHANGE_RULE = 19, /* change or add rules (long labels) */ 54 SMK_CHANGE_RULE = 19, /* change or add rules (long labels) */
55 SMK_SYSLOG = 20, /* change syslog label) */ 55 SMK_SYSLOG = 20, /* change syslog label) */
56 SMK_PTRACE = 21, /* set ptrace rule */ 56 SMK_PTRACE = 21, /* set ptrace rule */
57#ifdef CONFIG_SECURITY_SMACK_BRINGUP
58 SMK_UNCONFINED = 22, /* define an unconfined label */
59#endif
57}; 60};
58 61
59/* 62/*
@@ -61,7 +64,6 @@ enum smk_inos {
61 */ 64 */
62static DEFINE_MUTEX(smack_cipso_lock); 65static DEFINE_MUTEX(smack_cipso_lock);
63static DEFINE_MUTEX(smack_ambient_lock); 66static DEFINE_MUTEX(smack_ambient_lock);
64static DEFINE_MUTEX(smack_syslog_lock);
65static DEFINE_MUTEX(smk_netlbladdr_lock); 67static DEFINE_MUTEX(smk_netlbladdr_lock);
66 68
67/* 69/*
@@ -95,6 +97,16 @@ int smack_cipso_mapped = SMACK_CIPSO_MAPPED_DEFAULT;
95 */ 97 */
96struct smack_known *smack_onlycap; 98struct smack_known *smack_onlycap;
97 99
100#ifdef CONFIG_SECURITY_SMACK_BRINGUP
101/*
102 * Allow one label to be unconfined. This is for
103 * debugging and application bring-up purposes only.
104 * It is bad and wrong, but everyone seems to expect
105 * to have it.
106 */
107struct smack_known *smack_unconfined;
108#endif
109
98/* 110/*
99 * If this value is set restrict syslog use to the label specified. 111 * If this value is set restrict syslog use to the label specified.
100 * It can be reset via smackfs/syslog 112 * It can be reset via smackfs/syslog
@@ -1717,6 +1729,85 @@ static const struct file_operations smk_onlycap_ops = {
1717 .llseek = default_llseek, 1729 .llseek = default_llseek,
1718}; 1730};
1719 1731
1732#ifdef CONFIG_SECURITY_SMACK_BRINGUP
1733/**
1734 * smk_read_unconfined - read() for smackfs/unconfined
1735 * @filp: file pointer, not actually used
1736 * @buf: where to put the result
1737 * @cn: maximum to send along
1738 * @ppos: where to start
1739 *
1740 * Returns number of bytes read or error code, as appropriate
1741 */
1742static ssize_t smk_read_unconfined(struct file *filp, char __user *buf,
1743 size_t cn, loff_t *ppos)
1744{
1745 char *smack = "";
1746 ssize_t rc = -EINVAL;
1747 int asize;
1748
1749 if (*ppos != 0)
1750 return 0;
1751
1752 if (smack_unconfined != NULL)
1753 smack = smack_unconfined->smk_known;
1754
1755 asize = strlen(smack) + 1;
1756
1757 if (cn >= asize)
1758 rc = simple_read_from_buffer(buf, cn, ppos, smack, asize);
1759
1760 return rc;
1761}
1762
1763/**
1764 * smk_write_unconfined - write() for smackfs/unconfined
1765 * @file: file pointer, not actually used
1766 * @buf: where to get the data from
1767 * @count: bytes sent
1768 * @ppos: where to start
1769 *
1770 * Returns number of bytes written or error code, as appropriate
1771 */
1772static ssize_t smk_write_unconfined(struct file *file, const char __user *buf,
1773 size_t count, loff_t *ppos)
1774{
1775 char *data;
1776 int rc = count;
1777
1778 if (!smack_privileged(CAP_MAC_ADMIN))
1779 return -EPERM;
1780
1781 data = kzalloc(count + 1, GFP_KERNEL);
1782 if (data == NULL)
1783 return -ENOMEM;
1784
1785 /*
1786 * Should the null string be passed in unset the unconfined value.
1787 * This seems like something to be careful with as usually
1788 * smk_import only expects to return NULL for errors. It
1789 * is usually the case that a nullstring or "\n" would be
1790 * bad to pass to smk_import but in fact this is useful here.
1791 *
1792 * smk_import will also reject a label beginning with '-',
1793 * so "-confine" will also work.
1794 */
1795 if (copy_from_user(data, buf, count) != 0)
1796 rc = -EFAULT;
1797 else
1798 smack_unconfined = smk_import_entry(data, count);
1799
1800 kfree(data);
1801 return rc;
1802}
1803
1804static const struct file_operations smk_unconfined_ops = {
1805 .read = smk_read_unconfined,
1806 .write = smk_write_unconfined,
1807 .llseek = default_llseek,
1808};
1809#endif /* CONFIG_SECURITY_SMACK_BRINGUP */
1810
1720/** 1811/**
1721 * smk_read_logging - read() for /smack/logging 1812 * smk_read_logging - read() for /smack/logging
1722 * @filp: file pointer, not actually used 1813 * @filp: file pointer, not actually used
@@ -2384,6 +2475,10 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent)
2384 "syslog", &smk_syslog_ops, S_IRUGO|S_IWUSR}, 2475 "syslog", &smk_syslog_ops, S_IRUGO|S_IWUSR},
2385 [SMK_PTRACE] = { 2476 [SMK_PTRACE] = {
2386 "ptrace", &smk_ptrace_ops, S_IRUGO|S_IWUSR}, 2477 "ptrace", &smk_ptrace_ops, S_IRUGO|S_IWUSR},
2478#ifdef CONFIG_SECURITY_SMACK_BRINGUP
2479 [SMK_UNCONFINED] = {
2480 "unconfined", &smk_unconfined_ops, S_IRUGO|S_IWUSR},
2481#endif
2387 /* last one */ 2482 /* last one */
2388 {""} 2483 {""}
2389 }; 2484 };
diff --git a/security/tomoyo/.gitignore b/security/tomoyo/.gitignore
index 5caf1a6f5907..dc0f220a210b 100644
--- a/security/tomoyo/.gitignore
+++ b/security/tomoyo/.gitignore
@@ -1,2 +1,2 @@
1builtin-policy.h 1builtin-policy.h
2policy/ 2policy/*.conf
diff --git a/security/tomoyo/Kconfig b/security/tomoyo/Kconfig
index 604e718d68d3..404dce66952a 100644
--- a/security/tomoyo/Kconfig
+++ b/security/tomoyo/Kconfig
@@ -6,6 +6,7 @@ config SECURITY_TOMOYO
6 select SECURITY_PATH 6 select SECURITY_PATH
7 select SECURITY_NETWORK 7 select SECURITY_NETWORK
8 select SRCU 8 select SRCU
9 select BUILD_BIN2C
9 default n 10 default n
10 help 11 help
11 This selects TOMOYO Linux, pathname-based access control. 12 This selects TOMOYO Linux, pathname-based access control.
diff --git a/security/tomoyo/Makefile b/security/tomoyo/Makefile
index 56a0c7be409e..65dbcb2fd850 100644
--- a/security/tomoyo/Makefile
+++ b/security/tomoyo/Makefile
@@ -1,48 +1,15 @@
1obj-y = audit.o common.o condition.o domain.o environ.o file.o gc.o group.o load_policy.o memory.o mount.o network.o realpath.o securityfs_if.o tomoyo.o util.o 1obj-y = audit.o common.o condition.o domain.o environ.o file.o gc.o group.o load_policy.o memory.o mount.o network.o realpath.o securityfs_if.o tomoyo.o util.o
2 2
3$(obj)/policy/profile.conf: 3targets += builtin-policy.h
4 @mkdir -p $(obj)/policy/ 4define do_policy
5 @echo Creating an empty policy/profile.conf 5echo "static char tomoyo_builtin_$(1)[] __initdata ="; \
6 @touch $@ 6$(objtree)/scripts/basic/bin2c <$(firstword $(wildcard $(obj)/policy/$(1).conf $(srctree)/$(src)/policy/$(1).conf.default) /dev/null); \
7 7echo ";"
8$(obj)/policy/exception_policy.conf: 8endef
9 @mkdir -p $(obj)/policy/ 9quiet_cmd_policy = POLICY $@
10 @echo Creating a default policy/exception_policy.conf 10 cmd_policy = ($(call do_policy,profile); $(call do_policy,exception_policy); $(call do_policy,domain_policy); $(call do_policy,manager); $(call do_policy,stat)) >$@
11 @echo initialize_domain /sbin/modprobe from any >> $@ 11
12 @echo initialize_domain /sbin/hotplug from any >> $@ 12$(obj)/builtin-policy.h: $(wildcard $(obj)/policy/*.conf $(src)/policy/*.conf.default) FORCE
13 13 $(call if_changed,policy)
14$(obj)/policy/domain_policy.conf:
15 @mkdir -p $(obj)/policy/
16 @echo Creating an empty policy/domain_policy.conf
17 @touch $@
18
19$(obj)/policy/manager.conf:
20 @mkdir -p $(obj)/policy/
21 @echo Creating an empty policy/manager.conf
22 @touch $@
23
24$(obj)/policy/stat.conf:
25 @mkdir -p $(obj)/policy/
26 @echo Creating an empty policy/stat.conf
27 @touch $@
28
29$(obj)/builtin-policy.h: $(obj)/policy/profile.conf $(obj)/policy/exception_policy.conf $(obj)/policy/domain_policy.conf $(obj)/policy/manager.conf $(obj)/policy/stat.conf
30 @echo Generating built-in policy for TOMOYO 2.5.x.
31 @echo "static char tomoyo_builtin_profile[] __initdata =" > $@.tmp
32 @sed -e 's/\\/\\\\/g' -e 's/\"/\\"/g' -e 's/\(.*\)/"\1\\n"/' < $(obj)/policy/profile.conf >> $@.tmp
33 @echo "\"\";" >> $@.tmp
34 @echo "static char tomoyo_builtin_exception_policy[] __initdata =" >> $@.tmp
35 @sed -e 's/\\/\\\\/g' -e 's/\"/\\"/g' -e 's/\(.*\)/"\1\\n"/' < $(obj)/policy/exception_policy.conf >> $@.tmp
36 @echo "\"\";" >> $@.tmp
37 @echo "static char tomoyo_builtin_domain_policy[] __initdata =" >> $@.tmp
38 @sed -e 's/\\/\\\\/g' -e 's/\"/\\"/g' -e 's/\(.*\)/"\1\\n"/' < $(obj)/policy/domain_policy.conf >> $@.tmp
39 @echo "\"\";" >> $@.tmp
40 @echo "static char tomoyo_builtin_manager[] __initdata =" >> $@.tmp
41 @sed -e 's/\\/\\\\/g' -e 's/\"/\\"/g' -e 's/\(.*\)/"\1\\n"/' < $(obj)/policy/manager.conf >> $@.tmp
42 @echo "\"\";" >> $@.tmp
43 @echo "static char tomoyo_builtin_stat[] __initdata =" >> $@.tmp
44 @sed -e 's/\\/\\\\/g' -e 's/\"/\\"/g' -e 's/\(.*\)/"\1\\n"/' < $(obj)/policy/stat.conf >> $@.tmp
45 @echo "\"\";" >> $@.tmp
46 @mv $@.tmp $@
47 14
48$(obj)/common.o: $(obj)/builtin-policy.h 15$(obj)/common.o: $(obj)/builtin-policy.h
diff --git a/security/tomoyo/policy/exception_policy.conf.default b/security/tomoyo/policy/exception_policy.conf.default
new file mode 100644
index 000000000000..2678df4964ee
--- /dev/null
+++ b/security/tomoyo/policy/exception_policy.conf.default
@@ -0,0 +1,2 @@
1initialize_domain /sbin/modprobe from any
2initialize_domain /sbin/hotplug from any
diff --git a/security/tomoyo/util.c b/security/tomoyo/util.c
index 2952ba576fb9..b974a6997d7f 100644
--- a/security/tomoyo/util.c
+++ b/security/tomoyo/util.c
@@ -948,15 +948,18 @@ bool tomoyo_path_matches_pattern(const struct tomoyo_path_info *filename,
948 */ 948 */
949const char *tomoyo_get_exe(void) 949const char *tomoyo_get_exe(void)
950{ 950{
951 struct file *exe_file;
952 const char *cp;
951 struct mm_struct *mm = current->mm; 953 struct mm_struct *mm = current->mm;
952 const char *cp = NULL;
953 954
954 if (!mm) 955 if (!mm)
955 return NULL; 956 return NULL;
956 down_read(&mm->mmap_sem); 957 exe_file = get_mm_exe_file(mm);
957 if (mm->exe_file) 958 if (!exe_file)
958 cp = tomoyo_realpath_from_path(&mm->exe_file->f_path); 959 return NULL;
959 up_read(&mm->mmap_sem); 960
961 cp = tomoyo_realpath_from_path(&exe_file->f_path);
962 fput(exe_file);
960 return cp; 963 return cp;
961} 964}
962 965
diff --git a/security/yama/Kconfig b/security/yama/Kconfig
index 20ef5143c0c0..3123e1da2fed 100644
--- a/security/yama/Kconfig
+++ b/security/yama/Kconfig
@@ -1,8 +1,6 @@
1config SECURITY_YAMA 1config SECURITY_YAMA
2 bool "Yama support" 2 bool "Yama support"
3 depends on SECURITY 3 depends on SECURITY
4 select SECURITYFS
5 select SECURITY_PATH
6 default n 4 default n
7 help 5 help
8 This selects Yama, which extends DAC support with additional 6 This selects Yama, which extends DAC support with additional
diff --git a/security/yama/yama_lsm.c b/security/yama/yama_lsm.c
index 13c88fbcf037..24aae2ae2b30 100644
--- a/security/yama/yama_lsm.c
+++ b/security/yama/yama_lsm.c
@@ -379,20 +379,17 @@ static struct security_operations yama_ops = {
379static int yama_dointvec_minmax(struct ctl_table *table, int write, 379static int yama_dointvec_minmax(struct ctl_table *table, int write,
380 void __user *buffer, size_t *lenp, loff_t *ppos) 380 void __user *buffer, size_t *lenp, loff_t *ppos)
381{ 381{
382 int rc; 382 struct ctl_table table_copy;
383 383
384 if (write && !capable(CAP_SYS_PTRACE)) 384 if (write && !capable(CAP_SYS_PTRACE))
385 return -EPERM; 385 return -EPERM;
386 386
387 rc = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
388 if (rc)
389 return rc;
390
391 /* Lock the max value if it ever gets set. */ 387 /* Lock the max value if it ever gets set. */
392 if (write && *(int *)table->data == *(int *)table->extra2) 388 table_copy = *table;
393 table->extra1 = table->extra2; 389 if (*(int *)table_copy.data == *(int *)table_copy.extra2)
390 table_copy.extra1 = table_copy.extra2;
394 391
395 return rc; 392 return proc_dointvec_minmax(&table_copy, write, buffer, lenp, ppos);
396} 393}
397 394
398static int zero; 395static int zero;