aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorJames Morris <james.l.morris@oracle.com>2015-08-10 21:18:53 -0400
committerJames Morris <james.l.morris@oracle.com>2015-08-10 21:18:53 -0400
commit5ab16579020edb79e215b401399f88c7e07fdaf9 (patch)
tree5fdb2e49d543af7de6b129d6c87abb1967000a6b /security
parent459c15e53cf7e4e88a78ecfb109af5a267c5500a (diff)
parent41a2d5751616e38d1e293e3cb35a6e2bc7a03473 (diff)
Merge branch 'smack-for-4.3' of https://github.com/cschaufler/smack-next into next
Diffstat (limited to 'security')
-rw-r--r--security/smack/smack.h66
-rw-r--r--security/smack/smack_access.c6
-rw-r--r--security/smack/smack_lsm.c507
-rw-r--r--security/smack/smackfs.c436
4 files changed, 807 insertions, 208 deletions
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..54fb3a1d8953 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,9 +51,9 @@
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
@@ -64,6 +65,15 @@ static char *smk_bu_mess[] = {
64 "Unconfined Object", /* SMACK_UNCONFINED_OBJECT */ 65 "Unconfined Object", /* SMACK_UNCONFINED_OBJECT */
65}; 66};
66 67
68static const match_table_t tokens = {
69 {Opt_fsdefault, SMK_FSDEFAULT "%s"},
70 {Opt_fsfloor, SMK_FSFLOOR "%s"},
71 {Opt_fshat, SMK_FSHAT "%s"},
72 {Opt_fsroot, SMK_FSROOT "%s"},
73 {Opt_fstransmute, SMK_FSTRANS "%s"},
74 {Opt_error, NULL},
75};
76
67static void smk_bu_mode(int mode, char *s) 77static void smk_bu_mode(int mode, char *s)
68{ 78{
69 int i = 0; 79 int i = 0;
@@ -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,193 @@ 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, *fsfloor = NULL;
603 char *fshat = NULL, *fsroot = NULL, *fstransmute = NULL;
604 int rc = -ENOMEM, num_mnt_opts = 0;
605
606 opts->num_mnt_opts = 0;
607
608 if (!options)
609 return 0;
610
611 while ((p = strsep(&options, ",")) != NULL) {
612 int token;
613 substring_t args[MAX_OPT_ARGS];
614
615 if (!*p)
616 continue;
617
618 token = match_token(p, tokens, args);
619
620 switch (token) {
621 case Opt_fsdefault:
622 if (fsdefault)
623 goto out_opt_err;
624 fsdefault = match_strdup(&args[0]);
625 if (!fsdefault)
626 goto out_err;
627 break;
628 case Opt_fsfloor:
629 if (fsfloor)
630 goto out_opt_err;
631 fsfloor = match_strdup(&args[0]);
632 if (!fsfloor)
633 goto out_err;
634 break;
635 case Opt_fshat:
636 if (fshat)
637 goto out_opt_err;
638 fshat = match_strdup(&args[0]);
639 if (!fshat)
640 goto out_err;
641 break;
642 case Opt_fsroot:
643 if (fsroot)
644 goto out_opt_err;
645 fsroot = match_strdup(&args[0]);
646 if (!fsroot)
647 goto out_err;
648 break;
649 case Opt_fstransmute:
650 if (fstransmute)
651 goto out_opt_err;
652 fstransmute = match_strdup(&args[0]);
653 if (!fstransmute)
654 goto out_err;
655 break;
656 default:
657 rc = -EINVAL;
658 pr_warn("Smack: unknown mount option\n");
659 goto out_err;
660 }
661 }
662
663 opts->mnt_opts = kcalloc(NUM_SMK_MNT_OPTS, sizeof(char *), GFP_ATOMIC);
664 if (!opts->mnt_opts)
665 goto out_err;
666
667 opts->mnt_opts_flags = kcalloc(NUM_SMK_MNT_OPTS, sizeof(int),
668 GFP_ATOMIC);
669 if (!opts->mnt_opts_flags) {
670 kfree(opts->mnt_opts);
671 goto out_err;
672 }
673
674 if (fsdefault) {
675 opts->mnt_opts[num_mnt_opts] = fsdefault;
676 opts->mnt_opts_flags[num_mnt_opts++] = FSDEFAULT_MNT;
677 }
678 if (fsfloor) {
679 opts->mnt_opts[num_mnt_opts] = fsfloor;
680 opts->mnt_opts_flags[num_mnt_opts++] = FSFLOOR_MNT;
681 }
682 if (fshat) {
683 opts->mnt_opts[num_mnt_opts] = fshat;
684 opts->mnt_opts_flags[num_mnt_opts++] = FSHAT_MNT;
685 }
686 if (fsroot) {
687 opts->mnt_opts[num_mnt_opts] = fsroot;
688 opts->mnt_opts_flags[num_mnt_opts++] = FSROOT_MNT;
689 }
690 if (fstransmute) {
691 opts->mnt_opts[num_mnt_opts] = fstransmute;
692 opts->mnt_opts_flags[num_mnt_opts++] = FSTRANS_MNT;
693 }
694
695 opts->num_mnt_opts = num_mnt_opts;
696 return 0;
697
698out_opt_err:
699 rc = -EINVAL;
700 pr_warn("Smack: duplicate mount options\n");
701
702out_err:
703 kfree(fsdefault);
704 kfree(fsfloor);
705 kfree(fshat);
706 kfree(fsroot);
707 kfree(fstransmute);
708 return rc;
709}
710
711/**
712 * smack_set_mnt_opts - set Smack specific mount options
581 * @sb: the file system superblock 713 * @sb: the file system superblock
582 * @flags: the mount flags 714 * @opts: Smack mount options
583 * @data: the smack mount options 715 * @kern_flags: mount option from kernel space or user space
716 * @set_kern_flags: where to store converted mount opts
584 * 717 *
585 * Returns 0 on success, an error code on failure 718 * Returns 0 on success, an error code on failure
719 *
720 * Allow filesystems with binary mount data to explicitly set Smack mount
721 * labels.
586 */ 722 */
587static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data) 723static int smack_set_mnt_opts(struct super_block *sb,
724 struct security_mnt_opts *opts,
725 unsigned long kern_flags,
726 unsigned long *set_kern_flags)
588{ 727{
589 struct dentry *root = sb->s_root; 728 struct dentry *root = sb->s_root;
590 struct inode *inode = d_backing_inode(root); 729 struct inode *inode = d_backing_inode(root);
591 struct superblock_smack *sp = sb->s_security; 730 struct superblock_smack *sp = sb->s_security;
592 struct inode_smack *isp; 731 struct inode_smack *isp;
593 struct smack_known *skp; 732 struct smack_known *skp;
594 char *op; 733 int i;
595 char *commap; 734 int num_opts = opts->num_mnt_opts;
596 int transmute = 0; 735 int transmute = 0;
597 int specified = 0;
598 736
599 if (sp->smk_initialized) 737 if (sp->smk_initialized)
600 return 0; 738 return 0;
601 739
602 sp->smk_initialized = 1; 740 sp->smk_initialized = 1;
603 741
604 for (op = data; op != NULL; op = commap) { 742 for (i = 0; i < num_opts; i++) {
605 commap = strchr(op, ','); 743 switch (opts->mnt_opts_flags[i]) {
606 if (commap != NULL) 744 case FSDEFAULT_MNT:
607 *commap++ = '\0'; 745 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)) 746 if (IS_ERR(skp))
613 return PTR_ERR(skp); 747 return PTR_ERR(skp);
614 sp->smk_hat = skp; 748 sp->smk_default = skp;
615 specified = 1; 749 break;
616 750 case FSFLOOR_MNT:
617 } else if (strncmp(op, SMK_FSFLOOR, strlen(SMK_FSFLOOR)) == 0) { 751 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)) 752 if (IS_ERR(skp))
621 return PTR_ERR(skp); 753 return PTR_ERR(skp);
622 sp->smk_floor = skp; 754 sp->smk_floor = skp;
623 specified = 1; 755 break;
624 756 case FSHAT_MNT:
625 } else if (strncmp(op, SMK_FSDEFAULT, 757 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)) 758 if (IS_ERR(skp))
630 return PTR_ERR(skp); 759 return PTR_ERR(skp);
631 sp->smk_default = skp; 760 sp->smk_hat = skp;
632 specified = 1; 761 break;
633 762 case FSROOT_MNT:
634 } else if (strncmp(op, SMK_FSROOT, strlen(SMK_FSROOT)) == 0) { 763 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)) 764 if (IS_ERR(skp))
638 return PTR_ERR(skp); 765 return PTR_ERR(skp);
639 sp->smk_root = skp; 766 sp->smk_root = skp;
640 specified = 1; 767 break;
641 768 case FSTRANS_MNT:
642 } else if (strncmp(op, SMK_FSTRANS, strlen(SMK_FSTRANS)) == 0) { 769 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)) 770 if (IS_ERR(skp))
646 return PTR_ERR(skp); 771 return PTR_ERR(skp);
647 sp->smk_root = skp; 772 sp->smk_root = skp;
648 transmute = 1; 773 transmute = 1;
649 specified = 1; 774 break;
775 default:
776 break;
650 } 777 }
651 } 778 }
652 779
@@ -654,7 +781,7 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data)
654 /* 781 /*
655 * Unprivileged mounts don't get to specify Smack values. 782 * Unprivileged mounts don't get to specify Smack values.
656 */ 783 */
657 if (specified) 784 if (num_opts)
658 return -EPERM; 785 return -EPERM;
659 /* 786 /*
660 * Unprivileged mounts get root and default from the caller. 787 * Unprivileged mounts get root and default from the caller.
@@ -663,6 +790,7 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data)
663 sp->smk_root = skp; 790 sp->smk_root = skp;
664 sp->smk_default = skp; 791 sp->smk_default = skp;
665 } 792 }
793
666 /* 794 /*
667 * Initialize the root inode. 795 * Initialize the root inode.
668 */ 796 */
@@ -682,6 +810,37 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data)
682} 810}
683 811
684/** 812/**
813 * smack_sb_kern_mount - Smack specific mount processing
814 * @sb: the file system superblock
815 * @flags: the mount flags
816 * @data: the smack mount options
817 *
818 * Returns 0 on success, an error code on failure
819 */
820static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data)
821{
822 int rc = 0;
823 char *options = data;
824 struct security_mnt_opts opts;
825
826 security_init_mnt_opts(&opts);
827
828 if (!options)
829 goto out;
830
831 rc = smack_parse_opts_str(options, &opts);
832 if (rc)
833 goto out_err;
834
835out:
836 rc = smack_set_mnt_opts(sb, &opts, 0, NULL);
837
838out_err:
839 security_free_mnt_opts(&opts);
840 return rc;
841}
842
843/**
685 * smack_sb_statfs - Smack check on statfs 844 * smack_sb_statfs - Smack check on statfs
686 * @dentry: identifies the file system in question 845 * @dentry: identifies the file system in question
687 * 846 *
@@ -2113,7 +2272,7 @@ static void smack_sk_free_security(struct sock *sk)
2113} 2272}
2114 2273
2115/** 2274/**
2116* smack_host_label - check host based restrictions 2275* smack_ipv4host_label - check host based restrictions
2117* @sip: the object end 2276* @sip: the object end
2118* 2277*
2119* looks for host based access restrictions 2278* looks for host based access restrictions
@@ -2124,30 +2283,96 @@ static void smack_sk_free_security(struct sock *sk)
2124* 2283*
2125* Returns the label of the far end or NULL if it's not special. 2284* Returns the label of the far end or NULL if it's not special.
2126*/ 2285*/
2127static struct smack_known *smack_host_label(struct sockaddr_in *sip) 2286static struct smack_known *smack_ipv4host_label(struct sockaddr_in *sip)
2128{ 2287{
2129 struct smk_netlbladdr *snp; 2288 struct smk_net4addr *snp;
2130 struct in_addr *siap = &sip->sin_addr; 2289 struct in_addr *siap = &sip->sin_addr;
2131 2290
2132 if (siap->s_addr == 0) 2291 if (siap->s_addr == 0)
2133 return NULL; 2292 return NULL;
2134 2293
2135 list_for_each_entry_rcu(snp, &smk_netlbladdr_list, list) 2294 list_for_each_entry_rcu(snp, &smk_net4addr_list, list)
2295 /*
2296 * we break after finding the first match because
2297 * the list is sorted from longest to shortest mask
2298 * so we have found the most specific match
2299 */
2300 if (snp->smk_host.s_addr ==
2301 (siap->s_addr & snp->smk_mask.s_addr))
2302 return snp->smk_label;
2303
2304 return NULL;
2305}
2306
2307#if IS_ENABLED(CONFIG_IPV6)
2308/*
2309 * smk_ipv6_localhost - Check for local ipv6 host address
2310 * @sip: the address
2311 *
2312 * Returns boolean true if this is the localhost address
2313 */
2314static bool smk_ipv6_localhost(struct sockaddr_in6 *sip)
2315{
2316 __be16 *be16p = (__be16 *)&sip->sin6_addr;
2317 __be32 *be32p = (__be32 *)&sip->sin6_addr;
2318
2319 if (be32p[0] == 0 && be32p[1] == 0 && be32p[2] == 0 && be16p[6] == 0 &&
2320 ntohs(be16p[7]) == 1)
2321 return true;
2322 return false;
2323}
2324
2325/**
2326* smack_ipv6host_label - check host based restrictions
2327* @sip: the object end
2328*
2329* looks for host based access restrictions
2330*
2331* This version will only be appropriate for really small sets of single label
2332* hosts. The caller is responsible for ensuring that the RCU read lock is
2333* taken before calling this function.
2334*
2335* Returns the label of the far end or NULL if it's not special.
2336*/
2337static struct smack_known *smack_ipv6host_label(struct sockaddr_in6 *sip)
2338{
2339 struct smk_net6addr *snp;
2340 struct in6_addr *sap = &sip->sin6_addr;
2341 int i;
2342 int found = 0;
2343
2344 /*
2345 * It's local. Don't look for a host label.
2346 */
2347 if (smk_ipv6_localhost(sip))
2348 return NULL;
2349
2350 list_for_each_entry_rcu(snp, &smk_net6addr_list, list) {
2136 /* 2351 /*
2137 * we break after finding the first match because 2352 * we break after finding the first match because
2138 * the list is sorted from longest to shortest mask 2353 * the list is sorted from longest to shortest mask
2139 * so we have found the most specific match 2354 * so we have found the most specific match
2140 */ 2355 */
2141 if ((&snp->smk_host.sin_addr)->s_addr == 2356 for (found = 1, i = 0; i < 8; i++) {
2142 (siap->s_addr & (&snp->smk_mask)->s_addr)) { 2357 /*
2143 /* we have found the special CIPSO option */ 2358 * If the label is NULL the entry has
2144 if (snp->smk_label == &smack_cipso_option) 2359 * been renounced. Ignore it.
2145 return NULL; 2360 */
2146 return snp->smk_label; 2361 if (snp->smk_label == NULL)
2362 continue;
2363 if ((sap->s6_addr16[i] & snp->smk_mask.s6_addr16[i]) !=
2364 snp->smk_host.s6_addr16[i]) {
2365 found = 0;
2366 break;
2367 }
2147 } 2368 }
2369 if (found)
2370 return snp->smk_label;
2371 }
2148 2372
2149 return NULL; 2373 return NULL;
2150} 2374}
2375#endif /* CONFIG_IPV6 */
2151 2376
2152/** 2377/**
2153 * smack_netlabel - Set the secattr on a socket 2378 * smack_netlabel - Set the secattr on a socket
@@ -2211,7 +2436,7 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap)
2211 struct smk_audit_info ad; 2436 struct smk_audit_info ad;
2212 2437
2213 rcu_read_lock(); 2438 rcu_read_lock();
2214 hkp = smack_host_label(sap); 2439 hkp = smack_ipv4host_label(sap);
2215 if (hkp != NULL) { 2440 if (hkp != NULL) {
2216#ifdef CONFIG_AUDIT 2441#ifdef CONFIG_AUDIT
2217 struct lsm_network_audit net; 2442 struct lsm_network_audit net;
@@ -2236,7 +2461,42 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap)
2236 return smack_netlabel(sk, sk_lbl); 2461 return smack_netlabel(sk, sk_lbl);
2237} 2462}
2238 2463
2239#if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) 2464#if IS_ENABLED(CONFIG_IPV6)
2465/**
2466 * smk_ipv6_check - check Smack access
2467 * @subject: subject Smack label
2468 * @object: object Smack label
2469 * @address: address
2470 * @act: the action being taken
2471 *
2472 * Check an IPv6 access
2473 */
2474static int smk_ipv6_check(struct smack_known *subject,
2475 struct smack_known *object,
2476 struct sockaddr_in6 *address, int act)
2477{
2478#ifdef CONFIG_AUDIT
2479 struct lsm_network_audit net;
2480#endif
2481 struct smk_audit_info ad;
2482 int rc;
2483
2484#ifdef CONFIG_AUDIT
2485 smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
2486 ad.a.u.net->family = PF_INET6;
2487 ad.a.u.net->dport = ntohs(address->sin6_port);
2488 if (act == SMK_RECEIVING)
2489 ad.a.u.net->v6info.saddr = address->sin6_addr;
2490 else
2491 ad.a.u.net->v6info.daddr = address->sin6_addr;
2492#endif
2493 rc = smk_access(subject, object, MAY_WRITE, &ad);
2494 rc = smk_bu_note("IPv6 check", subject, object, MAY_WRITE, rc);
2495 return rc;
2496}
2497#endif /* CONFIG_IPV6 */
2498
2499#ifdef SMACK_IPV6_PORT_LABELING
2240/** 2500/**
2241 * smk_ipv6_port_label - Smack port access table management 2501 * smk_ipv6_port_label - Smack port access table management
2242 * @sock: socket 2502 * @sock: socket
@@ -2320,48 +2580,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, 2580static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address,
2321 int act) 2581 int act)
2322{ 2582{
2323 __be16 *bep;
2324 __be32 *be32p;
2325 struct smk_port_label *spp; 2583 struct smk_port_label *spp;
2326 struct socket_smack *ssp = sk->sk_security; 2584 struct socket_smack *ssp = sk->sk_security;
2327 struct smack_known *skp; 2585 struct smack_known *skp = NULL;
2328 unsigned short port = 0; 2586 unsigned short port;
2329 struct smack_known *object; 2587 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 2588
2336 if (act == SMK_RECEIVING) { 2589 if (act == SMK_RECEIVING) {
2337 skp = smack_net_ambient; 2590 skp = smack_ipv6host_label(address);
2338 object = ssp->smk_in; 2591 object = ssp->smk_in;
2339 } else { 2592 } else {
2340 skp = ssp->smk_out; 2593 skp = ssp->smk_out;
2341 object = smack_net_ambient; 2594 object = smack_ipv6host_label(address);
2342 } 2595 }
2343 2596
2344 /* 2597 /*
2345 * Get the IP address and port from the address. 2598 * The other end is a single label host.
2346 */ 2599 */
2347 port = ntohs(address->sin6_port); 2600 if (skp != NULL && object != NULL)
2348 bep = (__be16 *)(&address->sin6_addr); 2601 return smk_ipv6_check(skp, object, address, act);
2349 be32p = (__be32 *)(&address->sin6_addr); 2602 if (skp == NULL)
2603 skp = smack_net_ambient;
2604 if (object == NULL)
2605 object = smack_net_ambient;
2350 2606
2351 /* 2607 /*
2352 * It's remote, so port lookup does no good. 2608 * It's remote, so port lookup does no good.
2353 */ 2609 */
2354 if (be32p[0] || be32p[1] || be32p[2] || bep[6] || ntohs(bep[7]) != 1) 2610 if (!smk_ipv6_localhost(address))
2355 goto auditout; 2611 return smk_ipv6_check(skp, object, address, act);
2356 2612
2357 /* 2613 /*
2358 * It's local so the send check has to have passed. 2614 * It's local so the send check has to have passed.
2359 */ 2615 */
2360 if (act == SMK_RECEIVING) { 2616 if (act == SMK_RECEIVING)
2361 skp = &smack_known_web; 2617 return 0;
2362 goto auditout;
2363 }
2364 2618
2619 port = ntohs(address->sin6_port);
2365 list_for_each_entry(spp, &smk_ipv6_port_list, list) { 2620 list_for_each_entry(spp, &smk_ipv6_port_list, list) {
2366 if (spp->smk_port != port) 2621 if (spp->smk_port != port)
2367 continue; 2622 continue;
@@ -2371,22 +2626,9 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address,
2371 break; 2626 break;
2372 } 2627 }
2373 2628
2374auditout: 2629 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} 2630}
2389#endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ 2631#endif /* SMACK_IPV6_PORT_LABELING */
2390 2632
2391/** 2633/**
2392 * smack_inode_setsecurity - set smack xattrs 2634 * smack_inode_setsecurity - set smack xattrs
@@ -2447,10 +2689,10 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
2447 } else 2689 } else
2448 return -EOPNOTSUPP; 2690 return -EOPNOTSUPP;
2449 2691
2450#if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) 2692#ifdef SMACK_IPV6_PORT_LABELING
2451 if (sock->sk->sk_family == PF_INET6) 2693 if (sock->sk->sk_family == PF_INET6)
2452 smk_ipv6_port_label(sock, NULL); 2694 smk_ipv6_port_label(sock, NULL);
2453#endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ 2695#endif
2454 2696
2455 return 0; 2697 return 0;
2456} 2698}
@@ -2492,7 +2734,7 @@ static int smack_socket_post_create(struct socket *sock, int family,
2492 return smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET); 2734 return smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET);
2493} 2735}
2494 2736
2495#ifndef CONFIG_SECURITY_SMACK_NETFILTER 2737#ifdef SMACK_IPV6_PORT_LABELING
2496/** 2738/**
2497 * smack_socket_bind - record port binding information. 2739 * smack_socket_bind - record port binding information.
2498 * @sock: the socket 2740 * @sock: the socket
@@ -2506,14 +2748,11 @@ static int smack_socket_post_create(struct socket *sock, int family,
2506static int smack_socket_bind(struct socket *sock, struct sockaddr *address, 2748static int smack_socket_bind(struct socket *sock, struct sockaddr *address,
2507 int addrlen) 2749 int addrlen)
2508{ 2750{
2509#if IS_ENABLED(CONFIG_IPV6)
2510 if (sock->sk != NULL && sock->sk->sk_family == PF_INET6) 2751 if (sock->sk != NULL && sock->sk->sk_family == PF_INET6)
2511 smk_ipv6_port_label(sock, address); 2752 smk_ipv6_port_label(sock, address);
2512#endif
2513
2514 return 0; 2753 return 0;
2515} 2754}
2516#endif /* !CONFIG_SECURITY_SMACK_NETFILTER */ 2755#endif /* SMACK_IPV6_PORT_LABELING */
2517 2756
2518/** 2757/**
2519 * smack_socket_connect - connect access check 2758 * smack_socket_connect - connect access check
@@ -2529,6 +2768,13 @@ static int smack_socket_connect(struct socket *sock, struct sockaddr *sap,
2529 int addrlen) 2768 int addrlen)
2530{ 2769{
2531 int rc = 0; 2770 int rc = 0;
2771#if IS_ENABLED(CONFIG_IPV6)
2772 struct sockaddr_in6 *sip = (struct sockaddr_in6 *)sap;
2773#endif
2774#ifdef SMACK_IPV6_SECMARK_LABELING
2775 struct smack_known *rsp;
2776 struct socket_smack *ssp = sock->sk->sk_security;
2777#endif
2532 2778
2533 if (sock->sk == NULL) 2779 if (sock->sk == NULL)
2534 return 0; 2780 return 0;
@@ -2542,10 +2788,15 @@ static int smack_socket_connect(struct socket *sock, struct sockaddr *sap,
2542 case PF_INET6: 2788 case PF_INET6:
2543 if (addrlen < sizeof(struct sockaddr_in6)) 2789 if (addrlen < sizeof(struct sockaddr_in6))
2544 return -EINVAL; 2790 return -EINVAL;
2545#if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) 2791#ifdef SMACK_IPV6_SECMARK_LABELING
2546 rc = smk_ipv6_port_check(sock->sk, (struct sockaddr_in6 *)sap, 2792 rsp = smack_ipv6host_label(sip);
2793 if (rsp != NULL)
2794 rc = smk_ipv6_check(ssp->smk_out, rsp, sip,
2547 SMK_CONNECTING); 2795 SMK_CONNECTING);
2548#endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ 2796#endif
2797#ifdef SMACK_IPV6_PORT_LABELING
2798 rc = smk_ipv6_port_check(sock->sk, sip, SMK_CONNECTING);
2799#endif
2549 break; 2800 break;
2550 } 2801 }
2551 return rc; 2802 return rc;
@@ -3431,9 +3682,13 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg,
3431 int size) 3682 int size)
3432{ 3683{
3433 struct sockaddr_in *sip = (struct sockaddr_in *) msg->msg_name; 3684 struct sockaddr_in *sip = (struct sockaddr_in *) msg->msg_name;
3434#if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) 3685#if IS_ENABLED(CONFIG_IPV6)
3435 struct sockaddr_in6 *sap = (struct sockaddr_in6 *) msg->msg_name; 3686 struct sockaddr_in6 *sap = (struct sockaddr_in6 *) msg->msg_name;
3436#endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ 3687#endif
3688#ifdef SMACK_IPV6_SECMARK_LABELING
3689 struct socket_smack *ssp = sock->sk->sk_security;
3690 struct smack_known *rsp;
3691#endif
3437 int rc = 0; 3692 int rc = 0;
3438 3693
3439 /* 3694 /*
@@ -3447,9 +3702,15 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg,
3447 rc = smack_netlabel_send(sock->sk, sip); 3702 rc = smack_netlabel_send(sock->sk, sip);
3448 break; 3703 break;
3449 case AF_INET6: 3704 case AF_INET6:
3450#if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) 3705#ifdef SMACK_IPV6_SECMARK_LABELING
3706 rsp = smack_ipv6host_label(sap);
3707 if (rsp != NULL)
3708 rc = smk_ipv6_check(ssp->smk_out, rsp, sap,
3709 SMK_CONNECTING);
3710#endif
3711#ifdef SMACK_IPV6_PORT_LABELING
3451 rc = smk_ipv6_port_check(sock->sk, sap, SMK_SENDING); 3712 rc = smk_ipv6_port_check(sock->sk, sap, SMK_SENDING);
3452#endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ 3713#endif
3453 break; 3714 break;
3454 } 3715 }
3455 return rc; 3716 return rc;
@@ -3663,10 +3924,12 @@ access_check:
3663 proto = smk_skb_to_addr_ipv6(skb, &sadd); 3924 proto = smk_skb_to_addr_ipv6(skb, &sadd);
3664 if (proto != IPPROTO_UDP && proto != IPPROTO_TCP) 3925 if (proto != IPPROTO_UDP && proto != IPPROTO_TCP)
3665 break; 3926 break;
3666#ifdef CONFIG_SECURITY_SMACK_NETFILTER 3927#ifdef SMACK_IPV6_SECMARK_LABELING
3667 if (skb && skb->secmark != 0) 3928 if (skb && skb->secmark != 0)
3668 skp = smack_from_secid(skb->secmark); 3929 skp = smack_from_secid(skb->secmark);
3669 else 3930 else
3931 skp = smack_ipv6host_label(&sadd);
3932 if (skp == NULL)
3670 skp = smack_net_ambient; 3933 skp = smack_net_ambient;
3671#ifdef CONFIG_AUDIT 3934#ifdef CONFIG_AUDIT
3672 smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); 3935 smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
@@ -3677,9 +3940,10 @@ access_check:
3677 rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad); 3940 rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad);
3678 rc = smk_bu_note("IPv6 delivery", skp, ssp->smk_in, 3941 rc = smk_bu_note("IPv6 delivery", skp, ssp->smk_in,
3679 MAY_WRITE, rc); 3942 MAY_WRITE, rc);
3680#else /* CONFIG_SECURITY_SMACK_NETFILTER */ 3943#endif /* SMACK_IPV6_SECMARK_LABELING */
3944#ifdef SMACK_IPV6_PORT_LABELING
3681 rc = smk_ipv6_port_check(sk, &sadd, SMK_RECEIVING); 3945 rc = smk_ipv6_port_check(sk, &sadd, SMK_RECEIVING);
3682#endif /* CONFIG_SECURITY_SMACK_NETFILTER */ 3946#endif /* SMACK_IPV6_PORT_LABELING */
3683 break; 3947 break;
3684#endif /* CONFIG_IPV6 */ 3948#endif /* CONFIG_IPV6 */
3685 } 3949 }
@@ -3777,13 +4041,11 @@ static int smack_socket_getpeersec_dgram(struct socket *sock,
3777 } 4041 }
3778 netlbl_secattr_destroy(&secattr); 4042 netlbl_secattr_destroy(&secattr);
3779 break; 4043 break;
3780#if IS_ENABLED(CONFIG_IPV6)
3781 case PF_INET6: 4044 case PF_INET6:
3782#ifdef CONFIG_SECURITY_SMACK_NETFILTER 4045#ifdef SMACK_IPV6_SECMARK_LABELING
3783 s = skb->secmark; 4046 s = skb->secmark;
3784#endif /* CONFIG_SECURITY_SMACK_NETFILTER */ 4047#endif
3785 break; 4048 break;
3786#endif /* CONFIG_IPV6 */
3787 } 4049 }
3788 *secid = s; 4050 *secid = s;
3789 if (s == 0) 4051 if (s == 0)
@@ -3906,7 +4168,7 @@ access_check:
3906 hdr = ip_hdr(skb); 4168 hdr = ip_hdr(skb);
3907 addr.sin_addr.s_addr = hdr->saddr; 4169 addr.sin_addr.s_addr = hdr->saddr;
3908 rcu_read_lock(); 4170 rcu_read_lock();
3909 hskp = smack_host_label(&addr); 4171 hskp = smack_ipv4host_label(&addr);
3910 rcu_read_unlock(); 4172 rcu_read_unlock();
3911 4173
3912 if (hskp == NULL) 4174 if (hskp == NULL)
@@ -4254,7 +4516,7 @@ static int smack_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
4254 return 0; 4516 return 0;
4255} 4517}
4256 4518
4257struct security_hook_list smack_hooks[] = { 4519static struct security_hook_list smack_hooks[] = {
4258 LSM_HOOK_INIT(ptrace_access_check, smack_ptrace_access_check), 4520 LSM_HOOK_INIT(ptrace_access_check, smack_ptrace_access_check),
4259 LSM_HOOK_INIT(ptrace_traceme, smack_ptrace_traceme), 4521 LSM_HOOK_INIT(ptrace_traceme, smack_ptrace_traceme),
4260 LSM_HOOK_INIT(syslog, smack_syslog), 4522 LSM_HOOK_INIT(syslog, smack_syslog),
@@ -4264,6 +4526,8 @@ struct security_hook_list smack_hooks[] = {
4264 LSM_HOOK_INIT(sb_copy_data, smack_sb_copy_data), 4526 LSM_HOOK_INIT(sb_copy_data, smack_sb_copy_data),
4265 LSM_HOOK_INIT(sb_kern_mount, smack_sb_kern_mount), 4527 LSM_HOOK_INIT(sb_kern_mount, smack_sb_kern_mount),
4266 LSM_HOOK_INIT(sb_statfs, smack_sb_statfs), 4528 LSM_HOOK_INIT(sb_statfs, smack_sb_statfs),
4529 LSM_HOOK_INIT(sb_set_mnt_opts, smack_set_mnt_opts),
4530 LSM_HOOK_INIT(sb_parse_opts_str, smack_parse_opts_str),
4267 4531
4268 LSM_HOOK_INIT(bprm_set_creds, smack_bprm_set_creds), 4532 LSM_HOOK_INIT(bprm_set_creds, smack_bprm_set_creds),
4269 LSM_HOOK_INIT(bprm_committing_creds, smack_bprm_committing_creds), 4533 LSM_HOOK_INIT(bprm_committing_creds, smack_bprm_committing_creds),
@@ -4356,9 +4620,9 @@ struct security_hook_list smack_hooks[] = {
4356 LSM_HOOK_INIT(unix_may_send, smack_unix_may_send), 4620 LSM_HOOK_INIT(unix_may_send, smack_unix_may_send),
4357 4621
4358 LSM_HOOK_INIT(socket_post_create, smack_socket_post_create), 4622 LSM_HOOK_INIT(socket_post_create, smack_socket_post_create),
4359#ifndef CONFIG_SECURITY_SMACK_NETFILTER 4623#ifdef SMACK_IPV6_PORT_LABELING
4360 LSM_HOOK_INIT(socket_bind, smack_socket_bind), 4624 LSM_HOOK_INIT(socket_bind, smack_socket_bind),
4361#endif /* CONFIG_SECURITY_SMACK_NETFILTER */ 4625#endif
4362 LSM_HOOK_INIT(socket_connect, smack_socket_connect), 4626 LSM_HOOK_INIT(socket_connect, smack_socket_connect),
4363 LSM_HOOK_INIT(socket_sendmsg, smack_socket_sendmsg), 4627 LSM_HOOK_INIT(socket_sendmsg, smack_socket_sendmsg),
4364 LSM_HOOK_INIT(socket_sock_rcv_skb, smack_socket_sock_rcv_skb), 4628 LSM_HOOK_INIT(socket_sock_rcv_skb, smack_socket_sock_rcv_skb),
@@ -4453,7 +4717,16 @@ static __init int smack_init(void)
4453 return -ENOMEM; 4717 return -ENOMEM;
4454 } 4718 }
4455 4719
4456 printk(KERN_INFO "Smack: Initializing.\n"); 4720 pr_info("Smack: Initializing.\n");
4721#ifdef CONFIG_SECURITY_SMACK_NETFILTER
4722 pr_info("Smack: Netfilter enabled.\n");
4723#endif
4724#ifdef SMACK_IPV6_PORT_LABELING
4725 pr_info("Smack: IPv6 port labeling enabled.\n");
4726#endif
4727#ifdef SMACK_IPV6_SECMARK_LABELING
4728 pr_info("Smack: IPv6 Netfilter enabled.\n");
4729#endif
4457 4730
4458 /* 4731 /*
4459 * Set the security state for the initial task. 4732 * 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 };