summaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-09-08 15:41:25 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-09-08 15:41:25 -0400
commitb793c005ceabf6db0b17494b0ec67ade6796bb34 (patch)
tree080c884f04254403ec9564742f591a9fd9b7e95a /security
parent6f0a2fc1feb19bd142961a39dc118e7e55418b3f (diff)
parent07f081fb5057b2ea98baeca3a47bf0eb33e94aa1 (diff)
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security
Pull security subsystem updates from James Morris: "Highlights: - PKCS#7 support added to support signed kexec, also utilized for module signing. See comments in 3f1e1bea. ** NOTE: this requires linking against the OpenSSL library, which must be installed, e.g. the openssl-devel on Fedora ** - Smack - add IPv6 host labeling; ignore labels on kernel threads - support smack labeling mounts which use binary mount data - SELinux: - add ioctl whitelisting (see http://kernsec.org/files/lss2015/vanderstoep.pdf) - fix mprotect PROT_EXEC regression caused by mm change - Seccomp: - add ptrace options for suspend/resume" * 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: (57 commits) PKCS#7: Add OIDs for sha224, sha284 and sha512 hash algos and use them Documentation/Changes: Now need OpenSSL devel packages for module signing scripts: add extract-cert and sign-file to .gitignore modsign: Handle signing key in source tree modsign: Use if_changed rule for extracting cert from module signing key Move certificate handling to its own directory sign-file: Fix warning about BIO_reset() return value PKCS#7: Add MODULE_LICENSE() to test module Smack - Fix build error with bringup unconfigured sign-file: Document dependency on OpenSSL devel libraries PKCS#7: Appropriately restrict authenticated attributes and content type KEYS: Add a name for PKEY_ID_PKCS7 PKCS#7: Improve and export the X.509 ASN.1 time object decoder modsign: Use extract-cert to process CONFIG_SYSTEM_TRUSTED_KEYS extract-cert: Cope with multiple X.509 certificates in a single file sign-file: Generate CMS message as signature instead of PKCS#7 PKCS#7: Support CMS messages also [RFC5652] X.509: Change recorded SKID & AKID to not include Subject or Issuer PKCS#7: Check content type and versions MAINTAINERS: The keyrings mailing list has moved ...
Diffstat (limited to 'security')
-rw-r--r--security/Kconfig5
-rw-r--r--security/lsm_audit.c15
-rw-r--r--security/security.c11
-rw-r--r--security/selinux/avc.c418
-rw-r--r--security/selinux/hooks.c147
-rw-r--r--security/selinux/include/avc.h6
-rw-r--r--security/selinux/include/security.h32
-rw-r--r--security/selinux/ss/avtab.c104
-rw-r--r--security/selinux/ss/avtab.h33
-rw-r--r--security/selinux/ss/conditional.c32
-rw-r--r--security/selinux/ss/conditional.h6
-rw-r--r--security/selinux/ss/policydb.c5
-rw-r--r--security/selinux/ss/services.c213
-rw-r--r--security/selinux/ss/services.h6
-rw-r--r--security/smack/smack.h66
-rw-r--r--security/smack/smack_access.c6
-rw-r--r--security/smack/smack_lsm.c511
-rw-r--r--security/smack/smackfs.c436
-rw-r--r--security/yama/Kconfig9
-rw-r--r--security/yama/yama_lsm.c33
20 files changed, 1732 insertions, 362 deletions
diff --git a/security/Kconfig b/security/Kconfig
index bf4ec46474b6..e45237897b43 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -132,7 +132,6 @@ choice
132 default DEFAULT_SECURITY_SMACK if SECURITY_SMACK 132 default DEFAULT_SECURITY_SMACK if SECURITY_SMACK
133 default DEFAULT_SECURITY_TOMOYO if SECURITY_TOMOYO 133 default DEFAULT_SECURITY_TOMOYO if SECURITY_TOMOYO
134 default DEFAULT_SECURITY_APPARMOR if SECURITY_APPARMOR 134 default DEFAULT_SECURITY_APPARMOR if SECURITY_APPARMOR
135 default DEFAULT_SECURITY_YAMA if SECURITY_YAMA
136 default DEFAULT_SECURITY_DAC 135 default DEFAULT_SECURITY_DAC
137 136
138 help 137 help
@@ -151,9 +150,6 @@ choice
151 config DEFAULT_SECURITY_APPARMOR 150 config DEFAULT_SECURITY_APPARMOR
152 bool "AppArmor" if SECURITY_APPARMOR=y 151 bool "AppArmor" if SECURITY_APPARMOR=y
153 152
154 config DEFAULT_SECURITY_YAMA
155 bool "Yama" if SECURITY_YAMA=y
156
157 config DEFAULT_SECURITY_DAC 153 config DEFAULT_SECURITY_DAC
158 bool "Unix Discretionary Access Controls" 154 bool "Unix Discretionary Access Controls"
159 155
@@ -165,7 +161,6 @@ config DEFAULT_SECURITY
165 default "smack" if DEFAULT_SECURITY_SMACK 161 default "smack" if DEFAULT_SECURITY_SMACK
166 default "tomoyo" if DEFAULT_SECURITY_TOMOYO 162 default "tomoyo" if DEFAULT_SECURITY_TOMOYO
167 default "apparmor" if DEFAULT_SECURITY_APPARMOR 163 default "apparmor" if DEFAULT_SECURITY_APPARMOR
168 default "yama" if DEFAULT_SECURITY_YAMA
169 default "" if DEFAULT_SECURITY_DAC 164 default "" if DEFAULT_SECURITY_DAC
170 165
171endmenu 166endmenu
diff --git a/security/lsm_audit.c b/security/lsm_audit.c
index 4ed98107ace3..cccbf3068cdc 100644
--- a/security/lsm_audit.c
+++ b/security/lsm_audit.c
@@ -245,6 +245,21 @@ static void dump_common_audit_data(struct audit_buffer *ab,
245 } 245 }
246 break; 246 break;
247 } 247 }
248 case LSM_AUDIT_DATA_IOCTL_OP: {
249 struct inode *inode;
250
251 audit_log_d_path(ab, " path=", &a->u.op->path);
252
253 inode = a->u.op->path.dentry->d_inode;
254 if (inode) {
255 audit_log_format(ab, " dev=");
256 audit_log_untrustedstring(ab, inode->i_sb->s_id);
257 audit_log_format(ab, " ino=%lu", inode->i_ino);
258 }
259
260 audit_log_format(ab, " ioctlcmd=%hx", a->u.op->cmd);
261 break;
262 }
248 case LSM_AUDIT_DATA_DENTRY: { 263 case LSM_AUDIT_DATA_DENTRY: {
249 struct inode *inode; 264 struct inode *inode;
250 265
diff --git a/security/security.c b/security/security.c
index 75b85fdc4e97..46f405ce6b0f 100644
--- a/security/security.c
+++ b/security/security.c
@@ -56,18 +56,13 @@ int __init security_init(void)
56 pr_info("Security Framework initialized\n"); 56 pr_info("Security Framework initialized\n");
57 57
58 /* 58 /*
59 * Always load the capability module. 59 * Load minor LSMs, with the capability module always first.
60 */ 60 */
61 capability_add_hooks(); 61 capability_add_hooks();
62#ifdef CONFIG_SECURITY_YAMA_STACKED
63 /*
64 * If Yama is configured for stacking load it next.
65 */
66 yama_add_hooks(); 62 yama_add_hooks();
67#endif 63
68 /* 64 /*
69 * Load the chosen module if there is one. 65 * Load all the remaining security modules.
70 * This will also find yama if it is stacking
71 */ 66 */
72 do_security_initcalls(); 67 do_security_initcalls();
73 68
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index 0b122b1421a9..e60c79de13e1 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -22,6 +22,7 @@
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/skbuff.h> 23#include <linux/skbuff.h>
24#include <linux/percpu.h> 24#include <linux/percpu.h>
25#include <linux/list.h>
25#include <net/sock.h> 26#include <net/sock.h>
26#include <linux/un.h> 27#include <linux/un.h>
27#include <net/af_unix.h> 28#include <net/af_unix.h>
@@ -48,6 +49,7 @@ struct avc_entry {
48 u32 tsid; 49 u32 tsid;
49 u16 tclass; 50 u16 tclass;
50 struct av_decision avd; 51 struct av_decision avd;
52 struct avc_xperms_node *xp_node;
51}; 53};
52 54
53struct avc_node { 55struct avc_node {
@@ -56,6 +58,16 @@ struct avc_node {
56 struct rcu_head rhead; 58 struct rcu_head rhead;
57}; 59};
58 60
61struct avc_xperms_decision_node {
62 struct extended_perms_decision xpd;
63 struct list_head xpd_list; /* list of extended_perms_decision */
64};
65
66struct avc_xperms_node {
67 struct extended_perms xp;
68 struct list_head xpd_head; /* list head of extended_perms_decision */
69};
70
59struct avc_cache { 71struct avc_cache {
60 struct hlist_head slots[AVC_CACHE_SLOTS]; /* head for avc_node->list */ 72 struct hlist_head slots[AVC_CACHE_SLOTS]; /* head for avc_node->list */
61 spinlock_t slots_lock[AVC_CACHE_SLOTS]; /* lock for writes */ 73 spinlock_t slots_lock[AVC_CACHE_SLOTS]; /* lock for writes */
@@ -80,6 +92,9 @@ DEFINE_PER_CPU(struct avc_cache_stats, avc_cache_stats) = { 0 };
80static struct avc_cache avc_cache; 92static struct avc_cache avc_cache;
81static struct avc_callback_node *avc_callbacks; 93static struct avc_callback_node *avc_callbacks;
82static struct kmem_cache *avc_node_cachep; 94static struct kmem_cache *avc_node_cachep;
95static struct kmem_cache *avc_xperms_data_cachep;
96static struct kmem_cache *avc_xperms_decision_cachep;
97static struct kmem_cache *avc_xperms_cachep;
83 98
84static inline int avc_hash(u32 ssid, u32 tsid, u16 tclass) 99static inline int avc_hash(u32 ssid, u32 tsid, u16 tclass)
85{ 100{
@@ -101,6 +116,7 @@ static void avc_dump_av(struct audit_buffer *ab, u16 tclass, u32 av)
101 return; 116 return;
102 } 117 }
103 118
119 BUG_ON(!tclass || tclass >= ARRAY_SIZE(secclass_map));
104 perms = secclass_map[tclass-1].perms; 120 perms = secclass_map[tclass-1].perms;
105 121
106 audit_log_format(ab, " {"); 122 audit_log_format(ab, " {");
@@ -149,7 +165,7 @@ static void avc_dump_query(struct audit_buffer *ab, u32 ssid, u32 tsid, u16 tcla
149 kfree(scontext); 165 kfree(scontext);
150 } 166 }
151 167
152 BUG_ON(tclass >= ARRAY_SIZE(secclass_map)); 168 BUG_ON(!tclass || tclass >= ARRAY_SIZE(secclass_map));
153 audit_log_format(ab, " tclass=%s", secclass_map[tclass-1].name); 169 audit_log_format(ab, " tclass=%s", secclass_map[tclass-1].name);
154} 170}
155 171
@@ -170,7 +186,17 @@ void __init avc_init(void)
170 atomic_set(&avc_cache.lru_hint, 0); 186 atomic_set(&avc_cache.lru_hint, 0);
171 187
172 avc_node_cachep = kmem_cache_create("avc_node", sizeof(struct avc_node), 188 avc_node_cachep = kmem_cache_create("avc_node", sizeof(struct avc_node),
173 0, SLAB_PANIC, NULL); 189 0, SLAB_PANIC, NULL);
190 avc_xperms_cachep = kmem_cache_create("avc_xperms_node",
191 sizeof(struct avc_xperms_node),
192 0, SLAB_PANIC, NULL);
193 avc_xperms_decision_cachep = kmem_cache_create(
194 "avc_xperms_decision_node",
195 sizeof(struct avc_xperms_decision_node),
196 0, SLAB_PANIC, NULL);
197 avc_xperms_data_cachep = kmem_cache_create("avc_xperms_data",
198 sizeof(struct extended_perms_data),
199 0, SLAB_PANIC, NULL);
174 200
175 audit_log(current->audit_context, GFP_KERNEL, AUDIT_KERNEL, "AVC INITIALIZED\n"); 201 audit_log(current->audit_context, GFP_KERNEL, AUDIT_KERNEL, "AVC INITIALIZED\n");
176} 202}
@@ -205,9 +231,261 @@ int avc_get_hash_stats(char *page)
205 slots_used, AVC_CACHE_SLOTS, max_chain_len); 231 slots_used, AVC_CACHE_SLOTS, max_chain_len);
206} 232}
207 233
234/*
235 * using a linked list for extended_perms_decision lookup because the list is
236 * always small. i.e. less than 5, typically 1
237 */
238static struct extended_perms_decision *avc_xperms_decision_lookup(u8 driver,
239 struct avc_xperms_node *xp_node)
240{
241 struct avc_xperms_decision_node *xpd_node;
242
243 list_for_each_entry(xpd_node, &xp_node->xpd_head, xpd_list) {
244 if (xpd_node->xpd.driver == driver)
245 return &xpd_node->xpd;
246 }
247 return NULL;
248}
249
250static inline unsigned int
251avc_xperms_has_perm(struct extended_perms_decision *xpd,
252 u8 perm, u8 which)
253{
254 unsigned int rc = 0;
255
256 if ((which == XPERMS_ALLOWED) &&
257 (xpd->used & XPERMS_ALLOWED))
258 rc = security_xperm_test(xpd->allowed->p, perm);
259 else if ((which == XPERMS_AUDITALLOW) &&
260 (xpd->used & XPERMS_AUDITALLOW))
261 rc = security_xperm_test(xpd->auditallow->p, perm);
262 else if ((which == XPERMS_DONTAUDIT) &&
263 (xpd->used & XPERMS_DONTAUDIT))
264 rc = security_xperm_test(xpd->dontaudit->p, perm);
265 return rc;
266}
267
268static void avc_xperms_allow_perm(struct avc_xperms_node *xp_node,
269 u8 driver, u8 perm)
270{
271 struct extended_perms_decision *xpd;
272 security_xperm_set(xp_node->xp.drivers.p, driver);
273 xpd = avc_xperms_decision_lookup(driver, xp_node);
274 if (xpd && xpd->allowed)
275 security_xperm_set(xpd->allowed->p, perm);
276}
277
278static void avc_xperms_decision_free(struct avc_xperms_decision_node *xpd_node)
279{
280 struct extended_perms_decision *xpd;
281
282 xpd = &xpd_node->xpd;
283 if (xpd->allowed)
284 kmem_cache_free(avc_xperms_data_cachep, xpd->allowed);
285 if (xpd->auditallow)
286 kmem_cache_free(avc_xperms_data_cachep, xpd->auditallow);
287 if (xpd->dontaudit)
288 kmem_cache_free(avc_xperms_data_cachep, xpd->dontaudit);
289 kmem_cache_free(avc_xperms_decision_cachep, xpd_node);
290}
291
292static void avc_xperms_free(struct avc_xperms_node *xp_node)
293{
294 struct avc_xperms_decision_node *xpd_node, *tmp;
295
296 if (!xp_node)
297 return;
298
299 list_for_each_entry_safe(xpd_node, tmp, &xp_node->xpd_head, xpd_list) {
300 list_del(&xpd_node->xpd_list);
301 avc_xperms_decision_free(xpd_node);
302 }
303 kmem_cache_free(avc_xperms_cachep, xp_node);
304}
305
306static void avc_copy_xperms_decision(struct extended_perms_decision *dest,
307 struct extended_perms_decision *src)
308{
309 dest->driver = src->driver;
310 dest->used = src->used;
311 if (dest->used & XPERMS_ALLOWED)
312 memcpy(dest->allowed->p, src->allowed->p,
313 sizeof(src->allowed->p));
314 if (dest->used & XPERMS_AUDITALLOW)
315 memcpy(dest->auditallow->p, src->auditallow->p,
316 sizeof(src->auditallow->p));
317 if (dest->used & XPERMS_DONTAUDIT)
318 memcpy(dest->dontaudit->p, src->dontaudit->p,
319 sizeof(src->dontaudit->p));
320}
321
322/*
323 * similar to avc_copy_xperms_decision, but only copy decision
324 * information relevant to this perm
325 */
326static inline void avc_quick_copy_xperms_decision(u8 perm,
327 struct extended_perms_decision *dest,
328 struct extended_perms_decision *src)
329{
330 /*
331 * compute index of the u32 of the 256 bits (8 u32s) that contain this
332 * command permission
333 */
334 u8 i = perm >> 5;
335
336 dest->used = src->used;
337 if (dest->used & XPERMS_ALLOWED)
338 dest->allowed->p[i] = src->allowed->p[i];
339 if (dest->used & XPERMS_AUDITALLOW)
340 dest->auditallow->p[i] = src->auditallow->p[i];
341 if (dest->used & XPERMS_DONTAUDIT)
342 dest->dontaudit->p[i] = src->dontaudit->p[i];
343}
344
345static struct avc_xperms_decision_node
346 *avc_xperms_decision_alloc(u8 which)
347{
348 struct avc_xperms_decision_node *xpd_node;
349 struct extended_perms_decision *xpd;
350
351 xpd_node = kmem_cache_zalloc(avc_xperms_decision_cachep,
352 GFP_ATOMIC | __GFP_NOMEMALLOC);
353 if (!xpd_node)
354 return NULL;
355
356 xpd = &xpd_node->xpd;
357 if (which & XPERMS_ALLOWED) {
358 xpd->allowed = kmem_cache_zalloc(avc_xperms_data_cachep,
359 GFP_ATOMIC | __GFP_NOMEMALLOC);
360 if (!xpd->allowed)
361 goto error;
362 }
363 if (which & XPERMS_AUDITALLOW) {
364 xpd->auditallow = kmem_cache_zalloc(avc_xperms_data_cachep,
365 GFP_ATOMIC | __GFP_NOMEMALLOC);
366 if (!xpd->auditallow)
367 goto error;
368 }
369 if (which & XPERMS_DONTAUDIT) {
370 xpd->dontaudit = kmem_cache_zalloc(avc_xperms_data_cachep,
371 GFP_ATOMIC | __GFP_NOMEMALLOC);
372 if (!xpd->dontaudit)
373 goto error;
374 }
375 return xpd_node;
376error:
377 avc_xperms_decision_free(xpd_node);
378 return NULL;
379}
380
381static int avc_add_xperms_decision(struct avc_node *node,
382 struct extended_perms_decision *src)
383{
384 struct avc_xperms_decision_node *dest_xpd;
385
386 node->ae.xp_node->xp.len++;
387 dest_xpd = avc_xperms_decision_alloc(src->used);
388 if (!dest_xpd)
389 return -ENOMEM;
390 avc_copy_xperms_decision(&dest_xpd->xpd, src);
391 list_add(&dest_xpd->xpd_list, &node->ae.xp_node->xpd_head);
392 return 0;
393}
394
395static struct avc_xperms_node *avc_xperms_alloc(void)
396{
397 struct avc_xperms_node *xp_node;
398
399 xp_node = kmem_cache_zalloc(avc_xperms_cachep,
400 GFP_ATOMIC|__GFP_NOMEMALLOC);
401 if (!xp_node)
402 return xp_node;
403 INIT_LIST_HEAD(&xp_node->xpd_head);
404 return xp_node;
405}
406
407static int avc_xperms_populate(struct avc_node *node,
408 struct avc_xperms_node *src)
409{
410 struct avc_xperms_node *dest;
411 struct avc_xperms_decision_node *dest_xpd;
412 struct avc_xperms_decision_node *src_xpd;
413
414 if (src->xp.len == 0)
415 return 0;
416 dest = avc_xperms_alloc();
417 if (!dest)
418 return -ENOMEM;
419
420 memcpy(dest->xp.drivers.p, src->xp.drivers.p, sizeof(dest->xp.drivers.p));
421 dest->xp.len = src->xp.len;
422
423 /* for each source xpd allocate a destination xpd and copy */
424 list_for_each_entry(src_xpd, &src->xpd_head, xpd_list) {
425 dest_xpd = avc_xperms_decision_alloc(src_xpd->xpd.used);
426 if (!dest_xpd)
427 goto error;
428 avc_copy_xperms_decision(&dest_xpd->xpd, &src_xpd->xpd);
429 list_add(&dest_xpd->xpd_list, &dest->xpd_head);
430 }
431 node->ae.xp_node = dest;
432 return 0;
433error:
434 avc_xperms_free(dest);
435 return -ENOMEM;
436
437}
438
439static inline u32 avc_xperms_audit_required(u32 requested,
440 struct av_decision *avd,
441 struct extended_perms_decision *xpd,
442 u8 perm,
443 int result,
444 u32 *deniedp)
445{
446 u32 denied, audited;
447
448 denied = requested & ~avd->allowed;
449 if (unlikely(denied)) {
450 audited = denied & avd->auditdeny;
451 if (audited && xpd) {
452 if (avc_xperms_has_perm(xpd, perm, XPERMS_DONTAUDIT))
453 audited &= ~requested;
454 }
455 } else if (result) {
456 audited = denied = requested;
457 } else {
458 audited = requested & avd->auditallow;
459 if (audited && xpd) {
460 if (!avc_xperms_has_perm(xpd, perm, XPERMS_AUDITALLOW))
461 audited &= ~requested;
462 }
463 }
464
465 *deniedp = denied;
466 return audited;
467}
468
469static inline int avc_xperms_audit(u32 ssid, u32 tsid, u16 tclass,
470 u32 requested, struct av_decision *avd,
471 struct extended_perms_decision *xpd,
472 u8 perm, int result,
473 struct common_audit_data *ad)
474{
475 u32 audited, denied;
476
477 audited = avc_xperms_audit_required(
478 requested, avd, xpd, perm, result, &denied);
479 if (likely(!audited))
480 return 0;
481 return slow_avc_audit(ssid, tsid, tclass, requested,
482 audited, denied, result, ad, 0);
483}
484
208static void avc_node_free(struct rcu_head *rhead) 485static void avc_node_free(struct rcu_head *rhead)
209{ 486{
210 struct avc_node *node = container_of(rhead, struct avc_node, rhead); 487 struct avc_node *node = container_of(rhead, struct avc_node, rhead);
488 avc_xperms_free(node->ae.xp_node);
211 kmem_cache_free(avc_node_cachep, node); 489 kmem_cache_free(avc_node_cachep, node);
212 avc_cache_stats_incr(frees); 490 avc_cache_stats_incr(frees);
213} 491}
@@ -221,6 +499,7 @@ static void avc_node_delete(struct avc_node *node)
221 499
222static void avc_node_kill(struct avc_node *node) 500static void avc_node_kill(struct avc_node *node)
223{ 501{
502 avc_xperms_free(node->ae.xp_node);
224 kmem_cache_free(avc_node_cachep, node); 503 kmem_cache_free(avc_node_cachep, node);
225 avc_cache_stats_incr(frees); 504 avc_cache_stats_incr(frees);
226 atomic_dec(&avc_cache.active_nodes); 505 atomic_dec(&avc_cache.active_nodes);
@@ -367,6 +646,7 @@ static int avc_latest_notif_update(int seqno, int is_insert)
367 * @tsid: target security identifier 646 * @tsid: target security identifier
368 * @tclass: target security class 647 * @tclass: target security class
369 * @avd: resulting av decision 648 * @avd: resulting av decision
649 * @xp_node: resulting extended permissions
370 * 650 *
371 * Insert an AVC entry for the SID pair 651 * Insert an AVC entry for the SID pair
372 * (@ssid, @tsid) and class @tclass. 652 * (@ssid, @tsid) and class @tclass.
@@ -378,7 +658,9 @@ static int avc_latest_notif_update(int seqno, int is_insert)
378 * the access vectors into a cache entry, returns 658 * the access vectors into a cache entry, returns
379 * avc_node inserted. Otherwise, this function returns NULL. 659 * avc_node inserted. Otherwise, this function returns NULL.
380 */ 660 */
381static struct avc_node *avc_insert(u32 ssid, u32 tsid, u16 tclass, struct av_decision *avd) 661static struct avc_node *avc_insert(u32 ssid, u32 tsid, u16 tclass,
662 struct av_decision *avd,
663 struct avc_xperms_node *xp_node)
382{ 664{
383 struct avc_node *pos, *node = NULL; 665 struct avc_node *pos, *node = NULL;
384 int hvalue; 666 int hvalue;
@@ -391,10 +673,15 @@ static struct avc_node *avc_insert(u32 ssid, u32 tsid, u16 tclass, struct av_dec
391 if (node) { 673 if (node) {
392 struct hlist_head *head; 674 struct hlist_head *head;
393 spinlock_t *lock; 675 spinlock_t *lock;
676 int rc = 0;
394 677
395 hvalue = avc_hash(ssid, tsid, tclass); 678 hvalue = avc_hash(ssid, tsid, tclass);
396 avc_node_populate(node, ssid, tsid, tclass, avd); 679 avc_node_populate(node, ssid, tsid, tclass, avd);
397 680 rc = avc_xperms_populate(node, xp_node);
681 if (rc) {
682 kmem_cache_free(avc_node_cachep, node);
683 return NULL;
684 }
398 head = &avc_cache.slots[hvalue]; 685 head = &avc_cache.slots[hvalue];
399 lock = &avc_cache.slots_lock[hvalue]; 686 lock = &avc_cache.slots_lock[hvalue];
400 687
@@ -523,14 +810,17 @@ out:
523 * @perms : Permission mask bits 810 * @perms : Permission mask bits
524 * @ssid,@tsid,@tclass : identifier of an AVC entry 811 * @ssid,@tsid,@tclass : identifier of an AVC entry
525 * @seqno : sequence number when decision was made 812 * @seqno : sequence number when decision was made
813 * @xpd: extended_perms_decision to be added to the node
526 * 814 *
527 * if a valid AVC entry doesn't exist,this function returns -ENOENT. 815 * if a valid AVC entry doesn't exist,this function returns -ENOENT.
528 * if kmalloc() called internal returns NULL, this function returns -ENOMEM. 816 * if kmalloc() called internal returns NULL, this function returns -ENOMEM.
529 * otherwise, this function updates the AVC entry. The original AVC-entry object 817 * otherwise, this function updates the AVC entry. The original AVC-entry object
530 * will release later by RCU. 818 * will release later by RCU.
531 */ 819 */
532static int avc_update_node(u32 event, u32 perms, u32 ssid, u32 tsid, u16 tclass, 820static int avc_update_node(u32 event, u32 perms, u8 driver, u8 xperm, u32 ssid,
533 u32 seqno) 821 u32 tsid, u16 tclass, u32 seqno,
822 struct extended_perms_decision *xpd,
823 u32 flags)
534{ 824{
535 int hvalue, rc = 0; 825 int hvalue, rc = 0;
536 unsigned long flag; 826 unsigned long flag;
@@ -574,9 +864,19 @@ static int avc_update_node(u32 event, u32 perms, u32 ssid, u32 tsid, u16 tclass,
574 864
575 avc_node_populate(node, ssid, tsid, tclass, &orig->ae.avd); 865 avc_node_populate(node, ssid, tsid, tclass, &orig->ae.avd);
576 866
867 if (orig->ae.xp_node) {
868 rc = avc_xperms_populate(node, orig->ae.xp_node);
869 if (rc) {
870 kmem_cache_free(avc_node_cachep, node);
871 goto out_unlock;
872 }
873 }
874
577 switch (event) { 875 switch (event) {
578 case AVC_CALLBACK_GRANT: 876 case AVC_CALLBACK_GRANT:
579 node->ae.avd.allowed |= perms; 877 node->ae.avd.allowed |= perms;
878 if (node->ae.xp_node && (flags & AVC_EXTENDED_PERMS))
879 avc_xperms_allow_perm(node->ae.xp_node, driver, xperm);
580 break; 880 break;
581 case AVC_CALLBACK_TRY_REVOKE: 881 case AVC_CALLBACK_TRY_REVOKE:
582 case AVC_CALLBACK_REVOKE: 882 case AVC_CALLBACK_REVOKE:
@@ -594,6 +894,9 @@ static int avc_update_node(u32 event, u32 perms, u32 ssid, u32 tsid, u16 tclass,
594 case AVC_CALLBACK_AUDITDENY_DISABLE: 894 case AVC_CALLBACK_AUDITDENY_DISABLE:
595 node->ae.avd.auditdeny &= ~perms; 895 node->ae.avd.auditdeny &= ~perms;
596 break; 896 break;
897 case AVC_CALLBACK_ADD_XPERMS:
898 avc_add_xperms_decision(node, xpd);
899 break;
597 } 900 }
598 avc_node_replace(node, orig); 901 avc_node_replace(node, orig);
599out_unlock: 902out_unlock:
@@ -665,18 +968,20 @@ int avc_ss_reset(u32 seqno)
665 * results in a bigger stack frame. 968 * results in a bigger stack frame.
666 */ 969 */
667static noinline struct avc_node *avc_compute_av(u32 ssid, u32 tsid, 970static noinline struct avc_node *avc_compute_av(u32 ssid, u32 tsid,
668 u16 tclass, struct av_decision *avd) 971 u16 tclass, struct av_decision *avd,
972 struct avc_xperms_node *xp_node)
669{ 973{
670 rcu_read_unlock(); 974 rcu_read_unlock();
671 security_compute_av(ssid, tsid, tclass, avd); 975 INIT_LIST_HEAD(&xp_node->xpd_head);
976 security_compute_av(ssid, tsid, tclass, avd, &xp_node->xp);
672 rcu_read_lock(); 977 rcu_read_lock();
673 return avc_insert(ssid, tsid, tclass, avd); 978 return avc_insert(ssid, tsid, tclass, avd, xp_node);
674} 979}
675 980
676static noinline int avc_denied(u32 ssid, u32 tsid, 981static noinline int avc_denied(u32 ssid, u32 tsid,
677 u16 tclass, u32 requested, 982 u16 tclass, u32 requested,
678 unsigned flags, 983 u8 driver, u8 xperm, unsigned flags,
679 struct av_decision *avd) 984 struct av_decision *avd)
680{ 985{
681 if (flags & AVC_STRICT) 986 if (flags & AVC_STRICT)
682 return -EACCES; 987 return -EACCES;
@@ -684,11 +989,91 @@ static noinline int avc_denied(u32 ssid, u32 tsid,
684 if (selinux_enforcing && !(avd->flags & AVD_FLAGS_PERMISSIVE)) 989 if (selinux_enforcing && !(avd->flags & AVD_FLAGS_PERMISSIVE))
685 return -EACCES; 990 return -EACCES;
686 991
687 avc_update_node(AVC_CALLBACK_GRANT, requested, ssid, 992 avc_update_node(AVC_CALLBACK_GRANT, requested, driver, xperm, ssid,
688 tsid, tclass, avd->seqno); 993 tsid, tclass, avd->seqno, NULL, flags);
689 return 0; 994 return 0;
690} 995}
691 996
997/*
998 * The avc extended permissions logic adds an additional 256 bits of
999 * permissions to an avc node when extended permissions for that node are
1000 * specified in the avtab. If the additional 256 permissions is not adequate,
1001 * as-is the case with ioctls, then multiple may be chained together and the
1002 * driver field is used to specify which set contains the permission.
1003 */
1004int avc_has_extended_perms(u32 ssid, u32 tsid, u16 tclass, u32 requested,
1005 u8 driver, u8 xperm, struct common_audit_data *ad)
1006{
1007 struct avc_node *node;
1008 struct av_decision avd;
1009 u32 denied;
1010 struct extended_perms_decision local_xpd;
1011 struct extended_perms_decision *xpd = NULL;
1012 struct extended_perms_data allowed;
1013 struct extended_perms_data auditallow;
1014 struct extended_perms_data dontaudit;
1015 struct avc_xperms_node local_xp_node;
1016 struct avc_xperms_node *xp_node;
1017 int rc = 0, rc2;
1018
1019 xp_node = &local_xp_node;
1020 BUG_ON(!requested);
1021
1022 rcu_read_lock();
1023
1024 node = avc_lookup(ssid, tsid, tclass);
1025 if (unlikely(!node)) {
1026 node = avc_compute_av(ssid, tsid, tclass, &avd, xp_node);
1027 } else {
1028 memcpy(&avd, &node->ae.avd, sizeof(avd));
1029 xp_node = node->ae.xp_node;
1030 }
1031 /* if extended permissions are not defined, only consider av_decision */
1032 if (!xp_node || !xp_node->xp.len)
1033 goto decision;
1034
1035 local_xpd.allowed = &allowed;
1036 local_xpd.auditallow = &auditallow;
1037 local_xpd.dontaudit = &dontaudit;
1038
1039 xpd = avc_xperms_decision_lookup(driver, xp_node);
1040 if (unlikely(!xpd)) {
1041 /*
1042 * Compute the extended_perms_decision only if the driver
1043 * is flagged
1044 */
1045 if (!security_xperm_test(xp_node->xp.drivers.p, driver)) {
1046 avd.allowed &= ~requested;
1047 goto decision;
1048 }
1049 rcu_read_unlock();
1050 security_compute_xperms_decision(ssid, tsid, tclass, driver,
1051 &local_xpd);
1052 rcu_read_lock();
1053 avc_update_node(AVC_CALLBACK_ADD_XPERMS, requested, driver, xperm,
1054 ssid, tsid, tclass, avd.seqno, &local_xpd, 0);
1055 } else {
1056 avc_quick_copy_xperms_decision(xperm, &local_xpd, xpd);
1057 }
1058 xpd = &local_xpd;
1059
1060 if (!avc_xperms_has_perm(xpd, xperm, XPERMS_ALLOWED))
1061 avd.allowed &= ~requested;
1062
1063decision:
1064 denied = requested & ~(avd.allowed);
1065 if (unlikely(denied))
1066 rc = avc_denied(ssid, tsid, tclass, requested, driver, xperm,
1067 AVC_EXTENDED_PERMS, &avd);
1068
1069 rcu_read_unlock();
1070
1071 rc2 = avc_xperms_audit(ssid, tsid, tclass, requested,
1072 &avd, xpd, xperm, rc, ad);
1073 if (rc2)
1074 return rc2;
1075 return rc;
1076}
692 1077
693/** 1078/**
694 * avc_has_perm_noaudit - Check permissions but perform no auditing. 1079 * avc_has_perm_noaudit - Check permissions but perform no auditing.
@@ -716,6 +1101,7 @@ inline int avc_has_perm_noaudit(u32 ssid, u32 tsid,
716 struct av_decision *avd) 1101 struct av_decision *avd)
717{ 1102{
718 struct avc_node *node; 1103 struct avc_node *node;
1104 struct avc_xperms_node xp_node;
719 int rc = 0; 1105 int rc = 0;
720 u32 denied; 1106 u32 denied;
721 1107
@@ -725,13 +1111,13 @@ inline int avc_has_perm_noaudit(u32 ssid, u32 tsid,
725 1111
726 node = avc_lookup(ssid, tsid, tclass); 1112 node = avc_lookup(ssid, tsid, tclass);
727 if (unlikely(!node)) 1113 if (unlikely(!node))
728 node = avc_compute_av(ssid, tsid, tclass, avd); 1114 node = avc_compute_av(ssid, tsid, tclass, avd, &xp_node);
729 else 1115 else
730 memcpy(avd, &node->ae.avd, sizeof(*avd)); 1116 memcpy(avd, &node->ae.avd, sizeof(*avd));
731 1117
732 denied = requested & ~(avd->allowed); 1118 denied = requested & ~(avd->allowed);
733 if (unlikely(denied)) 1119 if (unlikely(denied))
734 rc = avc_denied(ssid, tsid, tclass, requested, flags, avd); 1120 rc = avc_denied(ssid, tsid, tclass, requested, 0, 0, flags, avd);
735 1121
736 rcu_read_unlock(); 1122 rcu_read_unlock();
737 return rc; 1123 return rc;
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index cdf4c589a391..e4369d86e588 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -254,10 +254,21 @@ static void inode_free_security(struct inode *inode)
254 struct inode_security_struct *isec = inode->i_security; 254 struct inode_security_struct *isec = inode->i_security;
255 struct superblock_security_struct *sbsec = inode->i_sb->s_security; 255 struct superblock_security_struct *sbsec = inode->i_sb->s_security;
256 256
257 spin_lock(&sbsec->isec_lock); 257 /*
258 if (!list_empty(&isec->list)) 258 * As not all inode security structures are in a list, we check for
259 * empty list outside of the lock to make sure that we won't waste
260 * time taking a lock doing nothing.
261 *
262 * The list_del_init() function can be safely called more than once.
263 * It should not be possible for this function to be called with
264 * concurrent list_add(), but for better safety against future changes
265 * in the code, we use list_empty_careful() here.
266 */
267 if (!list_empty_careful(&isec->list)) {
268 spin_lock(&sbsec->isec_lock);
259 list_del_init(&isec->list); 269 list_del_init(&isec->list);
260 spin_unlock(&sbsec->isec_lock); 270 spin_unlock(&sbsec->isec_lock);
271 }
261 272
262 /* 273 /*
263 * The inode may still be referenced in a path walk and 274 * The inode may still be referenced in a path walk and
@@ -1698,6 +1709,32 @@ out:
1698 return rc; 1709 return rc;
1699} 1710}
1700 1711
1712/*
1713 * Determine the label for an inode that might be unioned.
1714 */
1715static int selinux_determine_inode_label(const struct inode *dir,
1716 const struct qstr *name,
1717 u16 tclass,
1718 u32 *_new_isid)
1719{
1720 const struct superblock_security_struct *sbsec = dir->i_sb->s_security;
1721 const struct inode_security_struct *dsec = dir->i_security;
1722 const struct task_security_struct *tsec = current_security();
1723
1724 if ((sbsec->flags & SE_SBINITIALIZED) &&
1725 (sbsec->behavior == SECURITY_FS_USE_MNTPOINT)) {
1726 *_new_isid = sbsec->mntpoint_sid;
1727 } else if ((sbsec->flags & SBLABEL_MNT) &&
1728 tsec->create_sid) {
1729 *_new_isid = tsec->create_sid;
1730 } else {
1731 return security_transition_sid(tsec->sid, dsec->sid, tclass,
1732 name, _new_isid);
1733 }
1734
1735 return 0;
1736}
1737
1701/* Check whether a task can create a file. */ 1738/* Check whether a task can create a file. */
1702static int may_create(struct inode *dir, 1739static int may_create(struct inode *dir,
1703 struct dentry *dentry, 1740 struct dentry *dentry,
@@ -1714,7 +1751,6 @@ static int may_create(struct inode *dir,
1714 sbsec = dir->i_sb->s_security; 1751 sbsec = dir->i_sb->s_security;
1715 1752
1716 sid = tsec->sid; 1753 sid = tsec->sid;
1717 newsid = tsec->create_sid;
1718 1754
1719 ad.type = LSM_AUDIT_DATA_DENTRY; 1755 ad.type = LSM_AUDIT_DATA_DENTRY;
1720 ad.u.dentry = dentry; 1756 ad.u.dentry = dentry;
@@ -1725,12 +1761,10 @@ static int may_create(struct inode *dir,
1725 if (rc) 1761 if (rc)
1726 return rc; 1762 return rc;
1727 1763
1728 if (!newsid || !(sbsec->flags & SBLABEL_MNT)) { 1764 rc = selinux_determine_inode_label(dir, &dentry->d_name, tclass,
1729 rc = security_transition_sid(sid, dsec->sid, tclass, 1765 &newsid);
1730 &dentry->d_name, &newsid); 1766 if (rc)
1731 if (rc) 1767 return rc;
1732 return rc;
1733 }
1734 1768
1735 rc = avc_has_perm(sid, newsid, tclass, FILE__CREATE, &ad); 1769 rc = avc_has_perm(sid, newsid, tclass, FILE__CREATE, &ad);
1736 if (rc) 1770 if (rc)
@@ -2704,32 +2738,14 @@ static int selinux_dentry_init_security(struct dentry *dentry, int mode,
2704 struct qstr *name, void **ctx, 2738 struct qstr *name, void **ctx,
2705 u32 *ctxlen) 2739 u32 *ctxlen)
2706{ 2740{
2707 const struct cred *cred = current_cred();
2708 struct task_security_struct *tsec;
2709 struct inode_security_struct *dsec;
2710 struct superblock_security_struct *sbsec;
2711 struct inode *dir = d_backing_inode(dentry->d_parent);
2712 u32 newsid; 2741 u32 newsid;
2713 int rc; 2742 int rc;
2714 2743
2715 tsec = cred->security; 2744 rc = selinux_determine_inode_label(d_inode(dentry->d_parent), name,
2716 dsec = dir->i_security; 2745 inode_mode_to_security_class(mode),
2717 sbsec = dir->i_sb->s_security; 2746 &newsid);
2718 2747 if (rc)
2719 if (tsec->create_sid && sbsec->behavior != SECURITY_FS_USE_MNTPOINT) { 2748 return rc;
2720 newsid = tsec->create_sid;
2721 } else {
2722 rc = security_transition_sid(tsec->sid, dsec->sid,
2723 inode_mode_to_security_class(mode),
2724 name,
2725 &newsid);
2726 if (rc) {
2727 printk(KERN_WARNING
2728 "%s: security_transition_sid failed, rc=%d\n",
2729 __func__, -rc);
2730 return rc;
2731 }
2732 }
2733 2749
2734 return security_sid_to_context(newsid, (char **)ctx, ctxlen); 2750 return security_sid_to_context(newsid, (char **)ctx, ctxlen);
2735} 2751}
@@ -2752,22 +2768,12 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
2752 sid = tsec->sid; 2768 sid = tsec->sid;
2753 newsid = tsec->create_sid; 2769 newsid = tsec->create_sid;
2754 2770
2755 if ((sbsec->flags & SE_SBINITIALIZED) && 2771 rc = selinux_determine_inode_label(
2756 (sbsec->behavior == SECURITY_FS_USE_MNTPOINT)) 2772 dir, qstr,
2757 newsid = sbsec->mntpoint_sid; 2773 inode_mode_to_security_class(inode->i_mode),
2758 else if (!newsid || !(sbsec->flags & SBLABEL_MNT)) { 2774 &newsid);
2759 rc = security_transition_sid(sid, dsec->sid, 2775 if (rc)
2760 inode_mode_to_security_class(inode->i_mode), 2776 return rc;
2761 qstr, &newsid);
2762 if (rc) {
2763 printk(KERN_WARNING "%s: "
2764 "security_transition_sid failed, rc=%d (dev=%s "
2765 "ino=%ld)\n",
2766 __func__,
2767 -rc, inode->i_sb->s_id, inode->i_ino);
2768 return rc;
2769 }
2770 }
2771 2777
2772 /* Possibly defer initialization to selinux_complete_init. */ 2778 /* Possibly defer initialization to selinux_complete_init. */
2773 if (sbsec->flags & SE_SBINITIALIZED) { 2779 if (sbsec->flags & SE_SBINITIALIZED) {
@@ -3228,6 +3234,46 @@ static void selinux_file_free_security(struct file *file)
3228 file_free_security(file); 3234 file_free_security(file);
3229} 3235}
3230 3236
3237/*
3238 * Check whether a task has the ioctl permission and cmd
3239 * operation to an inode.
3240 */
3241int ioctl_has_perm(const struct cred *cred, struct file *file,
3242 u32 requested, u16 cmd)
3243{
3244 struct common_audit_data ad;
3245 struct file_security_struct *fsec = file->f_security;
3246 struct inode *inode = file_inode(file);
3247 struct inode_security_struct *isec = inode->i_security;
3248 struct lsm_ioctlop_audit ioctl;
3249 u32 ssid = cred_sid(cred);
3250 int rc;
3251 u8 driver = cmd >> 8;
3252 u8 xperm = cmd & 0xff;
3253
3254 ad.type = LSM_AUDIT_DATA_IOCTL_OP;
3255 ad.u.op = &ioctl;
3256 ad.u.op->cmd = cmd;
3257 ad.u.op->path = file->f_path;
3258
3259 if (ssid != fsec->sid) {
3260 rc = avc_has_perm(ssid, fsec->sid,
3261 SECCLASS_FD,
3262 FD__USE,
3263 &ad);
3264 if (rc)
3265 goto out;
3266 }
3267
3268 if (unlikely(IS_PRIVATE(inode)))
3269 return 0;
3270
3271 rc = avc_has_extended_perms(ssid, isec->sid, isec->sclass,
3272 requested, driver, xperm, &ad);
3273out:
3274 return rc;
3275}
3276
3231static int selinux_file_ioctl(struct file *file, unsigned int cmd, 3277static int selinux_file_ioctl(struct file *file, unsigned int cmd,
3232 unsigned long arg) 3278 unsigned long arg)
3233{ 3279{
@@ -3270,7 +3316,7 @@ static int selinux_file_ioctl(struct file *file, unsigned int cmd,
3270 * to the file's ioctl() function. 3316 * to the file's ioctl() function.
3271 */ 3317 */
3272 default: 3318 default:
3273 error = file_has_perm(cred, file, FILE__IOCTL); 3319 error = ioctl_has_perm(cred, file, FILE__IOCTL, (u16) cmd);
3274 } 3320 }
3275 return error; 3321 return error;
3276} 3322}
@@ -4520,6 +4566,7 @@ static int selinux_sk_alloc_security(struct sock *sk, int family, gfp_t priority
4520 4566
4521 sksec->peer_sid = SECINITSID_UNLABELED; 4567 sksec->peer_sid = SECINITSID_UNLABELED;
4522 sksec->sid = SECINITSID_UNLABELED; 4568 sksec->sid = SECINITSID_UNLABELED;
4569 sksec->sclass = SECCLASS_SOCKET;
4523 selinux_netlbl_sk_security_reset(sksec); 4570 selinux_netlbl_sk_security_reset(sksec);
4524 sk->sk_security = sksec; 4571 sk->sk_security = sksec;
4525 4572
diff --git a/security/selinux/include/avc.h b/security/selinux/include/avc.h
index 5973c327c54e..0999df03af8b 100644
--- a/security/selinux/include/avc.h
+++ b/security/selinux/include/avc.h
@@ -143,6 +143,7 @@ static inline int avc_audit(u32 ssid, u32 tsid,
143} 143}
144 144
145#define AVC_STRICT 1 /* Ignore permissive mode. */ 145#define AVC_STRICT 1 /* Ignore permissive mode. */
146#define AVC_EXTENDED_PERMS 2 /* update extended permissions */
146int avc_has_perm_noaudit(u32 ssid, u32 tsid, 147int avc_has_perm_noaudit(u32 ssid, u32 tsid,
147 u16 tclass, u32 requested, 148 u16 tclass, u32 requested,
148 unsigned flags, 149 unsigned flags,
@@ -156,6 +157,10 @@ int avc_has_perm_flags(u32 ssid, u32 tsid,
156 struct common_audit_data *auditdata, 157 struct common_audit_data *auditdata,
157 int flags); 158 int flags);
158 159
160int avc_has_extended_perms(u32 ssid, u32 tsid, u16 tclass, u32 requested,
161 u8 driver, u8 perm, struct common_audit_data *ad);
162
163
159u32 avc_policy_seqno(void); 164u32 avc_policy_seqno(void);
160 165
161#define AVC_CALLBACK_GRANT 1 166#define AVC_CALLBACK_GRANT 1
@@ -166,6 +171,7 @@ u32 avc_policy_seqno(void);
166#define AVC_CALLBACK_AUDITALLOW_DISABLE 32 171#define AVC_CALLBACK_AUDITALLOW_DISABLE 32
167#define AVC_CALLBACK_AUDITDENY_ENABLE 64 172#define AVC_CALLBACK_AUDITDENY_ENABLE 64
168#define AVC_CALLBACK_AUDITDENY_DISABLE 128 173#define AVC_CALLBACK_AUDITDENY_DISABLE 128
174#define AVC_CALLBACK_ADD_XPERMS 256
169 175
170int avc_add_callback(int (*callback)(u32 event), u32 events); 176int avc_add_callback(int (*callback)(u32 event), u32 events);
171 177
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index 36993ad1c067..6a681d26bf20 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -35,13 +35,14 @@
35#define POLICYDB_VERSION_NEW_OBJECT_DEFAULTS 27 35#define POLICYDB_VERSION_NEW_OBJECT_DEFAULTS 27
36#define POLICYDB_VERSION_DEFAULT_TYPE 28 36#define POLICYDB_VERSION_DEFAULT_TYPE 28
37#define POLICYDB_VERSION_CONSTRAINT_NAMES 29 37#define POLICYDB_VERSION_CONSTRAINT_NAMES 29
38#define POLICYDB_VERSION_XPERMS_IOCTL 30
38 39
39/* Range of policy versions we understand*/ 40/* Range of policy versions we understand*/
40#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE 41#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE
41#ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX 42#ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX
42#define POLICYDB_VERSION_MAX CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE 43#define POLICYDB_VERSION_MAX CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE
43#else 44#else
44#define POLICYDB_VERSION_MAX POLICYDB_VERSION_CONSTRAINT_NAMES 45#define POLICYDB_VERSION_MAX POLICYDB_VERSION_XPERMS_IOCTL
45#endif 46#endif
46 47
47/* Mask for just the mount related flags */ 48/* Mask for just the mount related flags */
@@ -109,11 +110,38 @@ struct av_decision {
109 u32 flags; 110 u32 flags;
110}; 111};
111 112
113#define XPERMS_ALLOWED 1
114#define XPERMS_AUDITALLOW 2
115#define XPERMS_DONTAUDIT 4
116
117#define security_xperm_set(perms, x) (perms[x >> 5] |= 1 << (x & 0x1f))
118#define security_xperm_test(perms, x) (1 & (perms[x >> 5] >> (x & 0x1f)))
119struct extended_perms_data {
120 u32 p[8];
121};
122
123struct extended_perms_decision {
124 u8 used;
125 u8 driver;
126 struct extended_perms_data *allowed;
127 struct extended_perms_data *auditallow;
128 struct extended_perms_data *dontaudit;
129};
130
131struct extended_perms {
132 u16 len; /* length associated decision chain */
133 struct extended_perms_data drivers; /* flag drivers that are used */
134};
135
112/* definitions of av_decision.flags */ 136/* definitions of av_decision.flags */
113#define AVD_FLAGS_PERMISSIVE 0x0001 137#define AVD_FLAGS_PERMISSIVE 0x0001
114 138
115void security_compute_av(u32 ssid, u32 tsid, 139void security_compute_av(u32 ssid, u32 tsid,
116 u16 tclass, struct av_decision *avd); 140 u16 tclass, struct av_decision *avd,
141 struct extended_perms *xperms);
142
143void security_compute_xperms_decision(u32 ssid, u32 tsid, u16 tclass,
144 u8 driver, struct extended_perms_decision *xpermd);
117 145
118void security_compute_av_user(u32 ssid, u32 tsid, 146void security_compute_av_user(u32 ssid, u32 tsid,
119 u16 tclass, struct av_decision *avd); 147 u16 tclass, struct av_decision *avd);
diff --git a/security/selinux/ss/avtab.c b/security/selinux/ss/avtab.c
index b64f2772b030..3628d3a868b6 100644
--- a/security/selinux/ss/avtab.c
+++ b/security/selinux/ss/avtab.c
@@ -24,6 +24,7 @@
24#include "policydb.h" 24#include "policydb.h"
25 25
26static struct kmem_cache *avtab_node_cachep; 26static struct kmem_cache *avtab_node_cachep;
27static struct kmem_cache *avtab_xperms_cachep;
27 28
28/* Based on MurmurHash3, written by Austin Appleby and placed in the 29/* Based on MurmurHash3, written by Austin Appleby and placed in the
29 * public domain. 30 * public domain.
@@ -70,11 +71,24 @@ avtab_insert_node(struct avtab *h, int hvalue,
70 struct avtab_key *key, struct avtab_datum *datum) 71 struct avtab_key *key, struct avtab_datum *datum)
71{ 72{
72 struct avtab_node *newnode; 73 struct avtab_node *newnode;
74 struct avtab_extended_perms *xperms;
73 newnode = kmem_cache_zalloc(avtab_node_cachep, GFP_KERNEL); 75 newnode = kmem_cache_zalloc(avtab_node_cachep, GFP_KERNEL);
74 if (newnode == NULL) 76 if (newnode == NULL)
75 return NULL; 77 return NULL;
76 newnode->key = *key; 78 newnode->key = *key;
77 newnode->datum = *datum; 79
80 if (key->specified & AVTAB_XPERMS) {
81 xperms = kmem_cache_zalloc(avtab_xperms_cachep, GFP_KERNEL);
82 if (xperms == NULL) {
83 kmem_cache_free(avtab_node_cachep, newnode);
84 return NULL;
85 }
86 *xperms = *(datum->u.xperms);
87 newnode->datum.u.xperms = xperms;
88 } else {
89 newnode->datum.u.data = datum->u.data;
90 }
91
78 if (prev) { 92 if (prev) {
79 newnode->next = prev->next; 93 newnode->next = prev->next;
80 prev->next = newnode; 94 prev->next = newnode;
@@ -107,8 +121,12 @@ static int avtab_insert(struct avtab *h, struct avtab_key *key, struct avtab_dat
107 if (key->source_type == cur->key.source_type && 121 if (key->source_type == cur->key.source_type &&
108 key->target_type == cur->key.target_type && 122 key->target_type == cur->key.target_type &&
109 key->target_class == cur->key.target_class && 123 key->target_class == cur->key.target_class &&
110 (specified & cur->key.specified)) 124 (specified & cur->key.specified)) {
125 /* extended perms may not be unique */
126 if (specified & AVTAB_XPERMS)
127 break;
111 return -EEXIST; 128 return -EEXIST;
129 }
112 if (key->source_type < cur->key.source_type) 130 if (key->source_type < cur->key.source_type)
113 break; 131 break;
114 if (key->source_type == cur->key.source_type && 132 if (key->source_type == cur->key.source_type &&
@@ -271,6 +289,9 @@ void avtab_destroy(struct avtab *h)
271 while (cur) { 289 while (cur) {
272 temp = cur; 290 temp = cur;
273 cur = cur->next; 291 cur = cur->next;
292 if (temp->key.specified & AVTAB_XPERMS)
293 kmem_cache_free(avtab_xperms_cachep,
294 temp->datum.u.xperms);
274 kmem_cache_free(avtab_node_cachep, temp); 295 kmem_cache_free(avtab_node_cachep, temp);
275 } 296 }
276 } 297 }
@@ -359,7 +380,10 @@ static uint16_t spec_order[] = {
359 AVTAB_AUDITALLOW, 380 AVTAB_AUDITALLOW,
360 AVTAB_TRANSITION, 381 AVTAB_TRANSITION,
361 AVTAB_CHANGE, 382 AVTAB_CHANGE,
362 AVTAB_MEMBER 383 AVTAB_MEMBER,
384 AVTAB_XPERMS_ALLOWED,
385 AVTAB_XPERMS_AUDITALLOW,
386 AVTAB_XPERMS_DONTAUDIT
363}; 387};
364 388
365int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol, 389int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol,
@@ -369,10 +393,11 @@ int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol,
369{ 393{
370 __le16 buf16[4]; 394 __le16 buf16[4];
371 u16 enabled; 395 u16 enabled;
372 __le32 buf32[7];
373 u32 items, items2, val, vers = pol->policyvers; 396 u32 items, items2, val, vers = pol->policyvers;
374 struct avtab_key key; 397 struct avtab_key key;
375 struct avtab_datum datum; 398 struct avtab_datum datum;
399 struct avtab_extended_perms xperms;
400 __le32 buf32[ARRAY_SIZE(xperms.perms.p)];
376 int i, rc; 401 int i, rc;
377 unsigned set; 402 unsigned set;
378 403
@@ -429,11 +454,15 @@ int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol,
429 printk(KERN_ERR "SELinux: avtab: entry has both access vectors and types\n"); 454 printk(KERN_ERR "SELinux: avtab: entry has both access vectors and types\n");
430 return -EINVAL; 455 return -EINVAL;
431 } 456 }
457 if (val & AVTAB_XPERMS) {
458 printk(KERN_ERR "SELinux: avtab: entry has extended permissions\n");
459 return -EINVAL;
460 }
432 461
433 for (i = 0; i < ARRAY_SIZE(spec_order); i++) { 462 for (i = 0; i < ARRAY_SIZE(spec_order); i++) {
434 if (val & spec_order[i]) { 463 if (val & spec_order[i]) {
435 key.specified = spec_order[i] | enabled; 464 key.specified = spec_order[i] | enabled;
436 datum.data = le32_to_cpu(buf32[items++]); 465 datum.u.data = le32_to_cpu(buf32[items++]);
437 rc = insertf(a, &key, &datum, p); 466 rc = insertf(a, &key, &datum, p);
438 if (rc) 467 if (rc)
439 return rc; 468 return rc;
@@ -476,14 +505,42 @@ int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol,
476 return -EINVAL; 505 return -EINVAL;
477 } 506 }
478 507
479 rc = next_entry(buf32, fp, sizeof(u32)); 508 if ((vers < POLICYDB_VERSION_XPERMS_IOCTL) &&
480 if (rc) { 509 (key.specified & AVTAB_XPERMS)) {
481 printk(KERN_ERR "SELinux: avtab: truncated entry\n"); 510 printk(KERN_ERR "SELinux: avtab: policy version %u does not "
482 return rc; 511 "support extended permissions rules and one "
512 "was specified\n", vers);
513 return -EINVAL;
514 } else if (key.specified & AVTAB_XPERMS) {
515 memset(&xperms, 0, sizeof(struct avtab_extended_perms));
516 rc = next_entry(&xperms.specified, fp, sizeof(u8));
517 if (rc) {
518 printk(KERN_ERR "SELinux: avtab: truncated entry\n");
519 return rc;
520 }
521 rc = next_entry(&xperms.driver, fp, sizeof(u8));
522 if (rc) {
523 printk(KERN_ERR "SELinux: avtab: truncated entry\n");
524 return rc;
525 }
526 rc = next_entry(buf32, fp, sizeof(u32)*ARRAY_SIZE(xperms.perms.p));
527 if (rc) {
528 printk(KERN_ERR "SELinux: avtab: truncated entry\n");
529 return rc;
530 }
531 for (i = 0; i < ARRAY_SIZE(xperms.perms.p); i++)
532 xperms.perms.p[i] = le32_to_cpu(buf32[i]);
533 datum.u.xperms = &xperms;
534 } else {
535 rc = next_entry(buf32, fp, sizeof(u32));
536 if (rc) {
537 printk(KERN_ERR "SELinux: avtab: truncated entry\n");
538 return rc;
539 }
540 datum.u.data = le32_to_cpu(*buf32);
483 } 541 }
484 datum.data = le32_to_cpu(*buf32);
485 if ((key.specified & AVTAB_TYPE) && 542 if ((key.specified & AVTAB_TYPE) &&
486 !policydb_type_isvalid(pol, datum.data)) { 543 !policydb_type_isvalid(pol, datum.u.data)) {
487 printk(KERN_ERR "SELinux: avtab: invalid type\n"); 544 printk(KERN_ERR "SELinux: avtab: invalid type\n");
488 return -EINVAL; 545 return -EINVAL;
489 } 546 }
@@ -543,8 +600,9 @@ bad:
543int avtab_write_item(struct policydb *p, struct avtab_node *cur, void *fp) 600int avtab_write_item(struct policydb *p, struct avtab_node *cur, void *fp)
544{ 601{
545 __le16 buf16[4]; 602 __le16 buf16[4];
546 __le32 buf32[1]; 603 __le32 buf32[ARRAY_SIZE(cur->datum.u.xperms->perms.p)];
547 int rc; 604 int rc;
605 unsigned int i;
548 606
549 buf16[0] = cpu_to_le16(cur->key.source_type); 607 buf16[0] = cpu_to_le16(cur->key.source_type);
550 buf16[1] = cpu_to_le16(cur->key.target_type); 608 buf16[1] = cpu_to_le16(cur->key.target_type);
@@ -553,8 +611,22 @@ int avtab_write_item(struct policydb *p, struct avtab_node *cur, void *fp)
553 rc = put_entry(buf16, sizeof(u16), 4, fp); 611 rc = put_entry(buf16, sizeof(u16), 4, fp);
554 if (rc) 612 if (rc)
555 return rc; 613 return rc;
556 buf32[0] = cpu_to_le32(cur->datum.data); 614
557 rc = put_entry(buf32, sizeof(u32), 1, fp); 615 if (cur->key.specified & AVTAB_XPERMS) {
616 rc = put_entry(&cur->datum.u.xperms->specified, sizeof(u8), 1, fp);
617 if (rc)
618 return rc;
619 rc = put_entry(&cur->datum.u.xperms->driver, sizeof(u8), 1, fp);
620 if (rc)
621 return rc;
622 for (i = 0; i < ARRAY_SIZE(cur->datum.u.xperms->perms.p); i++)
623 buf32[i] = cpu_to_le32(cur->datum.u.xperms->perms.p[i]);
624 rc = put_entry(buf32, sizeof(u32),
625 ARRAY_SIZE(cur->datum.u.xperms->perms.p), fp);
626 } else {
627 buf32[0] = cpu_to_le32(cur->datum.u.data);
628 rc = put_entry(buf32, sizeof(u32), 1, fp);
629 }
558 if (rc) 630 if (rc)
559 return rc; 631 return rc;
560 return 0; 632 return 0;
@@ -588,9 +660,13 @@ void avtab_cache_init(void)
588 avtab_node_cachep = kmem_cache_create("avtab_node", 660 avtab_node_cachep = kmem_cache_create("avtab_node",
589 sizeof(struct avtab_node), 661 sizeof(struct avtab_node),
590 0, SLAB_PANIC, NULL); 662 0, SLAB_PANIC, NULL);
663 avtab_xperms_cachep = kmem_cache_create("avtab_extended_perms",
664 sizeof(struct avtab_extended_perms),
665 0, SLAB_PANIC, NULL);
591} 666}
592 667
593void avtab_cache_destroy(void) 668void avtab_cache_destroy(void)
594{ 669{
595 kmem_cache_destroy(avtab_node_cachep); 670 kmem_cache_destroy(avtab_node_cachep);
671 kmem_cache_destroy(avtab_xperms_cachep);
596} 672}
diff --git a/security/selinux/ss/avtab.h b/security/selinux/ss/avtab.h
index adb451cd44f9..d946c9dc3c9c 100644
--- a/security/selinux/ss/avtab.h
+++ b/security/selinux/ss/avtab.h
@@ -23,6 +23,7 @@
23#ifndef _SS_AVTAB_H_ 23#ifndef _SS_AVTAB_H_
24#define _SS_AVTAB_H_ 24#define _SS_AVTAB_H_
25 25
26#include "security.h"
26#include <linux/flex_array.h> 27#include <linux/flex_array.h>
27 28
28struct avtab_key { 29struct avtab_key {
@@ -37,13 +38,43 @@ struct avtab_key {
37#define AVTAB_MEMBER 0x0020 38#define AVTAB_MEMBER 0x0020
38#define AVTAB_CHANGE 0x0040 39#define AVTAB_CHANGE 0x0040
39#define AVTAB_TYPE (AVTAB_TRANSITION | AVTAB_MEMBER | AVTAB_CHANGE) 40#define AVTAB_TYPE (AVTAB_TRANSITION | AVTAB_MEMBER | AVTAB_CHANGE)
41/* extended permissions */
42#define AVTAB_XPERMS_ALLOWED 0x0100
43#define AVTAB_XPERMS_AUDITALLOW 0x0200
44#define AVTAB_XPERMS_DONTAUDIT 0x0400
45#define AVTAB_XPERMS (AVTAB_XPERMS_ALLOWED | \
46 AVTAB_XPERMS_AUDITALLOW | \
47 AVTAB_XPERMS_DONTAUDIT)
40#define AVTAB_ENABLED_OLD 0x80000000 /* reserved for used in cond_avtab */ 48#define AVTAB_ENABLED_OLD 0x80000000 /* reserved for used in cond_avtab */
41#define AVTAB_ENABLED 0x8000 /* reserved for used in cond_avtab */ 49#define AVTAB_ENABLED 0x8000 /* reserved for used in cond_avtab */
42 u16 specified; /* what field is specified */ 50 u16 specified; /* what field is specified */
43}; 51};
44 52
53/*
54 * For operations that require more than the 32 permissions provided by the avc
55 * extended permissions may be used to provide 256 bits of permissions.
56 */
57struct avtab_extended_perms {
58/* These are not flags. All 256 values may be used */
59#define AVTAB_XPERMS_IOCTLFUNCTION 0x01
60#define AVTAB_XPERMS_IOCTLDRIVER 0x02
61 /* extension of the avtab_key specified */
62 u8 specified; /* ioctl, netfilter, ... */
63 /*
64 * if 256 bits is not adequate as is often the case with ioctls, then
65 * multiple extended perms may be used and the driver field
66 * specifies which permissions are included.
67 */
68 u8 driver;
69 /* 256 bits of permissions */
70 struct extended_perms_data perms;
71};
72
45struct avtab_datum { 73struct avtab_datum {
46 u32 data; /* access vector or type value */ 74 union {
75 u32 data; /* access vector or type value */
76 struct avtab_extended_perms *xperms;
77 } u;
47}; 78};
48 79
49struct avtab_node { 80struct avtab_node {
diff --git a/security/selinux/ss/conditional.c b/security/selinux/ss/conditional.c
index 62c6773be0b7..18643bf9894d 100644
--- a/security/selinux/ss/conditional.c
+++ b/security/selinux/ss/conditional.c
@@ -15,6 +15,7 @@
15 15
16#include "security.h" 16#include "security.h"
17#include "conditional.h" 17#include "conditional.h"
18#include "services.h"
18 19
19/* 20/*
20 * cond_evaluate_expr evaluates a conditional expr 21 * cond_evaluate_expr evaluates a conditional expr
@@ -612,21 +613,39 @@ int cond_write_list(struct policydb *p, struct cond_node *list, void *fp)
612 613
613 return 0; 614 return 0;
614} 615}
616
617void cond_compute_xperms(struct avtab *ctab, struct avtab_key *key,
618 struct extended_perms_decision *xpermd)
619{
620 struct avtab_node *node;
621
622 if (!ctab || !key || !xpermd)
623 return;
624
625 for (node = avtab_search_node(ctab, key); node;
626 node = avtab_search_node_next(node, key->specified)) {
627 if (node->key.specified & AVTAB_ENABLED)
628 services_compute_xperms_decision(xpermd, node);
629 }
630 return;
631
632}
615/* Determine whether additional permissions are granted by the conditional 633/* Determine whether additional permissions are granted by the conditional
616 * av table, and if so, add them to the result 634 * av table, and if so, add them to the result
617 */ 635 */
618void cond_compute_av(struct avtab *ctab, struct avtab_key *key, struct av_decision *avd) 636void cond_compute_av(struct avtab *ctab, struct avtab_key *key,
637 struct av_decision *avd, struct extended_perms *xperms)
619{ 638{
620 struct avtab_node *node; 639 struct avtab_node *node;
621 640
622 if (!ctab || !key || !avd) 641 if (!ctab || !key || !avd || !xperms)
623 return; 642 return;
624 643
625 for (node = avtab_search_node(ctab, key); node; 644 for (node = avtab_search_node(ctab, key); node;
626 node = avtab_search_node_next(node, key->specified)) { 645 node = avtab_search_node_next(node, key->specified)) {
627 if ((u16)(AVTAB_ALLOWED|AVTAB_ENABLED) == 646 if ((u16)(AVTAB_ALLOWED|AVTAB_ENABLED) ==
628 (node->key.specified & (AVTAB_ALLOWED|AVTAB_ENABLED))) 647 (node->key.specified & (AVTAB_ALLOWED|AVTAB_ENABLED)))
629 avd->allowed |= node->datum.data; 648 avd->allowed |= node->datum.u.data;
630 if ((u16)(AVTAB_AUDITDENY|AVTAB_ENABLED) == 649 if ((u16)(AVTAB_AUDITDENY|AVTAB_ENABLED) ==
631 (node->key.specified & (AVTAB_AUDITDENY|AVTAB_ENABLED))) 650 (node->key.specified & (AVTAB_AUDITDENY|AVTAB_ENABLED)))
632 /* Since a '0' in an auditdeny mask represents a 651 /* Since a '0' in an auditdeny mask represents a
@@ -634,10 +653,13 @@ void cond_compute_av(struct avtab *ctab, struct avtab_key *key, struct av_decisi
634 * the '&' operand to ensure that all '0's in the mask 653 * the '&' operand to ensure that all '0's in the mask
635 * are retained (much unlike the allow and auditallow cases). 654 * are retained (much unlike the allow and auditallow cases).
636 */ 655 */
637 avd->auditdeny &= node->datum.data; 656 avd->auditdeny &= node->datum.u.data;
638 if ((u16)(AVTAB_AUDITALLOW|AVTAB_ENABLED) == 657 if ((u16)(AVTAB_AUDITALLOW|AVTAB_ENABLED) ==
639 (node->key.specified & (AVTAB_AUDITALLOW|AVTAB_ENABLED))) 658 (node->key.specified & (AVTAB_AUDITALLOW|AVTAB_ENABLED)))
640 avd->auditallow |= node->datum.data; 659 avd->auditallow |= node->datum.u.data;
660 if ((node->key.specified & AVTAB_ENABLED) &&
661 (node->key.specified & AVTAB_XPERMS))
662 services_compute_xperms_drivers(xperms, node);
641 } 663 }
642 return; 664 return;
643} 665}
diff --git a/security/selinux/ss/conditional.h b/security/selinux/ss/conditional.h
index 4d1f87466508..ddb43e7e1c75 100644
--- a/security/selinux/ss/conditional.h
+++ b/security/selinux/ss/conditional.h
@@ -73,8 +73,10 @@ int cond_read_list(struct policydb *p, void *fp);
73int cond_write_bool(void *key, void *datum, void *ptr); 73int cond_write_bool(void *key, void *datum, void *ptr);
74int cond_write_list(struct policydb *p, struct cond_node *list, void *fp); 74int cond_write_list(struct policydb *p, struct cond_node *list, void *fp);
75 75
76void cond_compute_av(struct avtab *ctab, struct avtab_key *key, struct av_decision *avd); 76void cond_compute_av(struct avtab *ctab, struct avtab_key *key,
77 77 struct av_decision *avd, struct extended_perms *xperms);
78void cond_compute_xperms(struct avtab *ctab, struct avtab_key *key,
79 struct extended_perms_decision *xpermd);
78int evaluate_cond_node(struct policydb *p, struct cond_node *node); 80int evaluate_cond_node(struct policydb *p, struct cond_node *node);
79 81
80#endif /* _CONDITIONAL_H_ */ 82#endif /* _CONDITIONAL_H_ */
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index 74aa224267c1..992a31530825 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -148,6 +148,11 @@ static struct policydb_compat_info policydb_compat[] = {
148 .sym_num = SYM_NUM, 148 .sym_num = SYM_NUM,
149 .ocon_num = OCON_NUM, 149 .ocon_num = OCON_NUM,
150 }, 150 },
151 {
152 .version = POLICYDB_VERSION_XPERMS_IOCTL,
153 .sym_num = SYM_NUM,
154 .ocon_num = OCON_NUM,
155 },
151}; 156};
152 157
153static struct policydb_compat_info *policydb_lookup_compat(int version) 158static struct policydb_compat_info *policydb_lookup_compat(int version)
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 9e2d82070915..b7df12ba61d8 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -93,9 +93,10 @@ static int context_struct_to_string(struct context *context, char **scontext,
93 u32 *scontext_len); 93 u32 *scontext_len);
94 94
95static void context_struct_compute_av(struct context *scontext, 95static void context_struct_compute_av(struct context *scontext,
96 struct context *tcontext, 96 struct context *tcontext,
97 u16 tclass, 97 u16 tclass,
98 struct av_decision *avd); 98 struct av_decision *avd,
99 struct extended_perms *xperms);
99 100
100struct selinux_mapping { 101struct selinux_mapping {
101 u16 value; /* policy value */ 102 u16 value; /* policy value */
@@ -565,7 +566,8 @@ static void type_attribute_bounds_av(struct context *scontext,
565 context_struct_compute_av(&lo_scontext, 566 context_struct_compute_av(&lo_scontext,
566 tcontext, 567 tcontext,
567 tclass, 568 tclass,
568 &lo_avd); 569 &lo_avd,
570 NULL);
569 if ((lo_avd.allowed & avd->allowed) == avd->allowed) 571 if ((lo_avd.allowed & avd->allowed) == avd->allowed)
570 return; /* no masked permission */ 572 return; /* no masked permission */
571 masked = ~lo_avd.allowed & avd->allowed; 573 masked = ~lo_avd.allowed & avd->allowed;
@@ -580,7 +582,8 @@ static void type_attribute_bounds_av(struct context *scontext,
580 context_struct_compute_av(scontext, 582 context_struct_compute_av(scontext,
581 &lo_tcontext, 583 &lo_tcontext,
582 tclass, 584 tclass,
583 &lo_avd); 585 &lo_avd,
586 NULL);
584 if ((lo_avd.allowed & avd->allowed) == avd->allowed) 587 if ((lo_avd.allowed & avd->allowed) == avd->allowed)
585 return; /* no masked permission */ 588 return; /* no masked permission */
586 masked = ~lo_avd.allowed & avd->allowed; 589 masked = ~lo_avd.allowed & avd->allowed;
@@ -596,7 +599,8 @@ static void type_attribute_bounds_av(struct context *scontext,
596 context_struct_compute_av(&lo_scontext, 599 context_struct_compute_av(&lo_scontext,
597 &lo_tcontext, 600 &lo_tcontext,
598 tclass, 601 tclass,
599 &lo_avd); 602 &lo_avd,
603 NULL);
600 if ((lo_avd.allowed & avd->allowed) == avd->allowed) 604 if ((lo_avd.allowed & avd->allowed) == avd->allowed)
601 return; /* no masked permission */ 605 return; /* no masked permission */
602 masked = ~lo_avd.allowed & avd->allowed; 606 masked = ~lo_avd.allowed & avd->allowed;
@@ -613,13 +617,39 @@ static void type_attribute_bounds_av(struct context *scontext,
613} 617}
614 618
615/* 619/*
616 * Compute access vectors based on a context structure pair for 620 * flag which drivers have permissions
617 * the permissions in a particular class. 621 * only looking for ioctl based extended permssions
622 */
623void services_compute_xperms_drivers(
624 struct extended_perms *xperms,
625 struct avtab_node *node)
626{
627 unsigned int i;
628
629 if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLDRIVER) {
630 /* if one or more driver has all permissions allowed */
631 for (i = 0; i < ARRAY_SIZE(xperms->drivers.p); i++)
632 xperms->drivers.p[i] |= node->datum.u.xperms->perms.p[i];
633 } else if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLFUNCTION) {
634 /* if allowing permissions within a driver */
635 security_xperm_set(xperms->drivers.p,
636 node->datum.u.xperms->driver);
637 }
638
639 /* If no ioctl commands are allowed, ignore auditallow and auditdeny */
640 if (node->key.specified & AVTAB_XPERMS_ALLOWED)
641 xperms->len = 1;
642}
643
644/*
645 * Compute access vectors and extended permissions based on a context
646 * structure pair for the permissions in a particular class.
618 */ 647 */
619static void context_struct_compute_av(struct context *scontext, 648static void context_struct_compute_av(struct context *scontext,
620 struct context *tcontext, 649 struct context *tcontext,
621 u16 tclass, 650 u16 tclass,
622 struct av_decision *avd) 651 struct av_decision *avd,
652 struct extended_perms *xperms)
623{ 653{
624 struct constraint_node *constraint; 654 struct constraint_node *constraint;
625 struct role_allow *ra; 655 struct role_allow *ra;
@@ -633,6 +663,10 @@ static void context_struct_compute_av(struct context *scontext,
633 avd->allowed = 0; 663 avd->allowed = 0;
634 avd->auditallow = 0; 664 avd->auditallow = 0;
635 avd->auditdeny = 0xffffffff; 665 avd->auditdeny = 0xffffffff;
666 if (xperms) {
667 memset(&xperms->drivers, 0, sizeof(xperms->drivers));
668 xperms->len = 0;
669 }
636 670
637 if (unlikely(!tclass || tclass > policydb.p_classes.nprim)) { 671 if (unlikely(!tclass || tclass > policydb.p_classes.nprim)) {
638 if (printk_ratelimit()) 672 if (printk_ratelimit())
@@ -647,7 +681,7 @@ static void context_struct_compute_av(struct context *scontext,
647 * this permission check, then use it. 681 * this permission check, then use it.
648 */ 682 */
649 avkey.target_class = tclass; 683 avkey.target_class = tclass;
650 avkey.specified = AVTAB_AV; 684 avkey.specified = AVTAB_AV | AVTAB_XPERMS;
651 sattr = flex_array_get(policydb.type_attr_map_array, scontext->type - 1); 685 sattr = flex_array_get(policydb.type_attr_map_array, scontext->type - 1);
652 BUG_ON(!sattr); 686 BUG_ON(!sattr);
653 tattr = flex_array_get(policydb.type_attr_map_array, tcontext->type - 1); 687 tattr = flex_array_get(policydb.type_attr_map_array, tcontext->type - 1);
@@ -660,15 +694,18 @@ static void context_struct_compute_av(struct context *scontext,
660 node; 694 node;
661 node = avtab_search_node_next(node, avkey.specified)) { 695 node = avtab_search_node_next(node, avkey.specified)) {
662 if (node->key.specified == AVTAB_ALLOWED) 696 if (node->key.specified == AVTAB_ALLOWED)
663 avd->allowed |= node->datum.data; 697 avd->allowed |= node->datum.u.data;
664 else if (node->key.specified == AVTAB_AUDITALLOW) 698 else if (node->key.specified == AVTAB_AUDITALLOW)
665 avd->auditallow |= node->datum.data; 699 avd->auditallow |= node->datum.u.data;
666 else if (node->key.specified == AVTAB_AUDITDENY) 700 else if (node->key.specified == AVTAB_AUDITDENY)
667 avd->auditdeny &= node->datum.data; 701 avd->auditdeny &= node->datum.u.data;
702 else if (xperms && (node->key.specified & AVTAB_XPERMS))
703 services_compute_xperms_drivers(xperms, node);
668 } 704 }
669 705
670 /* Check conditional av table for additional permissions */ 706 /* Check conditional av table for additional permissions */
671 cond_compute_av(&policydb.te_cond_avtab, &avkey, avd); 707 cond_compute_av(&policydb.te_cond_avtab, &avkey,
708 avd, xperms);
672 709
673 } 710 }
674 } 711 }
@@ -899,6 +936,139 @@ static void avd_init(struct av_decision *avd)
899 avd->flags = 0; 936 avd->flags = 0;
900} 937}
901 938
939void services_compute_xperms_decision(struct extended_perms_decision *xpermd,
940 struct avtab_node *node)
941{
942 unsigned int i;
943
944 if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLFUNCTION) {
945 if (xpermd->driver != node->datum.u.xperms->driver)
946 return;
947 } else if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLDRIVER) {
948 if (!security_xperm_test(node->datum.u.xperms->perms.p,
949 xpermd->driver))
950 return;
951 } else {
952 BUG();
953 }
954
955 if (node->key.specified == AVTAB_XPERMS_ALLOWED) {
956 xpermd->used |= XPERMS_ALLOWED;
957 if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLDRIVER) {
958 memset(xpermd->allowed->p, 0xff,
959 sizeof(xpermd->allowed->p));
960 }
961 if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLFUNCTION) {
962 for (i = 0; i < ARRAY_SIZE(xpermd->allowed->p); i++)
963 xpermd->allowed->p[i] |=
964 node->datum.u.xperms->perms.p[i];
965 }
966 } else if (node->key.specified == AVTAB_XPERMS_AUDITALLOW) {
967 xpermd->used |= XPERMS_AUDITALLOW;
968 if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLDRIVER) {
969 memset(xpermd->auditallow->p, 0xff,
970 sizeof(xpermd->auditallow->p));
971 }
972 if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLFUNCTION) {
973 for (i = 0; i < ARRAY_SIZE(xpermd->auditallow->p); i++)
974 xpermd->auditallow->p[i] |=
975 node->datum.u.xperms->perms.p[i];
976 }
977 } else if (node->key.specified == AVTAB_XPERMS_DONTAUDIT) {
978 xpermd->used |= XPERMS_DONTAUDIT;
979 if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLDRIVER) {
980 memset(xpermd->dontaudit->p, 0xff,
981 sizeof(xpermd->dontaudit->p));
982 }
983 if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLFUNCTION) {
984 for (i = 0; i < ARRAY_SIZE(xpermd->dontaudit->p); i++)
985 xpermd->dontaudit->p[i] |=
986 node->datum.u.xperms->perms.p[i];
987 }
988 } else {
989 BUG();
990 }
991}
992
993void security_compute_xperms_decision(u32 ssid,
994 u32 tsid,
995 u16 orig_tclass,
996 u8 driver,
997 struct extended_perms_decision *xpermd)
998{
999 u16 tclass;
1000 struct context *scontext, *tcontext;
1001 struct avtab_key avkey;
1002 struct avtab_node *node;
1003 struct ebitmap *sattr, *tattr;
1004 struct ebitmap_node *snode, *tnode;
1005 unsigned int i, j;
1006
1007 xpermd->driver = driver;
1008 xpermd->used = 0;
1009 memset(xpermd->allowed->p, 0, sizeof(xpermd->allowed->p));
1010 memset(xpermd->auditallow->p, 0, sizeof(xpermd->auditallow->p));
1011 memset(xpermd->dontaudit->p, 0, sizeof(xpermd->dontaudit->p));
1012
1013 read_lock(&policy_rwlock);
1014 if (!ss_initialized)
1015 goto allow;
1016
1017 scontext = sidtab_search(&sidtab, ssid);
1018 if (!scontext) {
1019 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
1020 __func__, ssid);
1021 goto out;
1022 }
1023
1024 tcontext = sidtab_search(&sidtab, tsid);
1025 if (!tcontext) {
1026 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
1027 __func__, tsid);
1028 goto out;
1029 }
1030
1031 tclass = unmap_class(orig_tclass);
1032 if (unlikely(orig_tclass && !tclass)) {
1033 if (policydb.allow_unknown)
1034 goto allow;
1035 goto out;
1036 }
1037
1038
1039 if (unlikely(!tclass || tclass > policydb.p_classes.nprim)) {
1040 pr_warn_ratelimited("SELinux: Invalid class %hu\n", tclass);
1041 goto out;
1042 }
1043
1044 avkey.target_class = tclass;
1045 avkey.specified = AVTAB_XPERMS;
1046 sattr = flex_array_get(policydb.type_attr_map_array,
1047 scontext->type - 1);
1048 BUG_ON(!sattr);
1049 tattr = flex_array_get(policydb.type_attr_map_array,
1050 tcontext->type - 1);
1051 BUG_ON(!tattr);
1052 ebitmap_for_each_positive_bit(sattr, snode, i) {
1053 ebitmap_for_each_positive_bit(tattr, tnode, j) {
1054 avkey.source_type = i + 1;
1055 avkey.target_type = j + 1;
1056 for (node = avtab_search_node(&policydb.te_avtab, &avkey);
1057 node;
1058 node = avtab_search_node_next(node, avkey.specified))
1059 services_compute_xperms_decision(xpermd, node);
1060
1061 cond_compute_xperms(&policydb.te_cond_avtab,
1062 &avkey, xpermd);
1063 }
1064 }
1065out:
1066 read_unlock(&policy_rwlock);
1067 return;
1068allow:
1069 memset(xpermd->allowed->p, 0xff, sizeof(xpermd->allowed->p));
1070 goto out;
1071}
902 1072
903/** 1073/**
904 * security_compute_av - Compute access vector decisions. 1074 * security_compute_av - Compute access vector decisions.
@@ -906,6 +1076,7 @@ static void avd_init(struct av_decision *avd)
906 * @tsid: target security identifier 1076 * @tsid: target security identifier
907 * @tclass: target security class 1077 * @tclass: target security class
908 * @avd: access vector decisions 1078 * @avd: access vector decisions
1079 * @xperms: extended permissions
909 * 1080 *
910 * Compute a set of access vector decisions based on the 1081 * Compute a set of access vector decisions based on the
911 * SID pair (@ssid, @tsid) for the permissions in @tclass. 1082 * SID pair (@ssid, @tsid) for the permissions in @tclass.
@@ -913,13 +1084,15 @@ static void avd_init(struct av_decision *avd)
913void security_compute_av(u32 ssid, 1084void security_compute_av(u32 ssid,
914 u32 tsid, 1085 u32 tsid,
915 u16 orig_tclass, 1086 u16 orig_tclass,
916 struct av_decision *avd) 1087 struct av_decision *avd,
1088 struct extended_perms *xperms)
917{ 1089{
918 u16 tclass; 1090 u16 tclass;
919 struct context *scontext = NULL, *tcontext = NULL; 1091 struct context *scontext = NULL, *tcontext = NULL;
920 1092
921 read_lock(&policy_rwlock); 1093 read_lock(&policy_rwlock);
922 avd_init(avd); 1094 avd_init(avd);
1095 xperms->len = 0;
923 if (!ss_initialized) 1096 if (!ss_initialized)
924 goto allow; 1097 goto allow;
925 1098
@@ -947,7 +1120,7 @@ void security_compute_av(u32 ssid,
947 goto allow; 1120 goto allow;
948 goto out; 1121 goto out;
949 } 1122 }
950 context_struct_compute_av(scontext, tcontext, tclass, avd); 1123 context_struct_compute_av(scontext, tcontext, tclass, avd, xperms);
951 map_decision(orig_tclass, avd, policydb.allow_unknown); 1124 map_decision(orig_tclass, avd, policydb.allow_unknown);
952out: 1125out:
953 read_unlock(&policy_rwlock); 1126 read_unlock(&policy_rwlock);
@@ -993,7 +1166,7 @@ void security_compute_av_user(u32 ssid,
993 goto out; 1166 goto out;
994 } 1167 }
995 1168
996 context_struct_compute_av(scontext, tcontext, tclass, avd); 1169 context_struct_compute_av(scontext, tcontext, tclass, avd, NULL);
997 out: 1170 out:
998 read_unlock(&policy_rwlock); 1171 read_unlock(&policy_rwlock);
999 return; 1172 return;
@@ -1515,7 +1688,7 @@ static int security_compute_sid(u32 ssid,
1515 1688
1516 if (avdatum) { 1689 if (avdatum) {
1517 /* Use the type from the type transition/member/change rule. */ 1690 /* Use the type from the type transition/member/change rule. */
1518 newcontext.type = avdatum->data; 1691 newcontext.type = avdatum->u.data;
1519 } 1692 }
1520 1693
1521 /* if we have a objname this is a file trans check so check those rules */ 1694 /* if we have a objname this is a file trans check so check those rules */
diff --git a/security/selinux/ss/services.h b/security/selinux/ss/services.h
index e8d907e903cd..6abcd8729ec3 100644
--- a/security/selinux/ss/services.h
+++ b/security/selinux/ss/services.h
@@ -11,5 +11,11 @@
11 11
12extern struct policydb policydb; 12extern struct policydb policydb;
13 13
14void services_compute_xperms_drivers(struct extended_perms *xperms,
15 struct avtab_node *node);
16
17void services_compute_xperms_decision(struct extended_perms_decision *xpermd,
18 struct avtab_node *node);
19
14#endif /* _SS_SERVICES_H_ */ 20#endif /* _SS_SERVICES_H_ */
15 21
diff --git a/security/smack/smack.h b/security/smack/smack.h
index 244e035e5a99..fff0c612bbb7 100644
--- a/security/smack/smack.h
+++ b/security/smack/smack.h
@@ -17,12 +17,27 @@
17#include <linux/spinlock.h> 17#include <linux/spinlock.h>
18#include <linux/lsm_hooks.h> 18#include <linux/lsm_hooks.h>
19#include <linux/in.h> 19#include <linux/in.h>
20#if IS_ENABLED(CONFIG_IPV6)
21#include <linux/in6.h>
22#endif /* CONFIG_IPV6 */
20#include <net/netlabel.h> 23#include <net/netlabel.h>
21#include <linux/list.h> 24#include <linux/list.h>
22#include <linux/rculist.h> 25#include <linux/rculist.h>
23#include <linux/lsm_audit.h> 26#include <linux/lsm_audit.h>
24 27
25/* 28/*
29 * Use IPv6 port labeling if IPv6 is enabled and secmarks
30 * are not being used.
31 */
32#if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER)
33#define SMACK_IPV6_PORT_LABELING 1
34#endif
35
36#if IS_ENABLED(CONFIG_IPV6) && defined(CONFIG_SECURITY_SMACK_NETFILTER)
37#define SMACK_IPV6_SECMARK_LABELING 1
38#endif
39
40/*
26 * Smack labels were limited to 23 characters for a long time. 41 * Smack labels were limited to 23 characters for a long time.
27 */ 42 */
28#define SMK_LABELLEN 24 43#define SMK_LABELLEN 24
@@ -118,15 +133,30 @@ struct smack_rule {
118}; 133};
119 134
120/* 135/*
121 * An entry in the table identifying hosts. 136 * An entry in the table identifying IPv4 hosts.
122 */ 137 */
123struct smk_netlbladdr { 138struct smk_net4addr {
124 struct list_head list; 139 struct list_head list;
125 struct sockaddr_in smk_host; /* network address */ 140 struct in_addr smk_host; /* network address */
126 struct in_addr smk_mask; /* network mask */ 141 struct in_addr smk_mask; /* network mask */
142 int smk_masks; /* mask size */
143 struct smack_known *smk_label; /* label */
144};
145
146#if IS_ENABLED(CONFIG_IPV6)
147/*
148 * An entry in the table identifying IPv6 hosts.
149 */
150struct smk_net6addr {
151 struct list_head list;
152 struct in6_addr smk_host; /* network address */
153 struct in6_addr smk_mask; /* network mask */
154 int smk_masks; /* mask size */
127 struct smack_known *smk_label; /* label */ 155 struct smack_known *smk_label; /* label */
128}; 156};
157#endif /* CONFIG_IPV6 */
129 158
159#ifdef SMACK_IPV6_PORT_LABELING
130/* 160/*
131 * An entry in the table identifying ports. 161 * An entry in the table identifying ports.
132 */ 162 */
@@ -137,12 +167,31 @@ struct smk_port_label {
137 struct smack_known *smk_in; /* inbound label */ 167 struct smack_known *smk_in; /* inbound label */
138 struct smack_known *smk_out; /* outgoing label */ 168 struct smack_known *smk_out; /* outgoing label */
139}; 169};
170#endif /* SMACK_IPV6_PORT_LABELING */
140 171
141struct smack_onlycap { 172struct smack_onlycap {
142 struct list_head list; 173 struct list_head list;
143 struct smack_known *smk_label; 174 struct smack_known *smk_label;
144}; 175};
145 176
177/* Super block security struct flags for mount options */
178#define FSDEFAULT_MNT 0x01
179#define FSFLOOR_MNT 0x02
180#define FSHAT_MNT 0x04
181#define FSROOT_MNT 0x08
182#define FSTRANS_MNT 0x10
183
184#define NUM_SMK_MNT_OPTS 5
185
186enum {
187 Opt_error = -1,
188 Opt_fsdefault = 1,
189 Opt_fsfloor = 2,
190 Opt_fshat = 3,
191 Opt_fsroot = 4,
192 Opt_fstransmute = 5,
193};
194
146/* 195/*
147 * Mount options 196 * Mount options
148 */ 197 */
@@ -152,6 +201,7 @@ struct smack_onlycap {
152#define SMK_FSROOT "smackfsroot=" 201#define SMK_FSROOT "smackfsroot="
153#define SMK_FSTRANS "smackfstransmute=" 202#define SMK_FSTRANS "smackfstransmute="
154 203
204#define SMACK_DELETE_OPTION "-DELETE"
155#define SMACK_CIPSO_OPTION "-CIPSO" 205#define SMACK_CIPSO_OPTION "-CIPSO"
156 206
157/* 207/*
@@ -234,10 +284,6 @@ struct smk_audit_info {
234 struct smack_audit_data sad; 284 struct smack_audit_data sad;
235#endif 285#endif
236}; 286};
237/*
238 * These functions are in smack_lsm.c
239 */
240struct inode_smack *new_inode_smack(struct smack_known *);
241 287
242/* 288/*
243 * These functions are in smack_access.c 289 * These functions are in smack_access.c
@@ -267,7 +313,6 @@ extern struct smack_known *smack_syslog_label;
267#ifdef CONFIG_SECURITY_SMACK_BRINGUP 313#ifdef CONFIG_SECURITY_SMACK_BRINGUP
268extern struct smack_known *smack_unconfined; 314extern struct smack_known *smack_unconfined;
269#endif 315#endif
270extern struct smack_known smack_cipso_option;
271extern int smack_ptrace_rule; 316extern int smack_ptrace_rule;
272 317
273extern struct smack_known smack_known_floor; 318extern struct smack_known smack_known_floor;
@@ -279,7 +324,10 @@ extern struct smack_known smack_known_web;
279 324
280extern struct mutex smack_known_lock; 325extern struct mutex smack_known_lock;
281extern struct list_head smack_known_list; 326extern struct list_head smack_known_list;
282extern struct list_head smk_netlbladdr_list; 327extern struct list_head smk_net4addr_list;
328#if IS_ENABLED(CONFIG_IPV6)
329extern struct list_head smk_net6addr_list;
330#endif /* CONFIG_IPV6 */
283 331
284extern struct mutex smack_onlycap_lock; 332extern struct mutex smack_onlycap_lock;
285extern struct list_head smack_onlycap_list; 333extern struct list_head smack_onlycap_list;
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c
index 00f6b38bffbd..bc1053fb5d1d 100644
--- a/security/smack/smack_access.c
+++ b/security/smack/smack_access.c
@@ -639,6 +639,12 @@ int smack_privileged(int cap)
639 struct smack_known *skp = smk_of_current(); 639 struct smack_known *skp = smk_of_current();
640 struct smack_onlycap *sop; 640 struct smack_onlycap *sop;
641 641
642 /*
643 * All kernel tasks are privileged
644 */
645 if (unlikely(current->flags & PF_KTHREAD))
646 return 1;
647
642 if (!capable(cap)) 648 if (!capable(cap))
643 return 0; 649 return 0;
644 650
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index a143328f75eb..996c88956438 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -41,6 +41,7 @@
41#include <linux/msg.h> 41#include <linux/msg.h>
42#include <linux/shm.h> 42#include <linux/shm.h>
43#include <linux/binfmts.h> 43#include <linux/binfmts.h>
44#include <linux/parser.h>
44#include "smack.h" 45#include "smack.h"
45 46
46#define TRANS_TRUE "TRUE" 47#define TRANS_TRUE "TRUE"
@@ -50,12 +51,21 @@
50#define SMK_RECEIVING 1 51#define SMK_RECEIVING 1
51#define SMK_SENDING 2 52#define SMK_SENDING 2
52 53
53#if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) 54#ifdef SMACK_IPV6_PORT_LABELING
54LIST_HEAD(smk_ipv6_port_list); 55LIST_HEAD(smk_ipv6_port_list);
55#endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ 56#endif
56static struct kmem_cache *smack_inode_cache; 57static struct kmem_cache *smack_inode_cache;
57int smack_enabled; 58int smack_enabled;
58 59
60static const match_table_t smk_mount_tokens = {
61 {Opt_fsdefault, SMK_FSDEFAULT "%s"},
62 {Opt_fsfloor, SMK_FSFLOOR "%s"},
63 {Opt_fshat, SMK_FSHAT "%s"},
64 {Opt_fsroot, SMK_FSROOT "%s"},
65 {Opt_fstransmute, SMK_FSTRANS "%s"},
66 {Opt_error, NULL},
67};
68
59#ifdef CONFIG_SECURITY_SMACK_BRINGUP 69#ifdef CONFIG_SECURITY_SMACK_BRINGUP
60static char *smk_bu_mess[] = { 70static char *smk_bu_mess[] = {
61 "Bringup Error", /* Unused */ 71 "Bringup Error", /* Unused */
@@ -281,7 +291,7 @@ static struct smack_known *smk_fetch(const char *name, struct inode *ip,
281 * 291 *
282 * Returns the new blob or NULL if there's no memory available 292 * Returns the new blob or NULL if there's no memory available
283 */ 293 */
284struct inode_smack *new_inode_smack(struct smack_known *skp) 294static struct inode_smack *new_inode_smack(struct smack_known *skp)
285{ 295{
286 struct inode_smack *isp; 296 struct inode_smack *isp;
287 297
@@ -577,76 +587,197 @@ static int smack_sb_copy_data(char *orig, char *smackopts)
577} 587}
578 588
579/** 589/**
580 * smack_sb_kern_mount - Smack specific mount processing 590 * smack_parse_opts_str - parse Smack specific mount options
591 * @options: mount options string
592 * @opts: where to store converted mount opts
593 *
594 * Returns 0 on success or -ENOMEM on error.
595 *
596 * converts Smack specific mount options to generic security option format
597 */
598static int smack_parse_opts_str(char *options,
599 struct security_mnt_opts *opts)
600{
601 char *p;
602 char *fsdefault = NULL;
603 char *fsfloor = NULL;
604 char *fshat = NULL;
605 char *fsroot = NULL;
606 char *fstransmute = NULL;
607 int rc = -ENOMEM;
608 int num_mnt_opts = 0;
609 int token;
610
611 opts->num_mnt_opts = 0;
612
613 if (!options)
614 return 0;
615
616 while ((p = strsep(&options, ",")) != NULL) {
617 substring_t args[MAX_OPT_ARGS];
618
619 if (!*p)
620 continue;
621
622 token = match_token(p, smk_mount_tokens, args);
623
624 switch (token) {
625 case Opt_fsdefault:
626 if (fsdefault)
627 goto out_opt_err;
628 fsdefault = match_strdup(&args[0]);
629 if (!fsdefault)
630 goto out_err;
631 break;
632 case Opt_fsfloor:
633 if (fsfloor)
634 goto out_opt_err;
635 fsfloor = match_strdup(&args[0]);
636 if (!fsfloor)
637 goto out_err;
638 break;
639 case Opt_fshat:
640 if (fshat)
641 goto out_opt_err;
642 fshat = match_strdup(&args[0]);
643 if (!fshat)
644 goto out_err;
645 break;
646 case Opt_fsroot:
647 if (fsroot)
648 goto out_opt_err;
649 fsroot = match_strdup(&args[0]);
650 if (!fsroot)
651 goto out_err;
652 break;
653 case Opt_fstransmute:
654 if (fstransmute)
655 goto out_opt_err;
656 fstransmute = match_strdup(&args[0]);
657 if (!fstransmute)
658 goto out_err;
659 break;
660 default:
661 rc = -EINVAL;
662 pr_warn("Smack: unknown mount option\n");
663 goto out_err;
664 }
665 }
666
667 opts->mnt_opts = kcalloc(NUM_SMK_MNT_OPTS, sizeof(char *), GFP_ATOMIC);
668 if (!opts->mnt_opts)
669 goto out_err;
670
671 opts->mnt_opts_flags = kcalloc(NUM_SMK_MNT_OPTS, sizeof(int),
672 GFP_ATOMIC);
673 if (!opts->mnt_opts_flags) {
674 kfree(opts->mnt_opts);
675 goto out_err;
676 }
677
678 if (fsdefault) {
679 opts->mnt_opts[num_mnt_opts] = fsdefault;
680 opts->mnt_opts_flags[num_mnt_opts++] = FSDEFAULT_MNT;
681 }
682 if (fsfloor) {
683 opts->mnt_opts[num_mnt_opts] = fsfloor;
684 opts->mnt_opts_flags[num_mnt_opts++] = FSFLOOR_MNT;
685 }
686 if (fshat) {
687 opts->mnt_opts[num_mnt_opts] = fshat;
688 opts->mnt_opts_flags[num_mnt_opts++] = FSHAT_MNT;
689 }
690 if (fsroot) {
691 opts->mnt_opts[num_mnt_opts] = fsroot;
692 opts->mnt_opts_flags[num_mnt_opts++] = FSROOT_MNT;
693 }
694 if (fstransmute) {
695 opts->mnt_opts[num_mnt_opts] = fstransmute;
696 opts->mnt_opts_flags[num_mnt_opts++] = FSTRANS_MNT;
697 }
698
699 opts->num_mnt_opts = num_mnt_opts;
700 return 0;
701
702out_opt_err:
703 rc = -EINVAL;
704 pr_warn("Smack: duplicate mount options\n");
705
706out_err:
707 kfree(fsdefault);
708 kfree(fsfloor);
709 kfree(fshat);
710 kfree(fsroot);
711 kfree(fstransmute);
712 return rc;
713}
714
715/**
716 * smack_set_mnt_opts - set Smack specific mount options
581 * @sb: the file system superblock 717 * @sb: the file system superblock
582 * @flags: the mount flags 718 * @opts: Smack mount options
583 * @data: the smack mount options 719 * @kern_flags: mount option from kernel space or user space
720 * @set_kern_flags: where to store converted mount opts
584 * 721 *
585 * Returns 0 on success, an error code on failure 722 * Returns 0 on success, an error code on failure
723 *
724 * Allow filesystems with binary mount data to explicitly set Smack mount
725 * labels.
586 */ 726 */
587static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data) 727static int smack_set_mnt_opts(struct super_block *sb,
728 struct security_mnt_opts *opts,
729 unsigned long kern_flags,
730 unsigned long *set_kern_flags)
588{ 731{
589 struct dentry *root = sb->s_root; 732 struct dentry *root = sb->s_root;
590 struct inode *inode = d_backing_inode(root); 733 struct inode *inode = d_backing_inode(root);
591 struct superblock_smack *sp = sb->s_security; 734 struct superblock_smack *sp = sb->s_security;
592 struct inode_smack *isp; 735 struct inode_smack *isp;
593 struct smack_known *skp; 736 struct smack_known *skp;
594 char *op; 737 int i;
595 char *commap; 738 int num_opts = opts->num_mnt_opts;
596 int transmute = 0; 739 int transmute = 0;
597 int specified = 0;
598 740
599 if (sp->smk_initialized) 741 if (sp->smk_initialized)
600 return 0; 742 return 0;
601 743
602 sp->smk_initialized = 1; 744 sp->smk_initialized = 1;
603 745
604 for (op = data; op != NULL; op = commap) { 746 for (i = 0; i < num_opts; i++) {
605 commap = strchr(op, ','); 747 switch (opts->mnt_opts_flags[i]) {
606 if (commap != NULL) 748 case FSDEFAULT_MNT:
607 *commap++ = '\0'; 749 skp = smk_import_entry(opts->mnt_opts[i], 0);
608
609 if (strncmp(op, SMK_FSHAT, strlen(SMK_FSHAT)) == 0) {
610 op += strlen(SMK_FSHAT);
611 skp = smk_import_entry(op, 0);
612 if (IS_ERR(skp)) 750 if (IS_ERR(skp))
613 return PTR_ERR(skp); 751 return PTR_ERR(skp);
614 sp->smk_hat = skp; 752 sp->smk_default = skp;
615 specified = 1; 753 break;
616 754 case FSFLOOR_MNT:
617 } else if (strncmp(op, SMK_FSFLOOR, strlen(SMK_FSFLOOR)) == 0) { 755 skp = smk_import_entry(opts->mnt_opts[i], 0);
618 op += strlen(SMK_FSFLOOR);
619 skp = smk_import_entry(op, 0);
620 if (IS_ERR(skp)) 756 if (IS_ERR(skp))
621 return PTR_ERR(skp); 757 return PTR_ERR(skp);
622 sp->smk_floor = skp; 758 sp->smk_floor = skp;
623 specified = 1; 759 break;
624 760 case FSHAT_MNT:
625 } else if (strncmp(op, SMK_FSDEFAULT, 761 skp = smk_import_entry(opts->mnt_opts[i], 0);
626 strlen(SMK_FSDEFAULT)) == 0) {
627 op += strlen(SMK_FSDEFAULT);
628 skp = smk_import_entry(op, 0);
629 if (IS_ERR(skp)) 762 if (IS_ERR(skp))
630 return PTR_ERR(skp); 763 return PTR_ERR(skp);
631 sp->smk_default = skp; 764 sp->smk_hat = skp;
632 specified = 1; 765 break;
633 766 case FSROOT_MNT:
634 } else if (strncmp(op, SMK_FSROOT, strlen(SMK_FSROOT)) == 0) { 767 skp = smk_import_entry(opts->mnt_opts[i], 0);
635 op += strlen(SMK_FSROOT);
636 skp = smk_import_entry(op, 0);
637 if (IS_ERR(skp)) 768 if (IS_ERR(skp))
638 return PTR_ERR(skp); 769 return PTR_ERR(skp);
639 sp->smk_root = skp; 770 sp->smk_root = skp;
640 specified = 1; 771 break;
641 772 case FSTRANS_MNT:
642 } else if (strncmp(op, SMK_FSTRANS, strlen(SMK_FSTRANS)) == 0) { 773 skp = smk_import_entry(opts->mnt_opts[i], 0);
643 op += strlen(SMK_FSTRANS);
644 skp = smk_import_entry(op, 0);
645 if (IS_ERR(skp)) 774 if (IS_ERR(skp))
646 return PTR_ERR(skp); 775 return PTR_ERR(skp);
647 sp->smk_root = skp; 776 sp->smk_root = skp;
648 transmute = 1; 777 transmute = 1;
649 specified = 1; 778 break;
779 default:
780 break;
650 } 781 }
651 } 782 }
652 783
@@ -654,7 +785,7 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data)
654 /* 785 /*
655 * Unprivileged mounts don't get to specify Smack values. 786 * Unprivileged mounts don't get to specify Smack values.
656 */ 787 */
657 if (specified) 788 if (num_opts)
658 return -EPERM; 789 return -EPERM;
659 /* 790 /*
660 * Unprivileged mounts get root and default from the caller. 791 * Unprivileged mounts get root and default from the caller.
@@ -663,6 +794,7 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data)
663 sp->smk_root = skp; 794 sp->smk_root = skp;
664 sp->smk_default = skp; 795 sp->smk_default = skp;
665 } 796 }
797
666 /* 798 /*
667 * Initialize the root inode. 799 * Initialize the root inode.
668 */ 800 */
@@ -682,6 +814,37 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data)
682} 814}
683 815
684/** 816/**
817 * smack_sb_kern_mount - Smack specific mount processing
818 * @sb: the file system superblock
819 * @flags: the mount flags
820 * @data: the smack mount options
821 *
822 * Returns 0 on success, an error code on failure
823 */
824static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data)
825{
826 int rc = 0;
827 char *options = data;
828 struct security_mnt_opts opts;
829
830 security_init_mnt_opts(&opts);
831
832 if (!options)
833 goto out;
834
835 rc = smack_parse_opts_str(options, &opts);
836 if (rc)
837 goto out_err;
838
839out:
840 rc = smack_set_mnt_opts(sb, &opts, 0, NULL);
841
842out_err:
843 security_free_mnt_opts(&opts);
844 return rc;
845}
846
847/**
685 * smack_sb_statfs - Smack check on statfs 848 * smack_sb_statfs - Smack check on statfs
686 * @dentry: identifies the file system in question 849 * @dentry: identifies the file system in question
687 * 850 *
@@ -2113,7 +2276,7 @@ static void smack_sk_free_security(struct sock *sk)
2113} 2276}
2114 2277
2115/** 2278/**
2116* smack_host_label - check host based restrictions 2279* smack_ipv4host_label - check host based restrictions
2117* @sip: the object end 2280* @sip: the object end
2118* 2281*
2119* looks for host based access restrictions 2282* looks for host based access restrictions
@@ -2124,30 +2287,96 @@ static void smack_sk_free_security(struct sock *sk)
2124* 2287*
2125* Returns the label of the far end or NULL if it's not special. 2288* Returns the label of the far end or NULL if it's not special.
2126*/ 2289*/
2127static struct smack_known *smack_host_label(struct sockaddr_in *sip) 2290static struct smack_known *smack_ipv4host_label(struct sockaddr_in *sip)
2128{ 2291{
2129 struct smk_netlbladdr *snp; 2292 struct smk_net4addr *snp;
2130 struct in_addr *siap = &sip->sin_addr; 2293 struct in_addr *siap = &sip->sin_addr;
2131 2294
2132 if (siap->s_addr == 0) 2295 if (siap->s_addr == 0)
2133 return NULL; 2296 return NULL;
2134 2297
2135 list_for_each_entry_rcu(snp, &smk_netlbladdr_list, list) 2298 list_for_each_entry_rcu(snp, &smk_net4addr_list, list)
2299 /*
2300 * we break after finding the first match because
2301 * the list is sorted from longest to shortest mask
2302 * so we have found the most specific match
2303 */
2304 if (snp->smk_host.s_addr ==
2305 (siap->s_addr & snp->smk_mask.s_addr))
2306 return snp->smk_label;
2307
2308 return NULL;
2309}
2310
2311#if IS_ENABLED(CONFIG_IPV6)
2312/*
2313 * smk_ipv6_localhost - Check for local ipv6 host address
2314 * @sip: the address
2315 *
2316 * Returns boolean true if this is the localhost address
2317 */
2318static bool smk_ipv6_localhost(struct sockaddr_in6 *sip)
2319{
2320 __be16 *be16p = (__be16 *)&sip->sin6_addr;
2321 __be32 *be32p = (__be32 *)&sip->sin6_addr;
2322
2323 if (be32p[0] == 0 && be32p[1] == 0 && be32p[2] == 0 && be16p[6] == 0 &&
2324 ntohs(be16p[7]) == 1)
2325 return true;
2326 return false;
2327}
2328
2329/**
2330* smack_ipv6host_label - check host based restrictions
2331* @sip: the object end
2332*
2333* looks for host based access restrictions
2334*
2335* This version will only be appropriate for really small sets of single label
2336* hosts. The caller is responsible for ensuring that the RCU read lock is
2337* taken before calling this function.
2338*
2339* Returns the label of the far end or NULL if it's not special.
2340*/
2341static struct smack_known *smack_ipv6host_label(struct sockaddr_in6 *sip)
2342{
2343 struct smk_net6addr *snp;
2344 struct in6_addr *sap = &sip->sin6_addr;
2345 int i;
2346 int found = 0;
2347
2348 /*
2349 * It's local. Don't look for a host label.
2350 */
2351 if (smk_ipv6_localhost(sip))
2352 return NULL;
2353
2354 list_for_each_entry_rcu(snp, &smk_net6addr_list, list) {
2136 /* 2355 /*
2137 * we break after finding the first match because 2356 * we break after finding the first match because
2138 * the list is sorted from longest to shortest mask 2357 * the list is sorted from longest to shortest mask
2139 * so we have found the most specific match 2358 * so we have found the most specific match
2140 */ 2359 */
2141 if ((&snp->smk_host.sin_addr)->s_addr == 2360 for (found = 1, i = 0; i < 8; i++) {
2142 (siap->s_addr & (&snp->smk_mask)->s_addr)) { 2361 /*
2143 /* we have found the special CIPSO option */ 2362 * If the label is NULL the entry has
2144 if (snp->smk_label == &smack_cipso_option) 2363 * been renounced. Ignore it.
2145 return NULL; 2364 */
2146 return snp->smk_label; 2365 if (snp->smk_label == NULL)
2366 continue;
2367 if ((sap->s6_addr16[i] & snp->smk_mask.s6_addr16[i]) !=
2368 snp->smk_host.s6_addr16[i]) {
2369 found = 0;
2370 break;
2371 }
2147 } 2372 }
2373 if (found)
2374 return snp->smk_label;
2375 }
2148 2376
2149 return NULL; 2377 return NULL;
2150} 2378}
2379#endif /* CONFIG_IPV6 */
2151 2380
2152/** 2381/**
2153 * smack_netlabel - Set the secattr on a socket 2382 * smack_netlabel - Set the secattr on a socket
@@ -2211,7 +2440,7 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap)
2211 struct smk_audit_info ad; 2440 struct smk_audit_info ad;
2212 2441
2213 rcu_read_lock(); 2442 rcu_read_lock();
2214 hkp = smack_host_label(sap); 2443 hkp = smack_ipv4host_label(sap);
2215 if (hkp != NULL) { 2444 if (hkp != NULL) {
2216#ifdef CONFIG_AUDIT 2445#ifdef CONFIG_AUDIT
2217 struct lsm_network_audit net; 2446 struct lsm_network_audit net;
@@ -2236,7 +2465,42 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap)
2236 return smack_netlabel(sk, sk_lbl); 2465 return smack_netlabel(sk, sk_lbl);
2237} 2466}
2238 2467
2239#if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) 2468#if IS_ENABLED(CONFIG_IPV6)
2469/**
2470 * smk_ipv6_check - check Smack access
2471 * @subject: subject Smack label
2472 * @object: object Smack label
2473 * @address: address
2474 * @act: the action being taken
2475 *
2476 * Check an IPv6 access
2477 */
2478static int smk_ipv6_check(struct smack_known *subject,
2479 struct smack_known *object,
2480 struct sockaddr_in6 *address, int act)
2481{
2482#ifdef CONFIG_AUDIT
2483 struct lsm_network_audit net;
2484#endif
2485 struct smk_audit_info ad;
2486 int rc;
2487
2488#ifdef CONFIG_AUDIT
2489 smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
2490 ad.a.u.net->family = PF_INET6;
2491 ad.a.u.net->dport = ntohs(address->sin6_port);
2492 if (act == SMK_RECEIVING)
2493 ad.a.u.net->v6info.saddr = address->sin6_addr;
2494 else
2495 ad.a.u.net->v6info.daddr = address->sin6_addr;
2496#endif
2497 rc = smk_access(subject, object, MAY_WRITE, &ad);
2498 rc = smk_bu_note("IPv6 check", subject, object, MAY_WRITE, rc);
2499 return rc;
2500}
2501#endif /* CONFIG_IPV6 */
2502
2503#ifdef SMACK_IPV6_PORT_LABELING
2240/** 2504/**
2241 * smk_ipv6_port_label - Smack port access table management 2505 * smk_ipv6_port_label - Smack port access table management
2242 * @sock: socket 2506 * @sock: socket
@@ -2320,48 +2584,43 @@ static void smk_ipv6_port_label(struct socket *sock, struct sockaddr *address)
2320static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address, 2584static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address,
2321 int act) 2585 int act)
2322{ 2586{
2323 __be16 *bep;
2324 __be32 *be32p;
2325 struct smk_port_label *spp; 2587 struct smk_port_label *spp;
2326 struct socket_smack *ssp = sk->sk_security; 2588 struct socket_smack *ssp = sk->sk_security;
2327 struct smack_known *skp; 2589 struct smack_known *skp = NULL;
2328 unsigned short port = 0; 2590 unsigned short port;
2329 struct smack_known *object; 2591 struct smack_known *object;
2330 struct smk_audit_info ad;
2331 int rc;
2332#ifdef CONFIG_AUDIT
2333 struct lsm_network_audit net;
2334#endif
2335 2592
2336 if (act == SMK_RECEIVING) { 2593 if (act == SMK_RECEIVING) {
2337 skp = smack_net_ambient; 2594 skp = smack_ipv6host_label(address);
2338 object = ssp->smk_in; 2595 object = ssp->smk_in;
2339 } else { 2596 } else {
2340 skp = ssp->smk_out; 2597 skp = ssp->smk_out;
2341 object = smack_net_ambient; 2598 object = smack_ipv6host_label(address);
2342 } 2599 }
2343 2600
2344 /* 2601 /*
2345 * Get the IP address and port from the address. 2602 * The other end is a single label host.
2346 */ 2603 */
2347 port = ntohs(address->sin6_port); 2604 if (skp != NULL && object != NULL)
2348 bep = (__be16 *)(&address->sin6_addr); 2605 return smk_ipv6_check(skp, object, address, act);
2349 be32p = (__be32 *)(&address->sin6_addr); 2606 if (skp == NULL)
2607 skp = smack_net_ambient;
2608 if (object == NULL)
2609 object = smack_net_ambient;
2350 2610
2351 /* 2611 /*
2352 * It's remote, so port lookup does no good. 2612 * It's remote, so port lookup does no good.
2353 */ 2613 */
2354 if (be32p[0] || be32p[1] || be32p[2] || bep[6] || ntohs(bep[7]) != 1) 2614 if (!smk_ipv6_localhost(address))
2355 goto auditout; 2615 return smk_ipv6_check(skp, object, address, act);
2356 2616
2357 /* 2617 /*
2358 * It's local so the send check has to have passed. 2618 * It's local so the send check has to have passed.
2359 */ 2619 */
2360 if (act == SMK_RECEIVING) { 2620 if (act == SMK_RECEIVING)
2361 skp = &smack_known_web; 2621 return 0;
2362 goto auditout;
2363 }
2364 2622
2623 port = ntohs(address->sin6_port);
2365 list_for_each_entry(spp, &smk_ipv6_port_list, list) { 2624 list_for_each_entry(spp, &smk_ipv6_port_list, list) {
2366 if (spp->smk_port != port) 2625 if (spp->smk_port != port)
2367 continue; 2626 continue;
@@ -2371,22 +2630,9 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address,
2371 break; 2630 break;
2372 } 2631 }
2373 2632
2374auditout: 2633 return smk_ipv6_check(skp, object, address, act);
2375
2376#ifdef CONFIG_AUDIT
2377 smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
2378 ad.a.u.net->family = sk->sk_family;
2379 ad.a.u.net->dport = port;
2380 if (act == SMK_RECEIVING)
2381 ad.a.u.net->v6info.saddr = address->sin6_addr;
2382 else
2383 ad.a.u.net->v6info.daddr = address->sin6_addr;
2384#endif
2385 rc = smk_access(skp, object, MAY_WRITE, &ad);
2386 rc = smk_bu_note("IPv6 port check", skp, object, MAY_WRITE, rc);
2387 return rc;
2388} 2634}
2389#endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ 2635#endif /* SMACK_IPV6_PORT_LABELING */
2390 2636
2391/** 2637/**
2392 * smack_inode_setsecurity - set smack xattrs 2638 * smack_inode_setsecurity - set smack xattrs
@@ -2447,10 +2693,10 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
2447 } else 2693 } else
2448 return -EOPNOTSUPP; 2694 return -EOPNOTSUPP;
2449 2695
2450#if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) 2696#ifdef SMACK_IPV6_PORT_LABELING
2451 if (sock->sk->sk_family == PF_INET6) 2697 if (sock->sk->sk_family == PF_INET6)
2452 smk_ipv6_port_label(sock, NULL); 2698 smk_ipv6_port_label(sock, NULL);
2453#endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ 2699#endif
2454 2700
2455 return 0; 2701 return 0;
2456} 2702}
@@ -2492,7 +2738,7 @@ static int smack_socket_post_create(struct socket *sock, int family,
2492 return smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET); 2738 return smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET);
2493} 2739}
2494 2740
2495#ifndef CONFIG_SECURITY_SMACK_NETFILTER 2741#ifdef SMACK_IPV6_PORT_LABELING
2496/** 2742/**
2497 * smack_socket_bind - record port binding information. 2743 * smack_socket_bind - record port binding information.
2498 * @sock: the socket 2744 * @sock: the socket
@@ -2506,14 +2752,11 @@ static int smack_socket_post_create(struct socket *sock, int family,
2506static int smack_socket_bind(struct socket *sock, struct sockaddr *address, 2752static int smack_socket_bind(struct socket *sock, struct sockaddr *address,
2507 int addrlen) 2753 int addrlen)
2508{ 2754{
2509#if IS_ENABLED(CONFIG_IPV6)
2510 if (sock->sk != NULL && sock->sk->sk_family == PF_INET6) 2755 if (sock->sk != NULL && sock->sk->sk_family == PF_INET6)
2511 smk_ipv6_port_label(sock, address); 2756 smk_ipv6_port_label(sock, address);
2512#endif
2513
2514 return 0; 2757 return 0;
2515} 2758}
2516#endif /* !CONFIG_SECURITY_SMACK_NETFILTER */ 2759#endif /* SMACK_IPV6_PORT_LABELING */
2517 2760
2518/** 2761/**
2519 * smack_socket_connect - connect access check 2762 * smack_socket_connect - connect access check
@@ -2529,6 +2772,13 @@ static int smack_socket_connect(struct socket *sock, struct sockaddr *sap,
2529 int addrlen) 2772 int addrlen)
2530{ 2773{
2531 int rc = 0; 2774 int rc = 0;
2775#if IS_ENABLED(CONFIG_IPV6)
2776 struct sockaddr_in6 *sip = (struct sockaddr_in6 *)sap;
2777#endif
2778#ifdef SMACK_IPV6_SECMARK_LABELING
2779 struct smack_known *rsp;
2780 struct socket_smack *ssp = sock->sk->sk_security;
2781#endif
2532 2782
2533 if (sock->sk == NULL) 2783 if (sock->sk == NULL)
2534 return 0; 2784 return 0;
@@ -2542,10 +2792,15 @@ static int smack_socket_connect(struct socket *sock, struct sockaddr *sap,
2542 case PF_INET6: 2792 case PF_INET6:
2543 if (addrlen < sizeof(struct sockaddr_in6)) 2793 if (addrlen < sizeof(struct sockaddr_in6))
2544 return -EINVAL; 2794 return -EINVAL;
2545#if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) 2795#ifdef SMACK_IPV6_SECMARK_LABELING
2546 rc = smk_ipv6_port_check(sock->sk, (struct sockaddr_in6 *)sap, 2796 rsp = smack_ipv6host_label(sip);
2797 if (rsp != NULL)
2798 rc = smk_ipv6_check(ssp->smk_out, rsp, sip,
2547 SMK_CONNECTING); 2799 SMK_CONNECTING);
2548#endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ 2800#endif
2801#ifdef SMACK_IPV6_PORT_LABELING
2802 rc = smk_ipv6_port_check(sock->sk, sip, SMK_CONNECTING);
2803#endif
2549 break; 2804 break;
2550 } 2805 }
2551 return rc; 2806 return rc;
@@ -3431,9 +3686,13 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg,
3431 int size) 3686 int size)
3432{ 3687{
3433 struct sockaddr_in *sip = (struct sockaddr_in *) msg->msg_name; 3688 struct sockaddr_in *sip = (struct sockaddr_in *) msg->msg_name;
3434#if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) 3689#if IS_ENABLED(CONFIG_IPV6)
3435 struct sockaddr_in6 *sap = (struct sockaddr_in6 *) msg->msg_name; 3690 struct sockaddr_in6 *sap = (struct sockaddr_in6 *) msg->msg_name;
3436#endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ 3691#endif
3692#ifdef SMACK_IPV6_SECMARK_LABELING
3693 struct socket_smack *ssp = sock->sk->sk_security;
3694 struct smack_known *rsp;
3695#endif
3437 int rc = 0; 3696 int rc = 0;
3438 3697
3439 /* 3698 /*
@@ -3447,9 +3706,15 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg,
3447 rc = smack_netlabel_send(sock->sk, sip); 3706 rc = smack_netlabel_send(sock->sk, sip);
3448 break; 3707 break;
3449 case AF_INET6: 3708 case AF_INET6:
3450#if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) 3709#ifdef SMACK_IPV6_SECMARK_LABELING
3710 rsp = smack_ipv6host_label(sap);
3711 if (rsp != NULL)
3712 rc = smk_ipv6_check(ssp->smk_out, rsp, sap,
3713 SMK_CONNECTING);
3714#endif
3715#ifdef SMACK_IPV6_PORT_LABELING
3451 rc = smk_ipv6_port_check(sock->sk, sap, SMK_SENDING); 3716 rc = smk_ipv6_port_check(sock->sk, sap, SMK_SENDING);
3452#endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ 3717#endif
3453 break; 3718 break;
3454 } 3719 }
3455 return rc; 3720 return rc;
@@ -3663,10 +3928,12 @@ access_check:
3663 proto = smk_skb_to_addr_ipv6(skb, &sadd); 3928 proto = smk_skb_to_addr_ipv6(skb, &sadd);
3664 if (proto != IPPROTO_UDP && proto != IPPROTO_TCP) 3929 if (proto != IPPROTO_UDP && proto != IPPROTO_TCP)
3665 break; 3930 break;
3666#ifdef CONFIG_SECURITY_SMACK_NETFILTER 3931#ifdef SMACK_IPV6_SECMARK_LABELING
3667 if (skb && skb->secmark != 0) 3932 if (skb && skb->secmark != 0)
3668 skp = smack_from_secid(skb->secmark); 3933 skp = smack_from_secid(skb->secmark);
3669 else 3934 else
3935 skp = smack_ipv6host_label(&sadd);
3936 if (skp == NULL)
3670 skp = smack_net_ambient; 3937 skp = smack_net_ambient;
3671#ifdef CONFIG_AUDIT 3938#ifdef CONFIG_AUDIT
3672 smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); 3939 smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
@@ -3677,9 +3944,10 @@ access_check:
3677 rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad); 3944 rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad);
3678 rc = smk_bu_note("IPv6 delivery", skp, ssp->smk_in, 3945 rc = smk_bu_note("IPv6 delivery", skp, ssp->smk_in,
3679 MAY_WRITE, rc); 3946 MAY_WRITE, rc);
3680#else /* CONFIG_SECURITY_SMACK_NETFILTER */ 3947#endif /* SMACK_IPV6_SECMARK_LABELING */
3948#ifdef SMACK_IPV6_PORT_LABELING
3681 rc = smk_ipv6_port_check(sk, &sadd, SMK_RECEIVING); 3949 rc = smk_ipv6_port_check(sk, &sadd, SMK_RECEIVING);
3682#endif /* CONFIG_SECURITY_SMACK_NETFILTER */ 3950#endif /* SMACK_IPV6_PORT_LABELING */
3683 break; 3951 break;
3684#endif /* CONFIG_IPV6 */ 3952#endif /* CONFIG_IPV6 */
3685 } 3953 }
@@ -3777,13 +4045,11 @@ static int smack_socket_getpeersec_dgram(struct socket *sock,
3777 } 4045 }
3778 netlbl_secattr_destroy(&secattr); 4046 netlbl_secattr_destroy(&secattr);
3779 break; 4047 break;
3780#if IS_ENABLED(CONFIG_IPV6)
3781 case PF_INET6: 4048 case PF_INET6:
3782#ifdef CONFIG_SECURITY_SMACK_NETFILTER 4049#ifdef SMACK_IPV6_SECMARK_LABELING
3783 s = skb->secmark; 4050 s = skb->secmark;
3784#endif /* CONFIG_SECURITY_SMACK_NETFILTER */ 4051#endif
3785 break; 4052 break;
3786#endif /* CONFIG_IPV6 */
3787 } 4053 }
3788 *secid = s; 4054 *secid = s;
3789 if (s == 0) 4055 if (s == 0)
@@ -3906,7 +4172,7 @@ access_check:
3906 hdr = ip_hdr(skb); 4172 hdr = ip_hdr(skb);
3907 addr.sin_addr.s_addr = hdr->saddr; 4173 addr.sin_addr.s_addr = hdr->saddr;
3908 rcu_read_lock(); 4174 rcu_read_lock();
3909 hskp = smack_host_label(&addr); 4175 hskp = smack_ipv4host_label(&addr);
3910 rcu_read_unlock(); 4176 rcu_read_unlock();
3911 4177
3912 if (hskp == NULL) 4178 if (hskp == NULL)
@@ -4254,7 +4520,7 @@ static int smack_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
4254 return 0; 4520 return 0;
4255} 4521}
4256 4522
4257struct security_hook_list smack_hooks[] = { 4523static struct security_hook_list smack_hooks[] = {
4258 LSM_HOOK_INIT(ptrace_access_check, smack_ptrace_access_check), 4524 LSM_HOOK_INIT(ptrace_access_check, smack_ptrace_access_check),
4259 LSM_HOOK_INIT(ptrace_traceme, smack_ptrace_traceme), 4525 LSM_HOOK_INIT(ptrace_traceme, smack_ptrace_traceme),
4260 LSM_HOOK_INIT(syslog, smack_syslog), 4526 LSM_HOOK_INIT(syslog, smack_syslog),
@@ -4264,6 +4530,8 @@ struct security_hook_list smack_hooks[] = {
4264 LSM_HOOK_INIT(sb_copy_data, smack_sb_copy_data), 4530 LSM_HOOK_INIT(sb_copy_data, smack_sb_copy_data),
4265 LSM_HOOK_INIT(sb_kern_mount, smack_sb_kern_mount), 4531 LSM_HOOK_INIT(sb_kern_mount, smack_sb_kern_mount),
4266 LSM_HOOK_INIT(sb_statfs, smack_sb_statfs), 4532 LSM_HOOK_INIT(sb_statfs, smack_sb_statfs),
4533 LSM_HOOK_INIT(sb_set_mnt_opts, smack_set_mnt_opts),
4534 LSM_HOOK_INIT(sb_parse_opts_str, smack_parse_opts_str),
4267 4535
4268 LSM_HOOK_INIT(bprm_set_creds, smack_bprm_set_creds), 4536 LSM_HOOK_INIT(bprm_set_creds, smack_bprm_set_creds),
4269 LSM_HOOK_INIT(bprm_committing_creds, smack_bprm_committing_creds), 4537 LSM_HOOK_INIT(bprm_committing_creds, smack_bprm_committing_creds),
@@ -4356,9 +4624,9 @@ struct security_hook_list smack_hooks[] = {
4356 LSM_HOOK_INIT(unix_may_send, smack_unix_may_send), 4624 LSM_HOOK_INIT(unix_may_send, smack_unix_may_send),
4357 4625
4358 LSM_HOOK_INIT(socket_post_create, smack_socket_post_create), 4626 LSM_HOOK_INIT(socket_post_create, smack_socket_post_create),
4359#ifndef CONFIG_SECURITY_SMACK_NETFILTER 4627#ifdef SMACK_IPV6_PORT_LABELING
4360 LSM_HOOK_INIT(socket_bind, smack_socket_bind), 4628 LSM_HOOK_INIT(socket_bind, smack_socket_bind),
4361#endif /* CONFIG_SECURITY_SMACK_NETFILTER */ 4629#endif
4362 LSM_HOOK_INIT(socket_connect, smack_socket_connect), 4630 LSM_HOOK_INIT(socket_connect, smack_socket_connect),
4363 LSM_HOOK_INIT(socket_sendmsg, smack_socket_sendmsg), 4631 LSM_HOOK_INIT(socket_sendmsg, smack_socket_sendmsg),
4364 LSM_HOOK_INIT(socket_sock_rcv_skb, smack_socket_sock_rcv_skb), 4632 LSM_HOOK_INIT(socket_sock_rcv_skb, smack_socket_sock_rcv_skb),
@@ -4453,7 +4721,16 @@ static __init int smack_init(void)
4453 return -ENOMEM; 4721 return -ENOMEM;
4454 } 4722 }
4455 4723
4456 printk(KERN_INFO "Smack: Initializing.\n"); 4724 pr_info("Smack: Initializing.\n");
4725#ifdef CONFIG_SECURITY_SMACK_NETFILTER
4726 pr_info("Smack: Netfilter enabled.\n");
4727#endif
4728#ifdef SMACK_IPV6_PORT_LABELING
4729 pr_info("Smack: IPv6 port labeling enabled.\n");
4730#endif
4731#ifdef SMACK_IPV6_SECMARK_LABELING
4732 pr_info("Smack: IPv6 Netfilter enabled.\n");
4733#endif
4457 4734
4458 /* 4735 /*
4459 * Set the security state for the initial task. 4736 * Set the security state for the initial task.
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index 2716d02119f3..c20b154a33f2 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -29,6 +29,7 @@
29#include <linux/magic.h> 29#include <linux/magic.h>
30#include "smack.h" 30#include "smack.h"
31 31
32#define BEBITS (sizeof(__be32) * 8)
32/* 33/*
33 * smackfs pseudo filesystem. 34 * smackfs pseudo filesystem.
34 */ 35 */
@@ -40,7 +41,7 @@ enum smk_inos {
40 SMK_DOI = 5, /* CIPSO DOI */ 41 SMK_DOI = 5, /* CIPSO DOI */
41 SMK_DIRECT = 6, /* CIPSO level indicating direct label */ 42 SMK_DIRECT = 6, /* CIPSO level indicating direct label */
42 SMK_AMBIENT = 7, /* internet ambient label */ 43 SMK_AMBIENT = 7, /* internet ambient label */
43 SMK_NETLBLADDR = 8, /* single label hosts */ 44 SMK_NET4ADDR = 8, /* single label hosts */
44 SMK_ONLYCAP = 9, /* the only "capable" label */ 45 SMK_ONLYCAP = 9, /* the only "capable" label */
45 SMK_LOGGING = 10, /* logging */ 46 SMK_LOGGING = 10, /* logging */
46 SMK_LOAD_SELF = 11, /* task specific rules */ 47 SMK_LOAD_SELF = 11, /* task specific rules */
@@ -57,6 +58,9 @@ enum smk_inos {
57#ifdef CONFIG_SECURITY_SMACK_BRINGUP 58#ifdef CONFIG_SECURITY_SMACK_BRINGUP
58 SMK_UNCONFINED = 22, /* define an unconfined label */ 59 SMK_UNCONFINED = 22, /* define an unconfined label */
59#endif 60#endif
61#if IS_ENABLED(CONFIG_IPV6)
62 SMK_NET6ADDR = 23, /* single label IPv6 hosts */
63#endif /* CONFIG_IPV6 */
60}; 64};
61 65
62/* 66/*
@@ -64,7 +68,10 @@ enum smk_inos {
64 */ 68 */
65static DEFINE_MUTEX(smack_cipso_lock); 69static DEFINE_MUTEX(smack_cipso_lock);
66static DEFINE_MUTEX(smack_ambient_lock); 70static DEFINE_MUTEX(smack_ambient_lock);
67static DEFINE_MUTEX(smk_netlbladdr_lock); 71static DEFINE_MUTEX(smk_net4addr_lock);
72#if IS_ENABLED(CONFIG_IPV6)
73static DEFINE_MUTEX(smk_net6addr_lock);
74#endif /* CONFIG_IPV6 */
68 75
69/* 76/*
70 * This is the "ambient" label for network traffic. 77 * This is the "ambient" label for network traffic.
@@ -118,7 +125,10 @@ int smack_ptrace_rule = SMACK_PTRACE_DEFAULT;
118 * can write to the specified label. 125 * can write to the specified label.
119 */ 126 */
120 127
121LIST_HEAD(smk_netlbladdr_list); 128LIST_HEAD(smk_net4addr_list);
129#if IS_ENABLED(CONFIG_IPV6)
130LIST_HEAD(smk_net6addr_list);
131#endif /* CONFIG_IPV6 */
122 132
123/* 133/*
124 * Rule lists are maintained for each label. 134 * Rule lists are maintained for each label.
@@ -129,7 +139,7 @@ struct smack_master_list {
129 struct smack_rule *smk_rule; 139 struct smack_rule *smk_rule;
130}; 140};
131 141
132LIST_HEAD(smack_rule_list); 142static LIST_HEAD(smack_rule_list);
133 143
134struct smack_parsed_rule { 144struct smack_parsed_rule {
135 struct smack_known *smk_subject; 145 struct smack_known *smk_subject;
@@ -140,11 +150,6 @@ struct smack_parsed_rule {
140 150
141static int smk_cipso_doi_value = SMACK_CIPSO_DOI_DEFAULT; 151static int smk_cipso_doi_value = SMACK_CIPSO_DOI_DEFAULT;
142 152
143struct smack_known smack_cipso_option = {
144 .smk_known = SMACK_CIPSO_OPTION,
145 .smk_secid = 0,
146};
147
148/* 153/*
149 * Values for parsing cipso rules 154 * Values for parsing cipso rules
150 * SMK_DIGITLEN: Length of a digit field in a rule. 155 * SMK_DIGITLEN: Length of a digit field in a rule.
@@ -1047,92 +1052,90 @@ static const struct file_operations smk_cipso2_ops = {
1047 * Seq_file read operations for /smack/netlabel 1052 * Seq_file read operations for /smack/netlabel
1048 */ 1053 */
1049 1054
1050static void *netlbladdr_seq_start(struct seq_file *s, loff_t *pos) 1055static void *net4addr_seq_start(struct seq_file *s, loff_t *pos)
1051{ 1056{
1052 return smk_seq_start(s, pos, &smk_netlbladdr_list); 1057 return smk_seq_start(s, pos, &smk_net4addr_list);
1053} 1058}
1054 1059
1055static void *netlbladdr_seq_next(struct seq_file *s, void *v, loff_t *pos) 1060static void *net4addr_seq_next(struct seq_file *s, void *v, loff_t *pos)
1056{ 1061{
1057 return smk_seq_next(s, v, pos, &smk_netlbladdr_list); 1062 return smk_seq_next(s, v, pos, &smk_net4addr_list);
1058} 1063}
1059#define BEBITS (sizeof(__be32) * 8)
1060 1064
1061/* 1065/*
1062 * Print host/label pairs 1066 * Print host/label pairs
1063 */ 1067 */
1064static int netlbladdr_seq_show(struct seq_file *s, void *v) 1068static int net4addr_seq_show(struct seq_file *s, void *v)
1065{ 1069{
1066 struct list_head *list = v; 1070 struct list_head *list = v;
1067 struct smk_netlbladdr *skp = 1071 struct smk_net4addr *skp =
1068 list_entry_rcu(list, struct smk_netlbladdr, list); 1072 list_entry_rcu(list, struct smk_net4addr, list);
1069 unsigned char *hp = (char *) &skp->smk_host.sin_addr.s_addr; 1073 char *kp = SMACK_CIPSO_OPTION;
1070 int maskn;
1071 u32 temp_mask = be32_to_cpu(skp->smk_mask.s_addr);
1072
1073 for (maskn = 0; temp_mask; temp_mask <<= 1, maskn++);
1074 1074
1075 seq_printf(s, "%u.%u.%u.%u/%d %s\n", 1075 if (skp->smk_label != NULL)
1076 hp[0], hp[1], hp[2], hp[3], maskn, skp->smk_label->smk_known); 1076 kp = skp->smk_label->smk_known;
1077 seq_printf(s, "%pI4/%d %s\n", &skp->smk_host.s_addr,
1078 skp->smk_masks, kp);
1077 1079
1078 return 0; 1080 return 0;
1079} 1081}
1080 1082
1081static const struct seq_operations netlbladdr_seq_ops = { 1083static const struct seq_operations net4addr_seq_ops = {
1082 .start = netlbladdr_seq_start, 1084 .start = net4addr_seq_start,
1083 .next = netlbladdr_seq_next, 1085 .next = net4addr_seq_next,
1084 .show = netlbladdr_seq_show, 1086 .show = net4addr_seq_show,
1085 .stop = smk_seq_stop, 1087 .stop = smk_seq_stop,
1086}; 1088};
1087 1089
1088/** 1090/**
1089 * smk_open_netlbladdr - open() for /smack/netlabel 1091 * smk_open_net4addr - open() for /smack/netlabel
1090 * @inode: inode structure representing file 1092 * @inode: inode structure representing file
1091 * @file: "netlabel" file pointer 1093 * @file: "netlabel" file pointer
1092 * 1094 *
1093 * Connect our netlbladdr_seq_* operations with /smack/netlabel 1095 * Connect our net4addr_seq_* operations with /smack/netlabel
1094 * file_operations 1096 * file_operations
1095 */ 1097 */
1096static int smk_open_netlbladdr(struct inode *inode, struct file *file) 1098static int smk_open_net4addr(struct inode *inode, struct file *file)
1097{ 1099{
1098 return seq_open(file, &netlbladdr_seq_ops); 1100 return seq_open(file, &net4addr_seq_ops);
1099} 1101}
1100 1102
1101/** 1103/**
1102 * smk_netlbladdr_insert 1104 * smk_net4addr_insert
1103 * @new : netlabel to insert 1105 * @new : netlabel to insert
1104 * 1106 *
1105 * This helper insert netlabel in the smack_netlbladdrs list 1107 * This helper insert netlabel in the smack_net4addrs list
1106 * sorted by netmask length (longest to smallest) 1108 * sorted by netmask length (longest to smallest)
1107 * locked by &smk_netlbladdr_lock in smk_write_netlbladdr 1109 * locked by &smk_net4addr_lock in smk_write_net4addr
1108 * 1110 *
1109 */ 1111 */
1110static void smk_netlbladdr_insert(struct smk_netlbladdr *new) 1112static void smk_net4addr_insert(struct smk_net4addr *new)
1111{ 1113{
1112 struct smk_netlbladdr *m, *m_next; 1114 struct smk_net4addr *m;
1115 struct smk_net4addr *m_next;
1113 1116
1114 if (list_empty(&smk_netlbladdr_list)) { 1117 if (list_empty(&smk_net4addr_list)) {
1115 list_add_rcu(&new->list, &smk_netlbladdr_list); 1118 list_add_rcu(&new->list, &smk_net4addr_list);
1116 return; 1119 return;
1117 } 1120 }
1118 1121
1119 m = list_entry_rcu(smk_netlbladdr_list.next, 1122 m = list_entry_rcu(smk_net4addr_list.next,
1120 struct smk_netlbladdr, list); 1123 struct smk_net4addr, list);
1121 1124
1122 /* the comparison '>' is a bit hacky, but works */ 1125 /* the comparison '>' is a bit hacky, but works */
1123 if (new->smk_mask.s_addr > m->smk_mask.s_addr) { 1126 if (new->smk_masks > m->smk_masks) {
1124 list_add_rcu(&new->list, &smk_netlbladdr_list); 1127 list_add_rcu(&new->list, &smk_net4addr_list);
1125 return; 1128 return;
1126 } 1129 }
1127 1130
1128 list_for_each_entry_rcu(m, &smk_netlbladdr_list, list) { 1131 list_for_each_entry_rcu(m, &smk_net4addr_list, list) {
1129 if (list_is_last(&m->list, &smk_netlbladdr_list)) { 1132 if (list_is_last(&m->list, &smk_net4addr_list)) {
1130 list_add_rcu(&new->list, &m->list); 1133 list_add_rcu(&new->list, &m->list);
1131 return; 1134 return;
1132 } 1135 }
1133 m_next = list_entry_rcu(m->list.next, 1136 m_next = list_entry_rcu(m->list.next,
1134 struct smk_netlbladdr, list); 1137 struct smk_net4addr, list);
1135 if (new->smk_mask.s_addr > m_next->smk_mask.s_addr) { 1138 if (new->smk_masks > m_next->smk_masks) {
1136 list_add_rcu(&new->list, &m->list); 1139 list_add_rcu(&new->list, &m->list);
1137 return; 1140 return;
1138 } 1141 }
@@ -1141,28 +1144,29 @@ static void smk_netlbladdr_insert(struct smk_netlbladdr *new)
1141 1144
1142 1145
1143/** 1146/**
1144 * smk_write_netlbladdr - write() for /smack/netlabel 1147 * smk_write_net4addr - write() for /smack/netlabel
1145 * @file: file pointer, not actually used 1148 * @file: file pointer, not actually used
1146 * @buf: where to get the data from 1149 * @buf: where to get the data from
1147 * @count: bytes sent 1150 * @count: bytes sent
1148 * @ppos: where to start 1151 * @ppos: where to start
1149 * 1152 *
1150 * Accepts only one netlbladdr per write call. 1153 * Accepts only one net4addr per write call.
1151 * Returns number of bytes written or error code, as appropriate 1154 * Returns number of bytes written or error code, as appropriate
1152 */ 1155 */
1153static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf, 1156static ssize_t smk_write_net4addr(struct file *file, const char __user *buf,
1154 size_t count, loff_t *ppos) 1157 size_t count, loff_t *ppos)
1155{ 1158{
1156 struct smk_netlbladdr *snp; 1159 struct smk_net4addr *snp;
1157 struct sockaddr_in newname; 1160 struct sockaddr_in newname;
1158 char *smack; 1161 char *smack;
1159 struct smack_known *skp; 1162 struct smack_known *skp = NULL;
1160 char *data; 1163 char *data;
1161 char *host = (char *)&newname.sin_addr.s_addr; 1164 char *host = (char *)&newname.sin_addr.s_addr;
1162 int rc; 1165 int rc;
1163 struct netlbl_audit audit_info; 1166 struct netlbl_audit audit_info;
1164 struct in_addr mask; 1167 struct in_addr mask;
1165 unsigned int m; 1168 unsigned int m;
1169 unsigned int masks;
1166 int found; 1170 int found;
1167 u32 mask_bits = (1<<31); 1171 u32 mask_bits = (1<<31);
1168 __be32 nsa; 1172 __be32 nsa;
@@ -1200,7 +1204,7 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
1200 data[count] = '\0'; 1204 data[count] = '\0';
1201 1205
1202 rc = sscanf(data, "%hhd.%hhd.%hhd.%hhd/%u %s", 1206 rc = sscanf(data, "%hhd.%hhd.%hhd.%hhd/%u %s",
1203 &host[0], &host[1], &host[2], &host[3], &m, smack); 1207 &host[0], &host[1], &host[2], &host[3], &masks, smack);
1204 if (rc != 6) { 1208 if (rc != 6) {
1205 rc = sscanf(data, "%hhd.%hhd.%hhd.%hhd %s", 1209 rc = sscanf(data, "%hhd.%hhd.%hhd.%hhd %s",
1206 &host[0], &host[1], &host[2], &host[3], smack); 1210 &host[0], &host[1], &host[2], &host[3], smack);
@@ -1209,8 +1213,9 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
1209 goto free_out; 1213 goto free_out;
1210 } 1214 }
1211 m = BEBITS; 1215 m = BEBITS;
1216 masks = 32;
1212 } 1217 }
1213 if (m > BEBITS) { 1218 if (masks > BEBITS) {
1214 rc = -EINVAL; 1219 rc = -EINVAL;
1215 goto free_out; 1220 goto free_out;
1216 } 1221 }
@@ -1225,16 +1230,16 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
1225 goto free_out; 1230 goto free_out;
1226 } 1231 }
1227 } else { 1232 } else {
1228 /* check known options */ 1233 /*
1229 if (strcmp(smack, smack_cipso_option.smk_known) == 0) 1234 * Only the -CIPSO option is supported for IPv4
1230 skp = &smack_cipso_option; 1235 */
1231 else { 1236 if (strcmp(smack, SMACK_CIPSO_OPTION) != 0) {
1232 rc = -EINVAL; 1237 rc = -EINVAL;
1233 goto free_out; 1238 goto free_out;
1234 } 1239 }
1235 } 1240 }
1236 1241
1237 for (temp_mask = 0; m > 0; m--) { 1242 for (m = masks, temp_mask = 0; m > 0; m--) {
1238 temp_mask |= mask_bits; 1243 temp_mask |= mask_bits;
1239 mask_bits >>= 1; 1244 mask_bits >>= 1;
1240 } 1245 }
@@ -1245,14 +1250,13 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
1245 * Only allow one writer at a time. Writes should be 1250 * Only allow one writer at a time. Writes should be
1246 * quite rare and small in any case. 1251 * quite rare and small in any case.
1247 */ 1252 */
1248 mutex_lock(&smk_netlbladdr_lock); 1253 mutex_lock(&smk_net4addr_lock);
1249 1254
1250 nsa = newname.sin_addr.s_addr; 1255 nsa = newname.sin_addr.s_addr;
1251 /* try to find if the prefix is already in the list */ 1256 /* try to find if the prefix is already in the list */
1252 found = 0; 1257 found = 0;
1253 list_for_each_entry_rcu(snp, &smk_netlbladdr_list, list) { 1258 list_for_each_entry_rcu(snp, &smk_net4addr_list, list) {
1254 if (snp->smk_host.sin_addr.s_addr == nsa && 1259 if (snp->smk_host.s_addr == nsa && snp->smk_masks == masks) {
1255 snp->smk_mask.s_addr == mask.s_addr) {
1256 found = 1; 1260 found = 1;
1257 break; 1261 break;
1258 } 1262 }
@@ -1265,17 +1269,20 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
1265 rc = -ENOMEM; 1269 rc = -ENOMEM;
1266 else { 1270 else {
1267 rc = 0; 1271 rc = 0;
1268 snp->smk_host.sin_addr.s_addr = newname.sin_addr.s_addr; 1272 snp->smk_host.s_addr = newname.sin_addr.s_addr;
1269 snp->smk_mask.s_addr = mask.s_addr; 1273 snp->smk_mask.s_addr = mask.s_addr;
1270 snp->smk_label = skp; 1274 snp->smk_label = skp;
1271 smk_netlbladdr_insert(snp); 1275 snp->smk_masks = masks;
1276 smk_net4addr_insert(snp);
1272 } 1277 }
1273 } else { 1278 } else {
1274 /* we delete the unlabeled entry, only if the previous label 1279 /*
1275 * wasn't the special CIPSO option */ 1280 * Delete the unlabeled entry, only if the previous label
1276 if (snp->smk_label != &smack_cipso_option) 1281 * wasn't the special CIPSO option
1282 */
1283 if (snp->smk_label != NULL)
1277 rc = netlbl_cfg_unlbl_static_del(&init_net, NULL, 1284 rc = netlbl_cfg_unlbl_static_del(&init_net, NULL,
1278 &snp->smk_host.sin_addr, &snp->smk_mask, 1285 &snp->smk_host, &snp->smk_mask,
1279 PF_INET, &audit_info); 1286 PF_INET, &audit_info);
1280 else 1287 else
1281 rc = 0; 1288 rc = 0;
@@ -1287,15 +1294,15 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
1287 * this host so that incoming packets get labeled. 1294 * this host so that incoming packets get labeled.
1288 * but only if we didn't get the special CIPSO option 1295 * but only if we didn't get the special CIPSO option
1289 */ 1296 */
1290 if (rc == 0 && skp != &smack_cipso_option) 1297 if (rc == 0 && skp != NULL)
1291 rc = netlbl_cfg_unlbl_static_add(&init_net, NULL, 1298 rc = netlbl_cfg_unlbl_static_add(&init_net, NULL,
1292 &snp->smk_host.sin_addr, &snp->smk_mask, PF_INET, 1299 &snp->smk_host, &snp->smk_mask, PF_INET,
1293 snp->smk_label->smk_secid, &audit_info); 1300 snp->smk_label->smk_secid, &audit_info);
1294 1301
1295 if (rc == 0) 1302 if (rc == 0)
1296 rc = count; 1303 rc = count;
1297 1304
1298 mutex_unlock(&smk_netlbladdr_lock); 1305 mutex_unlock(&smk_net4addr_lock);
1299 1306
1300free_out: 1307free_out:
1301 kfree(smack); 1308 kfree(smack);
@@ -1305,14 +1312,279 @@ free_data_out:
1305 return rc; 1312 return rc;
1306} 1313}
1307 1314
1308static const struct file_operations smk_netlbladdr_ops = { 1315static const struct file_operations smk_net4addr_ops = {
1309 .open = smk_open_netlbladdr, 1316 .open = smk_open_net4addr,
1310 .read = seq_read, 1317 .read = seq_read,
1311 .llseek = seq_lseek, 1318 .llseek = seq_lseek,
1312 .write = smk_write_netlbladdr, 1319 .write = smk_write_net4addr,
1313 .release = seq_release, 1320 .release = seq_release,
1314}; 1321};
1315 1322
1323#if IS_ENABLED(CONFIG_IPV6)
1324/*
1325 * Seq_file read operations for /smack/netlabel6
1326 */
1327
1328static void *net6addr_seq_start(struct seq_file *s, loff_t *pos)
1329{
1330 return smk_seq_start(s, pos, &smk_net6addr_list);
1331}
1332
1333static void *net6addr_seq_next(struct seq_file *s, void *v, loff_t *pos)
1334{
1335 return smk_seq_next(s, v, pos, &smk_net6addr_list);
1336}
1337
1338/*
1339 * Print host/label pairs
1340 */
1341static int net6addr_seq_show(struct seq_file *s, void *v)
1342{
1343 struct list_head *list = v;
1344 struct smk_net6addr *skp =
1345 list_entry(list, struct smk_net6addr, list);
1346
1347 if (skp->smk_label != NULL)
1348 seq_printf(s, "%pI6/%d %s\n", &skp->smk_host, skp->smk_masks,
1349 skp->smk_label->smk_known);
1350
1351 return 0;
1352}
1353
1354static const struct seq_operations net6addr_seq_ops = {
1355 .start = net6addr_seq_start,
1356 .next = net6addr_seq_next,
1357 .show = net6addr_seq_show,
1358 .stop = smk_seq_stop,
1359};
1360
1361/**
1362 * smk_open_net6addr - open() for /smack/netlabel
1363 * @inode: inode structure representing file
1364 * @file: "netlabel" file pointer
1365 *
1366 * Connect our net6addr_seq_* operations with /smack/netlabel
1367 * file_operations
1368 */
1369static int smk_open_net6addr(struct inode *inode, struct file *file)
1370{
1371 return seq_open(file, &net6addr_seq_ops);
1372}
1373
1374/**
1375 * smk_net6addr_insert
1376 * @new : entry to insert
1377 *
1378 * This inserts an entry in the smack_net6addrs list
1379 * sorted by netmask length (longest to smallest)
1380 * locked by &smk_net6addr_lock in smk_write_net6addr
1381 *
1382 */
1383static void smk_net6addr_insert(struct smk_net6addr *new)
1384{
1385 struct smk_net6addr *m_next;
1386 struct smk_net6addr *m;
1387
1388 if (list_empty(&smk_net6addr_list)) {
1389 list_add_rcu(&new->list, &smk_net6addr_list);
1390 return;
1391 }
1392
1393 m = list_entry_rcu(smk_net6addr_list.next,
1394 struct smk_net6addr, list);
1395
1396 if (new->smk_masks > m->smk_masks) {
1397 list_add_rcu(&new->list, &smk_net6addr_list);
1398 return;
1399 }
1400
1401 list_for_each_entry_rcu(m, &smk_net6addr_list, list) {
1402 if (list_is_last(&m->list, &smk_net6addr_list)) {
1403 list_add_rcu(&new->list, &m->list);
1404 return;
1405 }
1406 m_next = list_entry_rcu(m->list.next,
1407 struct smk_net6addr, list);
1408 if (new->smk_masks > m_next->smk_masks) {
1409 list_add_rcu(&new->list, &m->list);
1410 return;
1411 }
1412 }
1413}
1414
1415
1416/**
1417 * smk_write_net6addr - write() for /smack/netlabel
1418 * @file: file pointer, not actually used
1419 * @buf: where to get the data from
1420 * @count: bytes sent
1421 * @ppos: where to start
1422 *
1423 * Accepts only one net6addr per write call.
1424 * Returns number of bytes written or error code, as appropriate
1425 */
1426static ssize_t smk_write_net6addr(struct file *file, const char __user *buf,
1427 size_t count, loff_t *ppos)
1428{
1429 struct smk_net6addr *snp;
1430 struct in6_addr newname;
1431 struct in6_addr fullmask;
1432 struct smack_known *skp = NULL;
1433 char *smack;
1434 char *data;
1435 int rc = 0;
1436 int found = 0;
1437 int i;
1438 unsigned int scanned[8];
1439 unsigned int m;
1440 unsigned int mask = 128;
1441
1442 /*
1443 * Must have privilege.
1444 * No partial writes.
1445 * Enough data must be present.
1446 * "<addr/mask, as a:b:c:d:e:f:g:h/e><space><label>"
1447 * "<addr, as a:b:c:d:e:f:g:h><space><label>"
1448 */
1449 if (!smack_privileged(CAP_MAC_ADMIN))
1450 return -EPERM;
1451 if (*ppos != 0)
1452 return -EINVAL;
1453 if (count < SMK_NETLBLADDRMIN)
1454 return -EINVAL;
1455
1456 data = kzalloc(count + 1, GFP_KERNEL);
1457 if (data == NULL)
1458 return -ENOMEM;
1459
1460 if (copy_from_user(data, buf, count) != 0) {
1461 rc = -EFAULT;
1462 goto free_data_out;
1463 }
1464
1465 smack = kzalloc(count + 1, GFP_KERNEL);
1466 if (smack == NULL) {
1467 rc = -ENOMEM;
1468 goto free_data_out;
1469 }
1470
1471 data[count] = '\0';
1472
1473 i = sscanf(data, "%x:%x:%x:%x:%x:%x:%x:%x/%u %s",
1474 &scanned[0], &scanned[1], &scanned[2], &scanned[3],
1475 &scanned[4], &scanned[5], &scanned[6], &scanned[7],
1476 &mask, smack);
1477 if (i != 10) {
1478 i = sscanf(data, "%x:%x:%x:%x:%x:%x:%x:%x %s",
1479 &scanned[0], &scanned[1], &scanned[2],
1480 &scanned[3], &scanned[4], &scanned[5],
1481 &scanned[6], &scanned[7], smack);
1482 if (i != 9) {
1483 rc = -EINVAL;
1484 goto free_out;
1485 }
1486 }
1487 if (mask > 128) {
1488 rc = -EINVAL;
1489 goto free_out;
1490 }
1491 for (i = 0; i < 8; i++) {
1492 if (scanned[i] > 0xffff) {
1493 rc = -EINVAL;
1494 goto free_out;
1495 }
1496 newname.s6_addr16[i] = htons(scanned[i]);
1497 }
1498
1499 /*
1500 * If smack begins with '-', it is an option, don't import it
1501 */
1502 if (smack[0] != '-') {
1503 skp = smk_import_entry(smack, 0);
1504 if (skp == NULL) {
1505 rc = -EINVAL;
1506 goto free_out;
1507 }
1508 } else {
1509 /*
1510 * Only -DELETE is supported for IPv6
1511 */
1512 if (strcmp(smack, SMACK_DELETE_OPTION) != 0) {
1513 rc = -EINVAL;
1514 goto free_out;
1515 }
1516 }
1517
1518 for (i = 0, m = mask; i < 8; i++) {
1519 if (m >= 16) {
1520 fullmask.s6_addr16[i] = 0xffff;
1521 m -= 16;
1522 } else if (m > 0) {
1523 fullmask.s6_addr16[i] = (1 << m) - 1;
1524 m = 0;
1525 } else
1526 fullmask.s6_addr16[i] = 0;
1527 newname.s6_addr16[i] &= fullmask.s6_addr16[i];
1528 }
1529
1530 /*
1531 * Only allow one writer at a time. Writes should be
1532 * quite rare and small in any case.
1533 */
1534 mutex_lock(&smk_net6addr_lock);
1535 /*
1536 * Try to find the prefix in the list
1537 */
1538 list_for_each_entry_rcu(snp, &smk_net6addr_list, list) {
1539 if (mask != snp->smk_masks)
1540 continue;
1541 for (found = 1, i = 0; i < 8; i++) {
1542 if (newname.s6_addr16[i] !=
1543 snp->smk_host.s6_addr16[i]) {
1544 found = 0;
1545 break;
1546 }
1547 }
1548 if (found == 1)
1549 break;
1550 }
1551 if (found == 0) {
1552 snp = kzalloc(sizeof(*snp), GFP_KERNEL);
1553 if (snp == NULL)
1554 rc = -ENOMEM;
1555 else {
1556 snp->smk_host = newname;
1557 snp->smk_mask = fullmask;
1558 snp->smk_masks = mask;
1559 snp->smk_label = skp;
1560 smk_net6addr_insert(snp);
1561 }
1562 } else {
1563 snp->smk_label = skp;
1564 }
1565
1566 if (rc == 0)
1567 rc = count;
1568
1569 mutex_unlock(&smk_net6addr_lock);
1570
1571free_out:
1572 kfree(smack);
1573free_data_out:
1574 kfree(data);
1575
1576 return rc;
1577}
1578
1579static const struct file_operations smk_net6addr_ops = {
1580 .open = smk_open_net6addr,
1581 .read = seq_read,
1582 .llseek = seq_lseek,
1583 .write = smk_write_net6addr,
1584 .release = seq_release,
1585};
1586#endif /* CONFIG_IPV6 */
1587
1316/** 1588/**
1317 * smk_read_doi - read() for /smack/doi 1589 * smk_read_doi - read() for /smack/doi
1318 * @filp: file pointer, not actually used 1590 * @filp: file pointer, not actually used
@@ -2320,11 +2592,7 @@ static const struct file_operations smk_revoke_subj_ops = {
2320 */ 2592 */
2321static int smk_init_sysfs(void) 2593static int smk_init_sysfs(void)
2322{ 2594{
2323 int err; 2595 return sysfs_create_mount_point(fs_kobj, "smackfs");
2324 err = sysfs_create_mount_point(fs_kobj, "smackfs");
2325 if (err)
2326 return err;
2327 return 0;
2328} 2596}
2329 2597
2330/** 2598/**
@@ -2519,8 +2787,8 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent)
2519 "direct", &smk_direct_ops, S_IRUGO|S_IWUSR}, 2787 "direct", &smk_direct_ops, S_IRUGO|S_IWUSR},
2520 [SMK_AMBIENT] = { 2788 [SMK_AMBIENT] = {
2521 "ambient", &smk_ambient_ops, S_IRUGO|S_IWUSR}, 2789 "ambient", &smk_ambient_ops, S_IRUGO|S_IWUSR},
2522 [SMK_NETLBLADDR] = { 2790 [SMK_NET4ADDR] = {
2523 "netlabel", &smk_netlbladdr_ops, S_IRUGO|S_IWUSR}, 2791 "netlabel", &smk_net4addr_ops, S_IRUGO|S_IWUSR},
2524 [SMK_ONLYCAP] = { 2792 [SMK_ONLYCAP] = {
2525 "onlycap", &smk_onlycap_ops, S_IRUGO|S_IWUSR}, 2793 "onlycap", &smk_onlycap_ops, S_IRUGO|S_IWUSR},
2526 [SMK_LOGGING] = { 2794 [SMK_LOGGING] = {
@@ -2552,6 +2820,10 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent)
2552 [SMK_UNCONFINED] = { 2820 [SMK_UNCONFINED] = {
2553 "unconfined", &smk_unconfined_ops, S_IRUGO|S_IWUSR}, 2821 "unconfined", &smk_unconfined_ops, S_IRUGO|S_IWUSR},
2554#endif 2822#endif
2823#if IS_ENABLED(CONFIG_IPV6)
2824 [SMK_NET6ADDR] = {
2825 "ipv6host", &smk_net6addr_ops, S_IRUGO|S_IWUSR},
2826#endif /* CONFIG_IPV6 */
2555 /* last one */ 2827 /* last one */
2556 {""} 2828 {""}
2557 }; 2829 };
diff --git a/security/yama/Kconfig b/security/yama/Kconfig
index 3123e1da2fed..90c605eea892 100644
--- a/security/yama/Kconfig
+++ b/security/yama/Kconfig
@@ -6,14 +6,7 @@ config SECURITY_YAMA
6 This selects Yama, which extends DAC support with additional 6 This selects Yama, which extends DAC support with additional
7 system-wide security settings beyond regular Linux discretionary 7 system-wide security settings beyond regular Linux discretionary
8 access controls. Currently available is ptrace scope restriction. 8 access controls. Currently available is ptrace scope restriction.
9 Like capabilities, this security module stacks with other LSMs.
9 Further information can be found in Documentation/security/Yama.txt. 10 Further information can be found in Documentation/security/Yama.txt.
10 11
11 If you are unsure how to answer this question, answer N. 12 If you are unsure how to answer this question, answer N.
12
13config SECURITY_YAMA_STACKED
14 bool "Yama stacked with other LSMs"
15 depends on SECURITY_YAMA
16 default n
17 help
18 When Yama is built into the kernel, force it to stack with the
19 selected primary LSM.
diff --git a/security/yama/yama_lsm.c b/security/yama/yama_lsm.c
index 5ebb89687936..d3c19c970a06 100644
--- a/security/yama/yama_lsm.c
+++ b/security/yama/yama_lsm.c
@@ -353,11 +353,6 @@ static struct security_hook_list yama_hooks[] = {
353 LSM_HOOK_INIT(task_free, yama_task_free), 353 LSM_HOOK_INIT(task_free, yama_task_free),
354}; 354};
355 355
356void __init yama_add_hooks(void)
357{
358 security_add_hooks(yama_hooks, ARRAY_SIZE(yama_hooks));
359}
360
361#ifdef CONFIG_SYSCTL 356#ifdef CONFIG_SYSCTL
362static int yama_dointvec_minmax(struct ctl_table *table, int write, 357static int yama_dointvec_minmax(struct ctl_table *table, int write,
363 void __user *buffer, size_t *lenp, loff_t *ppos) 358 void __user *buffer, size_t *lenp, loff_t *ppos)
@@ -396,26 +391,18 @@ static struct ctl_table yama_sysctl_table[] = {
396 }, 391 },
397 { } 392 { }
398}; 393};
399#endif /* CONFIG_SYSCTL */ 394static void __init yama_init_sysctl(void)
400
401static __init int yama_init(void)
402{ 395{
403#ifndef CONFIG_SECURITY_YAMA_STACKED
404 /*
405 * If yama is being stacked this is already taken care of.
406 */
407 if (!security_module_enable("yama"))
408 return 0;
409 yama_add_hooks();
410#endif
411 pr_info("Yama: becoming mindful.\n");
412
413#ifdef CONFIG_SYSCTL
414 if (!register_sysctl_paths(yama_sysctl_path, yama_sysctl_table)) 396 if (!register_sysctl_paths(yama_sysctl_path, yama_sysctl_table))
415 panic("Yama: sysctl registration failed.\n"); 397 panic("Yama: sysctl registration failed.\n");
416#endif
417
418 return 0;
419} 398}
399#else
400static inline void yama_init_sysctl(void) { }
401#endif /* CONFIG_SYSCTL */
420 402
421security_initcall(yama_init); 403void __init yama_add_hooks(void)
404{
405 pr_info("Yama: becoming mindful.\n");
406 security_add_hooks(yama_hooks, ARRAY_SIZE(yama_hooks));
407 yama_init_sysctl();
408}