hc
2024-09-20 cf4ce59b3b70238352c7f1729f0f7223214828ad
kernel/security/smack/smack_lsm.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Simplified MAC Kernel (smack) security module
34 *
....@@ -12,10 +13,6 @@
1213 * Paul Moore <paul@paul-moore.com>
1314 * Copyright (C) 2010 Nokia Corporation
1415 * Copyright (C) 2011 Intel Corporation.
15
- *
16
- * This program is free software; you can redistribute it and/or modify
17
- * it under the terms of the GNU General Public License version 2,
18
- * as published by the Free Software Foundation.
1916 */
2017
2118 #include <linux/xattr.h>
....@@ -31,7 +28,6 @@
3128 #include <linux/icmpv6.h>
3229 #include <linux/slab.h>
3330 #include <linux/mutex.h>
34
-#include <linux/pipe_fs_i.h>
3531 #include <net/cipso_ipv4.h>
3632 #include <net/ip.h>
3733 #include <net/ipv6.h>
....@@ -43,6 +39,9 @@
4339 #include <linux/shm.h>
4440 #include <linux/binfmts.h>
4541 #include <linux/parser.h>
42
+#include <linux/fs_context.h>
43
+#include <linux/fs_parser.h>
44
+#include <linux/watch_queue.h>
4645 #include "smack.h"
4746
4847 #define TRANS_TRUE "TRUE"
....@@ -52,21 +51,37 @@
5251 #define SMK_RECEIVING 1
5352 #define SMK_SENDING 2
5453
55
-#ifdef SMACK_IPV6_PORT_LABELING
56
-DEFINE_MUTEX(smack_ipv6_lock);
54
+static DEFINE_MUTEX(smack_ipv6_lock);
5755 static LIST_HEAD(smk_ipv6_port_list);
58
-#endif
59
-static struct kmem_cache *smack_inode_cache;
56
+struct kmem_cache *smack_rule_cache;
6057 int smack_enabled;
6158
62
-static const match_table_t smk_mount_tokens = {
63
- {Opt_fsdefault, SMK_FSDEFAULT "%s"},
64
- {Opt_fsfloor, SMK_FSFLOOR "%s"},
65
- {Opt_fshat, SMK_FSHAT "%s"},
66
- {Opt_fsroot, SMK_FSROOT "%s"},
67
- {Opt_fstransmute, SMK_FSTRANS "%s"},
68
- {Opt_error, NULL},
59
+#define A(s) {"smack"#s, sizeof("smack"#s) - 1, Opt_##s}
60
+static struct {
61
+ const char *name;
62
+ int len;
63
+ int opt;
64
+} smk_mount_opts[] = {
65
+ {"smackfsdef", sizeof("smackfsdef") - 1, Opt_fsdefault},
66
+ A(fsdefault), A(fsfloor), A(fshat), A(fsroot), A(fstransmute)
6967 };
68
+#undef A
69
+
70
+static int match_opt_prefix(char *s, int l, char **arg)
71
+{
72
+ int i;
73
+
74
+ for (i = 0; i < ARRAY_SIZE(smk_mount_opts); i++) {
75
+ size_t len = smk_mount_opts[i].len;
76
+ if (len > l || memcmp(s, smk_mount_opts[i].name, len))
77
+ continue;
78
+ if (len == l || s[len] != '=')
79
+ continue;
80
+ *arg = s + len + 1;
81
+ return smk_mount_opts[i].opt;
82
+ }
83
+ return Opt_error;
84
+}
7085
7186 #ifdef CONFIG_SECURITY_SMACK_BRINGUP
7287 static char *smk_bu_mess[] = {
....@@ -122,7 +137,7 @@
122137 static int smk_bu_current(char *note, struct smack_known *oskp,
123138 int mode, int rc)
124139 {
125
- struct task_smack *tsp = current_security();
140
+ struct task_smack *tsp = smack_cred(current_cred());
126141 char acc[SMK_NUM_ACCESS_TYPE + 1];
127142
128143 if (rc <= 0)
....@@ -143,7 +158,7 @@
143158 #ifdef CONFIG_SECURITY_SMACK_BRINGUP
144159 static int smk_bu_task(struct task_struct *otp, int mode, int rc)
145160 {
146
- struct task_smack *tsp = current_security();
161
+ struct task_smack *tsp = smack_cred(current_cred());
147162 struct smack_known *smk_task = smk_of_task_struct(otp);
148163 char acc[SMK_NUM_ACCESS_TYPE + 1];
149164
....@@ -165,8 +180,8 @@
165180 #ifdef CONFIG_SECURITY_SMACK_BRINGUP
166181 static int smk_bu_inode(struct inode *inode, int mode, int rc)
167182 {
168
- struct task_smack *tsp = current_security();
169
- struct inode_smack *isp = inode->i_security;
183
+ struct task_smack *tsp = smack_cred(current_cred());
184
+ struct inode_smack *isp = smack_inode(inode);
170185 char acc[SMK_NUM_ACCESS_TYPE + 1];
171186
172187 if (isp->smk_flags & SMK_INODE_IMPURE)
....@@ -195,10 +210,10 @@
195210 #ifdef CONFIG_SECURITY_SMACK_BRINGUP
196211 static int smk_bu_file(struct file *file, int mode, int rc)
197212 {
198
- struct task_smack *tsp = current_security();
213
+ struct task_smack *tsp = smack_cred(current_cred());
199214 struct smack_known *sskp = tsp->smk_task;
200215 struct inode *inode = file_inode(file);
201
- struct inode_smack *isp = inode->i_security;
216
+ struct inode_smack *isp = smack_inode(inode);
202217 char acc[SMK_NUM_ACCESS_TYPE + 1];
203218
204219 if (isp->smk_flags & SMK_INODE_IMPURE)
....@@ -225,10 +240,10 @@
225240 static int smk_bu_credfile(const struct cred *cred, struct file *file,
226241 int mode, int rc)
227242 {
228
- struct task_smack *tsp = cred->security;
243
+ struct task_smack *tsp = smack_cred(cred);
229244 struct smack_known *sskp = tsp->smk_task;
230245 struct inode *inode = file_inode(file);
231
- struct inode_smack *isp = inode->i_security;
246
+ struct inode_smack *isp = smack_inode(inode);
232247 char acc[SMK_NUM_ACCESS_TYPE + 1];
233248
234249 if (isp->smk_flags & SMK_INODE_IMPURE)
....@@ -274,7 +289,8 @@
274289 if (buffer == NULL)
275290 return ERR_PTR(-ENOMEM);
276291
277
- rc = __vfs_getxattr(dp, ip, name, buffer, SMK_LONGLABEL);
292
+ rc = __vfs_getxattr(dp, ip, name, buffer, SMK_LONGLABEL,
293
+ XATTR_NOSECURITY);
278294 if (rc < 0)
279295 skp = ERR_PTR(rc);
280296 else if (rc == 0)
....@@ -288,50 +304,34 @@
288304 }
289305
290306 /**
291
- * new_inode_smack - allocate an inode security blob
307
+ * init_inode_smack - initialize an inode security blob
308
+ * @inode: inode to extract the info from
292309 * @skp: a pointer to the Smack label entry to use in the blob
293310 *
294
- * Returns the new blob or NULL if there's no memory available
295311 */
296
-static struct inode_smack *new_inode_smack(struct smack_known *skp)
312
+static void init_inode_smack(struct inode *inode, struct smack_known *skp)
297313 {
298
- struct inode_smack *isp;
299
-
300
- isp = kmem_cache_zalloc(smack_inode_cache, GFP_NOFS);
301
- if (isp == NULL)
302
- return NULL;
314
+ struct inode_smack *isp = smack_inode(inode);
303315
304316 isp->smk_inode = skp;
305317 isp->smk_flags = 0;
306
- mutex_init(&isp->smk_lock);
307
-
308
- return isp;
309318 }
310319
311320 /**
312
- * new_task_smack - allocate a task security blob
321
+ * init_task_smack - initialize a task security blob
322
+ * @tsp: blob to initialize
313323 * @task: a pointer to the Smack label for the running task
314324 * @forked: a pointer to the Smack label for the forked task
315
- * @gfp: type of the memory for the allocation
316325 *
317
- * Returns the new blob or NULL if there's no memory available
318326 */
319
-static struct task_smack *new_task_smack(struct smack_known *task,
320
- struct smack_known *forked, gfp_t gfp)
327
+static void init_task_smack(struct task_smack *tsp, struct smack_known *task,
328
+ struct smack_known *forked)
321329 {
322
- struct task_smack *tsp;
323
-
324
- tsp = kzalloc(sizeof(struct task_smack), gfp);
325
- if (tsp == NULL)
326
- return NULL;
327
-
328330 tsp->smk_task = task;
329331 tsp->smk_forked = forked;
330332 INIT_LIST_HEAD(&tsp->smk_rules);
331333 INIT_LIST_HEAD(&tsp->smk_relabel);
332334 mutex_init(&tsp->smk_rules_lock);
333
-
334
- return tsp;
335335 }
336336
337337 /**
....@@ -350,7 +350,7 @@
350350 int rc = 0;
351351
352352 list_for_each_entry_rcu(orp, ohead, list) {
353
- nrp = kzalloc(sizeof(struct smack_rule), gfp);
353
+ nrp = kmem_cache_zalloc(smack_rule_cache, gfp);
354354 if (nrp == NULL) {
355355 rc = -ENOMEM;
356356 break;
....@@ -431,7 +431,7 @@
431431
432432 rcu_read_lock();
433433 tracercred = __task_cred(tracer);
434
- tsp = tracercred->security;
434
+ tsp = smack_cred(tracercred);
435435 tracer_known = smk_of_task(tsp);
436436
437437 if ((mode & PTRACE_MODE_ATTACH) &&
....@@ -498,7 +498,7 @@
498498 int rc;
499499 struct smack_known *skp;
500500
501
- skp = smk_of_task(current_security());
501
+ skp = smk_of_task(smack_cred(current_cred()));
502502
503503 rc = smk_ptrace_rule_check(ptp, skp, PTRACE_MODE_ATTACH, __func__);
504504 return rc;
....@@ -506,7 +506,7 @@
506506
507507 /**
508508 * smack_syslog - Smack approval on syslog
509
- * @type: message type
509
+ * @typefrom_file: unused
510510 *
511511 * Returns 0 on success, error code otherwise.
512512 */
....@@ -523,7 +523,6 @@
523523
524524 return rc;
525525 }
526
-
527526
528527 /*
529528 * Superblock Hooks.
....@@ -567,181 +566,198 @@
567566 sb->s_security = NULL;
568567 }
569568
570
-/**
571
- * smack_sb_copy_data - copy mount options data for processing
572
- * @orig: where to start
573
- * @smackopts: mount options string
574
- *
575
- * Returns 0 on success or -ENOMEM on error.
576
- *
577
- * Copy the Smack specific mount options out of the mount
578
- * options list.
579
- */
580
-static int smack_sb_copy_data(char *orig, char *smackopts)
569
+struct smack_mnt_opts {
570
+ const char *fsdefault, *fsfloor, *fshat, *fsroot, *fstransmute;
571
+};
572
+
573
+static void smack_free_mnt_opts(void *mnt_opts)
581574 {
582
- char *cp, *commap, *otheropts, *dp;
583
-
584
- otheropts = (char *)get_zeroed_page(GFP_KERNEL);
585
- if (otheropts == NULL)
586
- return -ENOMEM;
587
-
588
- for (cp = orig, commap = orig; commap != NULL; cp = commap + 1) {
589
- if (strstr(cp, SMK_FSDEFAULT) == cp)
590
- dp = smackopts;
591
- else if (strstr(cp, SMK_FSFLOOR) == cp)
592
- dp = smackopts;
593
- else if (strstr(cp, SMK_FSHAT) == cp)
594
- dp = smackopts;
595
- else if (strstr(cp, SMK_FSROOT) == cp)
596
- dp = smackopts;
597
- else if (strstr(cp, SMK_FSTRANS) == cp)
598
- dp = smackopts;
599
- else
600
- dp = otheropts;
601
-
602
- commap = strchr(cp, ',');
603
- if (commap != NULL)
604
- *commap = '\0';
605
-
606
- if (*dp != '\0')
607
- strcat(dp, ",");
608
- strcat(dp, cp);
609
- }
610
-
611
- strcpy(orig, otheropts);
612
- free_page((unsigned long)otheropts);
613
-
614
- return 0;
575
+ struct smack_mnt_opts *opts = mnt_opts;
576
+ kfree(opts->fsdefault);
577
+ kfree(opts->fsfloor);
578
+ kfree(opts->fshat);
579
+ kfree(opts->fsroot);
580
+ kfree(opts->fstransmute);
581
+ kfree(opts);
615582 }
616583
617
-/**
618
- * smack_parse_opts_str - parse Smack specific mount options
619
- * @options: mount options string
620
- * @opts: where to store converted mount opts
621
- *
622
- * Returns 0 on success or -ENOMEM on error.
623
- *
624
- * converts Smack specific mount options to generic security option format
625
- */
626
-static int smack_parse_opts_str(char *options,
627
- struct security_mnt_opts *opts)
584
+static int smack_add_opt(int token, const char *s, void **mnt_opts)
628585 {
629
- char *p;
630
- char *fsdefault = NULL;
631
- char *fsfloor = NULL;
632
- char *fshat = NULL;
633
- char *fsroot = NULL;
634
- char *fstransmute = NULL;
635
- int rc = -ENOMEM;
636
- int num_mnt_opts = 0;
637
- int token;
586
+ struct smack_mnt_opts *opts = *mnt_opts;
638587
639
- opts->num_mnt_opts = 0;
640
-
641
- if (!options)
642
- return 0;
643
-
644
- while ((p = strsep(&options, ",")) != NULL) {
645
- substring_t args[MAX_OPT_ARGS];
646
-
647
- if (!*p)
648
- continue;
649
-
650
- token = match_token(p, smk_mount_tokens, args);
651
-
652
- switch (token) {
653
- case Opt_fsdefault:
654
- if (fsdefault)
655
- goto out_opt_err;
656
- fsdefault = match_strdup(&args[0]);
657
- if (!fsdefault)
658
- goto out_err;
659
- break;
660
- case Opt_fsfloor:
661
- if (fsfloor)
662
- goto out_opt_err;
663
- fsfloor = match_strdup(&args[0]);
664
- if (!fsfloor)
665
- goto out_err;
666
- break;
667
- case Opt_fshat:
668
- if (fshat)
669
- goto out_opt_err;
670
- fshat = match_strdup(&args[0]);
671
- if (!fshat)
672
- goto out_err;
673
- break;
674
- case Opt_fsroot:
675
- if (fsroot)
676
- goto out_opt_err;
677
- fsroot = match_strdup(&args[0]);
678
- if (!fsroot)
679
- goto out_err;
680
- break;
681
- case Opt_fstransmute:
682
- if (fstransmute)
683
- goto out_opt_err;
684
- fstransmute = match_strdup(&args[0]);
685
- if (!fstransmute)
686
- goto out_err;
687
- break;
688
- default:
689
- rc = -EINVAL;
690
- pr_warn("Smack: unknown mount option\n");
691
- goto out_err;
692
- }
588
+ if (!opts) {
589
+ opts = kzalloc(sizeof(struct smack_mnt_opts), GFP_KERNEL);
590
+ if (!opts)
591
+ return -ENOMEM;
592
+ *mnt_opts = opts;
693593 }
594
+ if (!s)
595
+ return -ENOMEM;
694596
695
- opts->mnt_opts = kcalloc(NUM_SMK_MNT_OPTS, sizeof(char *), GFP_KERNEL);
696
- if (!opts->mnt_opts)
697
- goto out_err;
698
-
699
- opts->mnt_opts_flags = kcalloc(NUM_SMK_MNT_OPTS, sizeof(int),
700
- GFP_KERNEL);
701
- if (!opts->mnt_opts_flags)
702
- goto out_err;
703
-
704
- if (fsdefault) {
705
- opts->mnt_opts[num_mnt_opts] = fsdefault;
706
- opts->mnt_opts_flags[num_mnt_opts++] = FSDEFAULT_MNT;
597
+ switch (token) {
598
+ case Opt_fsdefault:
599
+ if (opts->fsdefault)
600
+ goto out_opt_err;
601
+ opts->fsdefault = s;
602
+ break;
603
+ case Opt_fsfloor:
604
+ if (opts->fsfloor)
605
+ goto out_opt_err;
606
+ opts->fsfloor = s;
607
+ break;
608
+ case Opt_fshat:
609
+ if (opts->fshat)
610
+ goto out_opt_err;
611
+ opts->fshat = s;
612
+ break;
613
+ case Opt_fsroot:
614
+ if (opts->fsroot)
615
+ goto out_opt_err;
616
+ opts->fsroot = s;
617
+ break;
618
+ case Opt_fstransmute:
619
+ if (opts->fstransmute)
620
+ goto out_opt_err;
621
+ opts->fstransmute = s;
622
+ break;
707623 }
708
- if (fsfloor) {
709
- opts->mnt_opts[num_mnt_opts] = fsfloor;
710
- opts->mnt_opts_flags[num_mnt_opts++] = FSFLOOR_MNT;
711
- }
712
- if (fshat) {
713
- opts->mnt_opts[num_mnt_opts] = fshat;
714
- opts->mnt_opts_flags[num_mnt_opts++] = FSHAT_MNT;
715
- }
716
- if (fsroot) {
717
- opts->mnt_opts[num_mnt_opts] = fsroot;
718
- opts->mnt_opts_flags[num_mnt_opts++] = FSROOT_MNT;
719
- }
720
- if (fstransmute) {
721
- opts->mnt_opts[num_mnt_opts] = fstransmute;
722
- opts->mnt_opts_flags[num_mnt_opts++] = FSTRANS_MNT;
723
- }
724
-
725
- opts->num_mnt_opts = num_mnt_opts;
726624 return 0;
727625
728626 out_opt_err:
729
- rc = -EINVAL;
730627 pr_warn("Smack: duplicate mount options\n");
628
+ return -EINVAL;
629
+}
731630
732
-out_err:
733
- kfree(fsdefault);
734
- kfree(fsfloor);
735
- kfree(fshat);
736
- kfree(fsroot);
737
- kfree(fstransmute);
631
+/**
632
+ * smack_fs_context_dup - Duplicate the security data on fs_context duplication
633
+ * @fc: The new filesystem context.
634
+ * @src_fc: The source filesystem context being duplicated.
635
+ *
636
+ * Returns 0 on success or -ENOMEM on error.
637
+ */
638
+static int smack_fs_context_dup(struct fs_context *fc,
639
+ struct fs_context *src_fc)
640
+{
641
+ struct smack_mnt_opts *dst, *src = src_fc->security;
642
+
643
+ if (!src)
644
+ return 0;
645
+
646
+ fc->security = kzalloc(sizeof(struct smack_mnt_opts), GFP_KERNEL);
647
+ if (!fc->security)
648
+ return -ENOMEM;
649
+ dst = fc->security;
650
+
651
+ if (src->fsdefault) {
652
+ dst->fsdefault = kstrdup(src->fsdefault, GFP_KERNEL);
653
+ if (!dst->fsdefault)
654
+ return -ENOMEM;
655
+ }
656
+ if (src->fsfloor) {
657
+ dst->fsfloor = kstrdup(src->fsfloor, GFP_KERNEL);
658
+ if (!dst->fsfloor)
659
+ return -ENOMEM;
660
+ }
661
+ if (src->fshat) {
662
+ dst->fshat = kstrdup(src->fshat, GFP_KERNEL);
663
+ if (!dst->fshat)
664
+ return -ENOMEM;
665
+ }
666
+ if (src->fsroot) {
667
+ dst->fsroot = kstrdup(src->fsroot, GFP_KERNEL);
668
+ if (!dst->fsroot)
669
+ return -ENOMEM;
670
+ }
671
+ if (src->fstransmute) {
672
+ dst->fstransmute = kstrdup(src->fstransmute, GFP_KERNEL);
673
+ if (!dst->fstransmute)
674
+ return -ENOMEM;
675
+ }
676
+ return 0;
677
+}
678
+
679
+static const struct fs_parameter_spec smack_fs_parameters[] = {
680
+ fsparam_string("smackfsdef", Opt_fsdefault),
681
+ fsparam_string("smackfsdefault", Opt_fsdefault),
682
+ fsparam_string("smackfsfloor", Opt_fsfloor),
683
+ fsparam_string("smackfshat", Opt_fshat),
684
+ fsparam_string("smackfsroot", Opt_fsroot),
685
+ fsparam_string("smackfstransmute", Opt_fstransmute),
686
+ {}
687
+};
688
+
689
+/**
690
+ * smack_fs_context_parse_param - Parse a single mount parameter
691
+ * @fc: The new filesystem context being constructed.
692
+ * @param: The parameter.
693
+ *
694
+ * Returns 0 on success, -ENOPARAM to pass the parameter on or anything else on
695
+ * error.
696
+ */
697
+static int smack_fs_context_parse_param(struct fs_context *fc,
698
+ struct fs_parameter *param)
699
+{
700
+ struct fs_parse_result result;
701
+ int opt, rc;
702
+
703
+ opt = fs_parse(fc, smack_fs_parameters, param, &result);
704
+ if (opt < 0)
705
+ return opt;
706
+
707
+ rc = smack_add_opt(opt, param->string, &fc->security);
708
+ if (!rc)
709
+ param->string = NULL;
738710 return rc;
711
+}
712
+
713
+static int smack_sb_eat_lsm_opts(char *options, void **mnt_opts)
714
+{
715
+ char *from = options, *to = options;
716
+ bool first = true;
717
+
718
+ while (1) {
719
+ char *next = strchr(from, ',');
720
+ int token, len, rc;
721
+ char *arg = NULL;
722
+
723
+ if (next)
724
+ len = next - from;
725
+ else
726
+ len = strlen(from);
727
+
728
+ token = match_opt_prefix(from, len, &arg);
729
+ if (token != Opt_error) {
730
+ arg = kmemdup_nul(arg, from + len - arg, GFP_KERNEL);
731
+ rc = smack_add_opt(token, arg, mnt_opts);
732
+ if (unlikely(rc)) {
733
+ kfree(arg);
734
+ if (*mnt_opts)
735
+ smack_free_mnt_opts(*mnt_opts);
736
+ *mnt_opts = NULL;
737
+ return rc;
738
+ }
739
+ } else {
740
+ if (!first) { // copy with preceding comma
741
+ from--;
742
+ len++;
743
+ }
744
+ if (to != from)
745
+ memmove(to, from, len);
746
+ to += len;
747
+ first = false;
748
+ }
749
+ if (!from[len])
750
+ break;
751
+ from += len + 1;
752
+ }
753
+ *to = '\0';
754
+ return 0;
739755 }
740756
741757 /**
742758 * smack_set_mnt_opts - set Smack specific mount options
743759 * @sb: the file system superblock
744
- * @opts: Smack mount options
760
+ * @mnt_opts: Smack mount options
745761 * @kern_flags: mount option from kernel space or user space
746762 * @set_kern_flags: where to store converted mount opts
747763 *
....@@ -751,7 +767,7 @@
751767 * labels.
752768 */
753769 static int smack_set_mnt_opts(struct super_block *sb,
754
- struct security_mnt_opts *opts,
770
+ void *mnt_opts,
755771 unsigned long kern_flags,
756772 unsigned long *set_kern_flags)
757773 {
....@@ -760,18 +776,24 @@
760776 struct superblock_smack *sp = sb->s_security;
761777 struct inode_smack *isp;
762778 struct smack_known *skp;
763
- int i;
764
- int num_opts = opts->num_mnt_opts;
765
- int transmute = 0;
779
+ struct smack_mnt_opts *opts = mnt_opts;
780
+ bool transmute = false;
766781
767782 if (sp->smk_flags & SMK_SB_INITIALIZED)
768783 return 0;
784
+
785
+ if (inode->i_security == NULL) {
786
+ int rc = lsm_inode_alloc(inode);
787
+
788
+ if (rc)
789
+ return rc;
790
+ }
769791
770792 if (!smack_privileged(CAP_MAC_ADMIN)) {
771793 /*
772794 * Unprivileged mounts don't get to specify Smack values.
773795 */
774
- if (num_opts)
796
+ if (opts)
775797 return -EPERM;
776798 /*
777799 * Unprivileged mounts get root and default from the caller.
....@@ -787,98 +809,58 @@
787809 if (sb->s_user_ns != &init_user_ns &&
788810 sb->s_magic != SYSFS_MAGIC && sb->s_magic != TMPFS_MAGIC &&
789811 sb->s_magic != RAMFS_MAGIC) {
790
- transmute = 1;
812
+ transmute = true;
791813 sp->smk_flags |= SMK_SB_UNTRUSTED;
792814 }
793815 }
794816
795817 sp->smk_flags |= SMK_SB_INITIALIZED;
796818
797
- for (i = 0; i < num_opts; i++) {
798
- switch (opts->mnt_opts_flags[i]) {
799
- case FSDEFAULT_MNT:
800
- skp = smk_import_entry(opts->mnt_opts[i], 0);
819
+ if (opts) {
820
+ if (opts->fsdefault) {
821
+ skp = smk_import_entry(opts->fsdefault, 0);
801822 if (IS_ERR(skp))
802823 return PTR_ERR(skp);
803824 sp->smk_default = skp;
804
- break;
805
- case FSFLOOR_MNT:
806
- skp = smk_import_entry(opts->mnt_opts[i], 0);
825
+ }
826
+ if (opts->fsfloor) {
827
+ skp = smk_import_entry(opts->fsfloor, 0);
807828 if (IS_ERR(skp))
808829 return PTR_ERR(skp);
809830 sp->smk_floor = skp;
810
- break;
811
- case FSHAT_MNT:
812
- skp = smk_import_entry(opts->mnt_opts[i], 0);
831
+ }
832
+ if (opts->fshat) {
833
+ skp = smk_import_entry(opts->fshat, 0);
813834 if (IS_ERR(skp))
814835 return PTR_ERR(skp);
815836 sp->smk_hat = skp;
816
- break;
817
- case FSROOT_MNT:
818
- skp = smk_import_entry(opts->mnt_opts[i], 0);
837
+ }
838
+ if (opts->fsroot) {
839
+ skp = smk_import_entry(opts->fsroot, 0);
819840 if (IS_ERR(skp))
820841 return PTR_ERR(skp);
821842 sp->smk_root = skp;
822
- break;
823
- case FSTRANS_MNT:
824
- skp = smk_import_entry(opts->mnt_opts[i], 0);
843
+ }
844
+ if (opts->fstransmute) {
845
+ skp = smk_import_entry(opts->fstransmute, 0);
825846 if (IS_ERR(skp))
826847 return PTR_ERR(skp);
827848 sp->smk_root = skp;
828
- transmute = 1;
829
- break;
830
- default:
831
- break;
849
+ transmute = true;
832850 }
833851 }
834852
835853 /*
836854 * Initialize the root inode.
837855 */
838
- isp = inode->i_security;
839
- if (isp == NULL) {
840
- isp = new_inode_smack(sp->smk_root);
841
- if (isp == NULL)
842
- return -ENOMEM;
843
- inode->i_security = isp;
844
- } else
845
- isp->smk_inode = sp->smk_root;
856
+ init_inode_smack(inode, sp->smk_root);
846857
847
- if (transmute)
858
+ if (transmute) {
859
+ isp = smack_inode(inode);
848860 isp->smk_flags |= SMK_INODE_TRANSMUTE;
861
+ }
849862
850863 return 0;
851
-}
852
-
853
-/**
854
- * smack_sb_kern_mount - Smack specific mount processing
855
- * @sb: the file system superblock
856
- * @flags: the mount flags
857
- * @data: the smack mount options
858
- *
859
- * Returns 0 on success, an error code on failure
860
- */
861
-static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data)
862
-{
863
- int rc = 0;
864
- char *options = data;
865
- struct security_mnt_opts opts;
866
-
867
- security_init_mnt_opts(&opts);
868
-
869
- if (!options)
870
- goto out;
871
-
872
- rc = smack_parse_opts_str(options, &opts);
873
- if (rc)
874
- goto out_err;
875
-
876
-out:
877
- rc = smack_set_mnt_opts(sb, &opts, 0, NULL);
878
-
879
-out_err:
880
- security_free_mnt_opts(&opts);
881
- return rc;
882864 }
883865
884866 /**
....@@ -907,23 +889,20 @@
907889 */
908890
909891 /**
910
- * smack_bprm_set_creds - set creds for exec
892
+ * smack_bprm_creds_for_exec - Update bprm->cred if needed for exec
911893 * @bprm: the exec information
912894 *
913895 * Returns 0 if it gets a blob, -EPERM if exec forbidden and -ENOMEM otherwise
914896 */
915
-static int smack_bprm_set_creds(struct linux_binprm *bprm)
897
+static int smack_bprm_creds_for_exec(struct linux_binprm *bprm)
916898 {
917899 struct inode *inode = file_inode(bprm->file);
918
- struct task_smack *bsp = bprm->cred->security;
900
+ struct task_smack *bsp = smack_cred(bprm->cred);
919901 struct inode_smack *isp;
920902 struct superblock_smack *sbsp;
921903 int rc;
922904
923
- if (bprm->called_set_creds)
924
- return 0;
925
-
926
- isp = inode->i_security;
905
+ isp = smack_inode(inode);
927906 if (isp->smk_task == NULL || isp->smk_task == bsp->smk_task)
928907 return 0;
929908
....@@ -969,52 +948,14 @@
969948 * smack_inode_alloc_security - allocate an inode blob
970949 * @inode: the inode in need of a blob
971950 *
972
- * Returns 0 if it gets a blob, -ENOMEM otherwise
951
+ * Returns 0
973952 */
974953 static int smack_inode_alloc_security(struct inode *inode)
975954 {
976955 struct smack_known *skp = smk_of_current();
977956
978
- inode->i_security = new_inode_smack(skp);
979
- if (inode->i_security == NULL)
980
- return -ENOMEM;
957
+ init_inode_smack(inode, skp);
981958 return 0;
982
-}
983
-
984
-/**
985
- * smack_inode_free_rcu - Free inode_smack blob from cache
986
- * @head: the rcu_head for getting inode_smack pointer
987
- *
988
- * Call back function called from call_rcu() to free
989
- * the i_security blob pointer in inode
990
- */
991
-static void smack_inode_free_rcu(struct rcu_head *head)
992
-{
993
- struct inode_smack *issp;
994
-
995
- issp = container_of(head, struct inode_smack, smk_rcu);
996
- kmem_cache_free(smack_inode_cache, issp);
997
-}
998
-
999
-/**
1000
- * smack_inode_free_security - free an inode blob using call_rcu()
1001
- * @inode: the inode with a blob
1002
- *
1003
- * Clears the blob pointer in inode using RCU
1004
- */
1005
-static void smack_inode_free_security(struct inode *inode)
1006
-{
1007
- struct inode_smack *issp = inode->i_security;
1008
-
1009
- /*
1010
- * The inode may still be referenced in a path walk and
1011
- * a call to smack_inode_permission() can be made
1012
- * after smack_inode_free_security() is called.
1013
- * To avoid race condition free the i_security via RCU
1014
- * and leave the current inode->i_security pointer intact.
1015
- * The inode will be freed after the RCU grace period too.
1016
- */
1017
- call_rcu(&issp->smk_rcu, smack_inode_free_rcu);
1018959 }
1019960
1020961 /**
....@@ -1032,8 +973,9 @@
1032973 const struct qstr *qstr, const char **name,
1033974 void **value, size_t *len)
1034975 {
1035
- struct inode_smack *issp = inode->i_security;
1036
- struct smack_known *skp = smk_of_current();
976
+ struct task_smack *tsp = smack_cred(current_cred());
977
+ struct inode_smack *issp = smack_inode(inode);
978
+ struct smack_known *skp = smk_of_task(tsp);
1037979 struct smack_known *isp = smk_of_inode(inode);
1038980 struct smack_known *dsp = smk_of_inode(dir);
1039981 int may;
....@@ -1042,20 +984,34 @@
1042984 *name = XATTR_SMACK_SUFFIX;
1043985
1044986 if (value && len) {
1045
- rcu_read_lock();
1046
- may = smk_access_entry(skp->smk_known, dsp->smk_known,
1047
- &skp->smk_rules);
1048
- rcu_read_unlock();
987
+ /*
988
+ * If equal, transmuting already occurred in
989
+ * smack_dentry_create_files_as(). No need to check again.
990
+ */
991
+ if (tsp->smk_task != tsp->smk_transmuted) {
992
+ rcu_read_lock();
993
+ may = smk_access_entry(skp->smk_known, dsp->smk_known,
994
+ &skp->smk_rules);
995
+ rcu_read_unlock();
996
+ }
1049997
1050998 /*
1051
- * If the access rule allows transmutation and
1052
- * the directory requests transmutation then
1053
- * by all means transmute.
999
+ * In addition to having smk_task equal to smk_transmuted,
1000
+ * if the access rule allows transmutation and the directory
1001
+ * requests transmutation then by all means transmute.
10541002 * Mark the inode as changed.
10551003 */
1056
- if (may > 0 && ((may & MAY_TRANSMUTE) != 0) &&
1057
- smk_inode_transmutable(dir)) {
1058
- isp = dsp;
1004
+ if ((tsp->smk_task == tsp->smk_transmuted) ||
1005
+ (may > 0 && ((may & MAY_TRANSMUTE) != 0) &&
1006
+ smk_inode_transmutable(dir))) {
1007
+ /*
1008
+ * The caller of smack_dentry_create_files_as()
1009
+ * should have overridden the current cred, so the
1010
+ * inode label was already set correctly in
1011
+ * smack_inode_alloc_security().
1012
+ */
1013
+ if (tsp->smk_task != tsp->smk_transmuted)
1014
+ isp = dsp;
10591015 issp->smk_flags |= SMK_INODE_CHANGED;
10601016 }
10611017
....@@ -1213,7 +1169,7 @@
12131169 *
12141170 * This is the important Smack hook.
12151171 *
1216
- * Returns 0 if access is permitted, -EACCES otherwise
1172
+ * Returns 0 if access is permitted, an error code otherwise
12171173 */
12181174 static int smack_inode_permission(struct inode *inode, int mask)
12191175 {
....@@ -1271,8 +1227,7 @@
12711227
12721228 /**
12731229 * smack_inode_getattr - Smack check for getting attributes
1274
- * @mnt: vfsmount of the object
1275
- * @dentry: the object
1230
+ * @path: path to extract the info from
12761231 *
12771232 * Returns 0 if access is permitted, an error code otherwise
12781233 */
....@@ -1370,7 +1325,7 @@
13701325 const void *value, size_t size, int flags)
13711326 {
13721327 struct smack_known *skp;
1373
- struct inode_smack *isp = d_backing_inode(dentry)->i_security;
1328
+ struct inode_smack *isp = smack_inode(d_backing_inode(dentry));
13741329
13751330 if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) {
13761331 isp->smk_flags |= SMK_INODE_TRANSMUTE;
....@@ -1451,7 +1406,7 @@
14511406 if (rc != 0)
14521407 return rc;
14531408
1454
- isp = d_backing_inode(dentry)->i_security;
1409
+ isp = smack_inode(d_backing_inode(dentry));
14551410 /*
14561411 * Don't do anything special for these.
14571412 * XATTR_NAME_SMACKIPIN
....@@ -1490,10 +1445,19 @@
14901445 struct super_block *sbp;
14911446 struct inode *ip = (struct inode *)inode;
14921447 struct smack_known *isp;
1448
+ struct inode_smack *ispp;
1449
+ size_t label_len;
1450
+ char *label = NULL;
14931451
1494
- if (strcmp(name, XATTR_SMACK_SUFFIX) == 0)
1452
+ if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) {
14951453 isp = smk_of_inode(inode);
1496
- else {
1454
+ } else if (strcmp(name, XATTR_SMACK_TRANSMUTE) == 0) {
1455
+ ispp = smack_inode(inode);
1456
+ if (ispp->smk_flags & SMK_INODE_TRANSMUTE)
1457
+ label = TRANS_TRUE;
1458
+ else
1459
+ label = "";
1460
+ } else {
14971461 /*
14981462 * The rest of the Smack xattrs are only on sockets.
14991463 */
....@@ -1515,13 +1479,18 @@
15151479 return -EOPNOTSUPP;
15161480 }
15171481
1482
+ if (!label)
1483
+ label = isp->smk_known;
1484
+
1485
+ label_len = strlen(label);
1486
+
15181487 if (alloc) {
1519
- *buffer = kstrdup(isp->smk_known, GFP_KERNEL);
1488
+ *buffer = kstrdup(label, GFP_KERNEL);
15201489 if (*buffer == NULL)
15211490 return -ENOMEM;
15221491 }
15231492
1524
- return strlen(isp->smk_known);
1493
+ return label_len;
15251494 }
15261495
15271496
....@@ -1583,22 +1552,10 @@
15831552 */
15841553 static int smack_file_alloc_security(struct file *file)
15851554 {
1586
- struct smack_known *skp = smk_of_current();
1555
+ struct smack_known **blob = smack_file(file);
15871556
1588
- file->f_security = skp;
1557
+ *blob = smk_of_current();
15891558 return 0;
1590
-}
1591
-
1592
-/**
1593
- * smack_file_free_security - clear a file security blob
1594
- * @file: the object
1595
- *
1596
- * The security blob for a file is a pointer to the master
1597
- * label list, so no memory is freed.
1598
- */
1599
-static void smack_file_free_security(struct file *file)
1600
-{
1601
- file->f_security = NULL;
16021559 }
16031560
16041561 /**
....@@ -1738,7 +1695,7 @@
17381695 if (unlikely(IS_PRIVATE(file_inode(file))))
17391696 return 0;
17401697
1741
- isp = file_inode(file)->i_security;
1698
+ isp = smack_inode(file_inode(file));
17421699 if (isp->smk_mmap == NULL)
17431700 return 0;
17441701 sbsp = file_inode(file)->i_sb->s_security;
....@@ -1747,7 +1704,7 @@
17471704 return -EACCES;
17481705 mkp = isp->smk_mmap;
17491706
1750
- tsp = current_security();
1707
+ tsp = smack_cred(current_cred());
17511708 skp = smk_of_current();
17521709 rc = 0;
17531710
....@@ -1825,7 +1782,9 @@
18251782 */
18261783 static void smack_file_set_fowner(struct file *file)
18271784 {
1828
- file->f_security = smk_of_current();
1785
+ struct smack_known **blob = smack_file(file);
1786
+
1787
+ *blob = smk_of_current();
18291788 }
18301789
18311790 /**
....@@ -1842,8 +1801,9 @@
18421801 static int smack_file_send_sigiotask(struct task_struct *tsk,
18431802 struct fown_struct *fown, int signum)
18441803 {
1804
+ struct smack_known **blob;
18451805 struct smack_known *skp;
1846
- struct smack_known *tkp = smk_of_task(tsk->cred->security);
1806
+ struct smack_known *tkp = smk_of_task(smack_cred(tsk->cred));
18471807 const struct cred *tcred;
18481808 struct file *file;
18491809 int rc;
....@@ -1855,7 +1815,8 @@
18551815 file = container_of(fown, struct file, f_owner);
18561816
18571817 /* we don't log here as rc can be overriden */
1858
- skp = file->f_security;
1818
+ blob = smack_file(file);
1819
+ skp = *blob;
18591820 rc = smk_access(skp, tkp, MAY_DELIVER, NULL);
18601821 rc = smk_bu_note("sigiotask", skp, tkp, MAY_DELIVER, rc);
18611822
....@@ -1896,7 +1857,7 @@
18961857 if (inode->i_sb->s_magic == SOCKFS_MAGIC) {
18971858 sock = SOCKET_I(inode);
18981859 ssp = sock->sk->sk_security;
1899
- tsp = current_security();
1860
+ tsp = smack_cred(current_cred());
19001861 /*
19011862 * If the receiving process can't write to the
19021863 * passed socket or if the passed socket can't
....@@ -1927,18 +1888,17 @@
19271888 /**
19281889 * smack_file_open - Smack dentry open processing
19291890 * @file: the object
1930
- * @cred: task credential
19311891 *
19321892 * Set the security blob in the file structure.
19331893 * Allow the open only if the task has read access. There are
19341894 * many read operations (e.g. fstat) that you can do with an
19351895 * fd even if you have the file open write-only.
19361896 *
1937
- * Returns 0
1897
+ * Returns 0 if current has access, error code otherwise
19381898 */
19391899 static int smack_file_open(struct file *file)
19401900 {
1941
- struct task_smack *tsp = file->f_cred->security;
1901
+ struct task_smack *tsp = smack_cred(file->f_cred);
19421902 struct inode *inode = file_inode(file);
19431903 struct smk_audit_info ad;
19441904 int rc;
....@@ -1957,7 +1917,7 @@
19571917
19581918 /**
19591919 * smack_cred_alloc_blank - "allocate" blank task-level security credentials
1960
- * @new: the new credentials
1920
+ * @cred: the new credentials
19611921 * @gfp: the atomicity of any memory allocations
19621922 *
19631923 * Prepare a blank set of credentials for modification. This must allocate all
....@@ -1966,14 +1926,7 @@
19661926 */
19671927 static int smack_cred_alloc_blank(struct cred *cred, gfp_t gfp)
19681928 {
1969
- struct task_smack *tsp;
1970
-
1971
- tsp = new_task_smack(NULL, NULL, gfp);
1972
- if (tsp == NULL)
1973
- return -ENOMEM;
1974
-
1975
- cred->security = tsp;
1976
-
1929
+ init_task_smack(smack_cred(cred), NULL, NULL);
19771930 return 0;
19781931 }
19791932
....@@ -1985,23 +1938,18 @@
19851938 */
19861939 static void smack_cred_free(struct cred *cred)
19871940 {
1988
- struct task_smack *tsp = cred->security;
1941
+ struct task_smack *tsp = smack_cred(cred);
19891942 struct smack_rule *rp;
19901943 struct list_head *l;
19911944 struct list_head *n;
1992
-
1993
- if (tsp == NULL)
1994
- return;
1995
- cred->security = NULL;
19961945
19971946 smk_destroy_label_list(&tsp->smk_relabel);
19981947
19991948 list_for_each_safe(l, n, &tsp->smk_rules) {
20001949 rp = list_entry(l, struct smack_rule, list);
20011950 list_del(&rp->list);
2002
- kfree(rp);
1951
+ kmem_cache_free(smack_rule_cache, rp);
20031952 }
2004
- kfree(tsp);
20051953 }
20061954
20071955 /**
....@@ -2015,15 +1963,11 @@
20151963 static int smack_cred_prepare(struct cred *new, const struct cred *old,
20161964 gfp_t gfp)
20171965 {
2018
- struct task_smack *old_tsp = old->security;
2019
- struct task_smack *new_tsp;
1966
+ struct task_smack *old_tsp = smack_cred(old);
1967
+ struct task_smack *new_tsp = smack_cred(new);
20201968 int rc;
20211969
2022
- new_tsp = new_task_smack(old_tsp->smk_task, old_tsp->smk_task, gfp);
2023
- if (new_tsp == NULL)
2024
- return -ENOMEM;
2025
-
2026
- new->security = new_tsp;
1970
+ init_task_smack(new_tsp, old_tsp->smk_task, old_tsp->smk_task);
20271971
20281972 rc = smk_copy_rules(&new_tsp->smk_rules, &old_tsp->smk_rules, gfp);
20291973 if (rc != 0)
....@@ -2031,10 +1975,7 @@
20311975
20321976 rc = smk_copy_relabel(&new_tsp->smk_relabel, &old_tsp->smk_relabel,
20331977 gfp);
2034
- if (rc != 0)
2035
- return rc;
2036
-
2037
- return 0;
1978
+ return rc;
20381979 }
20391980
20401981 /**
....@@ -2046,31 +1987,30 @@
20461987 */
20471988 static void smack_cred_transfer(struct cred *new, const struct cred *old)
20481989 {
2049
- struct task_smack *old_tsp = old->security;
2050
- struct task_smack *new_tsp = new->security;
1990
+ struct task_smack *old_tsp = smack_cred(old);
1991
+ struct task_smack *new_tsp = smack_cred(new);
20511992
20521993 new_tsp->smk_task = old_tsp->smk_task;
20531994 new_tsp->smk_forked = old_tsp->smk_task;
20541995 mutex_init(&new_tsp->smk_rules_lock);
20551996 INIT_LIST_HEAD(&new_tsp->smk_rules);
20561997
2057
-
20581998 /* cbs copy rule list */
20591999 }
20602000
20612001 /**
20622002 * smack_cred_getsecid - get the secid corresponding to a creds structure
2063
- * @c: the object creds
2003
+ * @cred: the object creds
20642004 * @secid: where to put the result
20652005 *
20662006 * Sets the secid to contain a u32 version of the smack label.
20672007 */
2068
-static void smack_cred_getsecid(const struct cred *c, u32 *secid)
2008
+static void smack_cred_getsecid(const struct cred *cred, u32 *secid)
20692009 {
20702010 struct smack_known *skp;
20712011
20722012 rcu_read_lock();
2073
- skp = smk_of_task(c->security);
2013
+ skp = smk_of_task(smack_cred(cred));
20742014 *secid = skp->smk_secid;
20752015 rcu_read_unlock();
20762016 }
....@@ -2084,7 +2024,7 @@
20842024 */
20852025 static int smack_kernel_act_as(struct cred *new, u32 secid)
20862026 {
2087
- struct task_smack *new_tsp = new->security;
2027
+ struct task_smack *new_tsp = smack_cred(new);
20882028
20892029 new_tsp->smk_task = smack_from_secid(secid);
20902030 return 0;
....@@ -2101,8 +2041,8 @@
21012041 static int smack_kernel_create_files_as(struct cred *new,
21022042 struct inode *inode)
21032043 {
2104
- struct inode_smack *isp = inode->i_security;
2105
- struct task_smack *tsp = new->security;
2044
+ struct inode_smack *isp = smack_inode(inode);
2045
+ struct task_smack *tsp = smack_cred(new);
21062046
21072047 tsp->smk_forked = isp->smk_inode;
21082048 tsp->smk_task = tsp->smk_forked;
....@@ -2217,8 +2157,6 @@
22172157 /**
22182158 * smack_task_setscheduler - Smack check on setting scheduler
22192159 * @p: the task object
2220
- * @policy: unused
2221
- * @lp: unused
22222160 *
22232161 * Return 0 if read access is permitted
22242162 */
....@@ -2259,7 +2197,7 @@
22592197 * Return 0 if write access is permitted
22602198 *
22612199 */
2262
-static int smack_task_kill(struct task_struct *p, struct siginfo *info,
2200
+static int smack_task_kill(struct task_struct *p, struct kernel_siginfo *info,
22632201 int sig, const struct cred *cred)
22642202 {
22652203 struct smk_audit_info ad;
....@@ -2286,7 +2224,7 @@
22862224 * specific behavior. This is not clean. For one thing
22872225 * we can't take privilege into account.
22882226 */
2289
- skp = smk_of_task(cred->security);
2227
+ skp = smk_of_task(smack_cred(cred));
22902228 rc = smk_access(skp, tkp, MAY_DELIVER, &ad);
22912229 rc = smk_bu_note("USB signal", skp, tkp, MAY_DELIVER, rc);
22922230 return rc;
....@@ -2301,7 +2239,7 @@
23012239 */
23022240 static void smack_task_to_inode(struct task_struct *p, struct inode *inode)
23032241 {
2304
- struct inode_smack *isp = inode->i_security;
2242
+ struct inode_smack *isp = smack_inode(inode);
23052243 struct smack_known *skp = smk_of_task_struct(p);
23062244
23072245 isp->smk_inode = skp;
....@@ -2406,7 +2344,6 @@
24062344 return NULL;
24072345 }
24082346
2409
-#if IS_ENABLED(CONFIG_IPV6)
24102347 /*
24112348 * smk_ipv6_localhost - Check for local ipv6 host address
24122349 * @sip: the address
....@@ -2474,41 +2411,33 @@
24742411
24752412 return NULL;
24762413 }
2477
-#endif /* CONFIG_IPV6 */
24782414
24792415 /**
2480
- * smack_netlabel - Set the secattr on a socket
2416
+ * smack_netlbl_add - Set the secattr on a socket
24812417 * @sk: the socket
2482
- * @labeled: socket label scheme
24832418 *
2484
- * Convert the outbound smack value (smk_out) to a
2485
- * secattr and attach it to the socket.
2419
+ * Attach the outbound smack value (smk_out) to the socket.
24862420 *
24872421 * Returns 0 on success or an error code
24882422 */
2489
-static int smack_netlabel(struct sock *sk, int labeled)
2423
+static int smack_netlbl_add(struct sock *sk)
24902424 {
2491
- struct smack_known *skp;
24922425 struct socket_smack *ssp = sk->sk_security;
2493
- int rc = 0;
2426
+ struct smack_known *skp = ssp->smk_out;
2427
+ int rc;
24942428
2495
- /*
2496
- * Usually the netlabel code will handle changing the
2497
- * packet labeling based on the label.
2498
- * The case of a single label host is different, because
2499
- * a single label host should never get a labeled packet
2500
- * even though the label is usually associated with a packet
2501
- * label.
2502
- */
25032429 local_bh_disable();
25042430 bh_lock_sock_nested(sk);
25052431
2506
- if (ssp->smk_out == smack_net_ambient ||
2507
- labeled == SMACK_UNLABELED_SOCKET)
2508
- netlbl_sock_delattr(sk);
2509
- else {
2510
- skp = ssp->smk_out;
2511
- rc = netlbl_sock_setattr(sk, sk->sk_family, &skp->smk_netlabel);
2432
+ rc = netlbl_sock_setattr(sk, sk->sk_family, &skp->smk_netlabel);
2433
+ switch (rc) {
2434
+ case 0:
2435
+ ssp->smk_state = SMK_NETLBL_LABELED;
2436
+ break;
2437
+ case -EDESTADDRREQ:
2438
+ ssp->smk_state = SMK_NETLBL_REQSKB;
2439
+ rc = 0;
2440
+ break;
25122441 }
25132442
25142443 bh_unlock_sock(sk);
....@@ -2518,7 +2447,31 @@
25182447 }
25192448
25202449 /**
2521
- * smack_netlbel_send - Set the secattr on a socket and perform access checks
2450
+ * smack_netlbl_delete - Remove the secattr from a socket
2451
+ * @sk: the socket
2452
+ *
2453
+ * Remove the outbound smack value from a socket
2454
+ */
2455
+static void smack_netlbl_delete(struct sock *sk)
2456
+{
2457
+ struct socket_smack *ssp = sk->sk_security;
2458
+
2459
+ /*
2460
+ * Take the label off the socket if one is set.
2461
+ */
2462
+ if (ssp->smk_state != SMK_NETLBL_LABELED)
2463
+ return;
2464
+
2465
+ local_bh_disable();
2466
+ bh_lock_sock_nested(sk);
2467
+ netlbl_sock_delattr(sk);
2468
+ bh_unlock_sock(sk);
2469
+ local_bh_enable();
2470
+ ssp->smk_state = SMK_NETLBL_UNLABELED;
2471
+}
2472
+
2473
+/**
2474
+ * smk_ipv4_check - Perform IPv4 host access checks
25222475 * @sk: the socket
25232476 * @sap: the destination address
25242477 *
....@@ -2528,11 +2481,10 @@
25282481 * Returns 0 on success or an error code.
25292482 *
25302483 */
2531
-static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap)
2484
+static int smk_ipv4_check(struct sock *sk, struct sockaddr_in *sap)
25322485 {
25332486 struct smack_known *skp;
2534
- int rc;
2535
- int sk_lbl;
2487
+ int rc = 0;
25362488 struct smack_known *hkp;
25372489 struct socket_smack *ssp = sk->sk_security;
25382490 struct smk_audit_info ad;
....@@ -2548,22 +2500,20 @@
25482500 ad.a.u.net->dport = sap->sin_port;
25492501 ad.a.u.net->v4info.daddr = sap->sin_addr.s_addr;
25502502 #endif
2551
- sk_lbl = SMACK_UNLABELED_SOCKET;
25522503 skp = ssp->smk_out;
25532504 rc = smk_access(skp, hkp, MAY_WRITE, &ad);
25542505 rc = smk_bu_note("IPv4 host check", skp, hkp, MAY_WRITE, rc);
2555
- } else {
2556
- sk_lbl = SMACK_CIPSO_SOCKET;
2557
- rc = 0;
2506
+ /*
2507
+ * Clear the socket netlabel if it's set.
2508
+ */
2509
+ if (!rc)
2510
+ smack_netlbl_delete(sk);
25582511 }
25592512 rcu_read_unlock();
2560
- if (rc != 0)
2561
- return rc;
25622513
2563
- return smack_netlabel(sk, sk_lbl);
2514
+ return rc;
25642515 }
25652516
2566
-#if IS_ENABLED(CONFIG_IPV6)
25672517 /**
25682518 * smk_ipv6_check - check Smack access
25692519 * @subject: subject Smack label
....@@ -2586,7 +2536,7 @@
25862536 #ifdef CONFIG_AUDIT
25872537 smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
25882538 ad.a.u.net->family = PF_INET6;
2589
- ad.a.u.net->dport = ntohs(address->sin6_port);
2539
+ ad.a.u.net->dport = address->sin6_port;
25902540 if (act == SMK_RECEIVING)
25912541 ad.a.u.net->v6info.saddr = address->sin6_addr;
25922542 else
....@@ -2596,7 +2546,6 @@
25962546 rc = smk_bu_note("IPv6 check", subject, object, MAY_WRITE, rc);
25972547 return rc;
25982548 }
2599
-#endif /* CONFIG_IPV6 */
26002549
26012550 #ifdef SMACK_IPV6_PORT_LABELING
26022551 /**
....@@ -2685,11 +2634,13 @@
26852634 mutex_unlock(&smack_ipv6_lock);
26862635 return;
26872636 }
2637
+#endif
26882638
26892639 /**
26902640 * smk_ipv6_port_check - check Smack port access
2691
- * @sock: socket
2641
+ * @sk: socket
26922642 * @address: address
2643
+ * @act: the action being taken
26932644 *
26942645 * Create or update the port list entry
26952646 */
....@@ -2746,7 +2697,6 @@
27462697
27472698 return smk_ipv6_check(skp, object, address, act);
27482699 }
2749
-#endif /* SMACK_IPV6_PORT_LABELING */
27502700
27512701 /**
27522702 * smack_inode_setsecurity - set smack xattrs
....@@ -2764,7 +2714,7 @@
27642714 const void *value, size_t size, int flags)
27652715 {
27662716 struct smack_known *skp;
2767
- struct inode_smack *nsp = inode->i_security;
2717
+ struct inode_smack *nsp = smack_inode(inode);
27682718 struct socket_smack *ssp;
27692719 struct socket *sock;
27702720 int rc = 0;
....@@ -2798,7 +2748,7 @@
27982748 else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) {
27992749 ssp->smk_out = skp;
28002750 if (sock->sk->sk_family == PF_INET) {
2801
- rc = smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET);
2751
+ rc = smack_netlbl_add(sock->sk);
28022752 if (rc != 0)
28032753 printk(KERN_WARNING
28042754 "Smack: \"%s\" netlbl error %d.\n",
....@@ -2849,7 +2799,7 @@
28492799 /*
28502800 * Set the outbound netlbl.
28512801 */
2852
- return smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET);
2802
+ return smack_netlbl_add(sock->sk);
28532803 }
28542804
28552805 /**
....@@ -2859,7 +2809,7 @@
28592809 *
28602810 * Cross reference the peer labels for SO_PEERSEC
28612811 *
2862
- * Returns 0 on success, and error code otherwise
2812
+ * Returns 0
28632813 */
28642814 static int smack_socket_socketpair(struct socket *socka,
28652815 struct socket *sockb)
....@@ -2882,13 +2832,17 @@
28822832 *
28832833 * Records the label bound to a port.
28842834 *
2885
- * Returns 0
2835
+ * Returns 0 on success, and error code otherwise
28862836 */
28872837 static int smack_socket_bind(struct socket *sock, struct sockaddr *address,
28882838 int addrlen)
28892839 {
2890
- if (sock->sk != NULL && sock->sk->sk_family == PF_INET6)
2840
+ if (sock->sk != NULL && sock->sk->sk_family == PF_INET6) {
2841
+ if (addrlen < SIN6_LEN_RFC2133 ||
2842
+ address->sa_family != AF_INET6)
2843
+ return -EINVAL;
28912844 smk_ipv6_port_label(sock, address);
2845
+ }
28922846 return 0;
28932847 }
28942848 #endif /* SMACK_IPV6_PORT_LABELING */
....@@ -2907,41 +2861,36 @@
29072861 int addrlen)
29082862 {
29092863 int rc = 0;
2910
-#if IS_ENABLED(CONFIG_IPV6)
2911
- struct sockaddr_in6 *sip = (struct sockaddr_in6 *)sap;
2912
-#endif
2913
-#ifdef SMACK_IPV6_SECMARK_LABELING
2914
- struct smack_known *rsp;
2915
- struct socket_smack *ssp;
2916
-#endif
29172864
29182865 if (sock->sk == NULL)
29192866 return 0;
2867
+ if (sock->sk->sk_family != PF_INET &&
2868
+ (!IS_ENABLED(CONFIG_IPV6) || sock->sk->sk_family != PF_INET6))
2869
+ return 0;
2870
+ if (addrlen < offsetofend(struct sockaddr, sa_family))
2871
+ return 0;
2872
+ if (IS_ENABLED(CONFIG_IPV6) && sap->sa_family == AF_INET6) {
2873
+ struct sockaddr_in6 *sip = (struct sockaddr_in6 *)sap;
2874
+ struct smack_known *rsp = NULL;
29202875
2921
-#ifdef SMACK_IPV6_SECMARK_LABELING
2922
- ssp = sock->sk->sk_security;
2923
-#endif
2876
+ if (addrlen < SIN6_LEN_RFC2133)
2877
+ return 0;
2878
+ if (__is_defined(SMACK_IPV6_SECMARK_LABELING))
2879
+ rsp = smack_ipv6host_label(sip);
2880
+ if (rsp != NULL) {
2881
+ struct socket_smack *ssp = sock->sk->sk_security;
29242882
2925
- switch (sock->sk->sk_family) {
2926
- case PF_INET:
2927
- if (addrlen < sizeof(struct sockaddr_in))
2928
- return -EINVAL;
2929
- rc = smack_netlabel_send(sock->sk, (struct sockaddr_in *)sap);
2930
- break;
2931
- case PF_INET6:
2932
- if (addrlen < sizeof(struct sockaddr_in6))
2933
- return -EINVAL;
2934
-#ifdef SMACK_IPV6_SECMARK_LABELING
2935
- rsp = smack_ipv6host_label(sip);
2936
- if (rsp != NULL)
29372883 rc = smk_ipv6_check(ssp->smk_out, rsp, sip,
2938
- SMK_CONNECTING);
2939
-#endif
2940
-#ifdef SMACK_IPV6_PORT_LABELING
2941
- rc = smk_ipv6_port_check(sock->sk, sip, SMK_CONNECTING);
2942
-#endif
2943
- break;
2884
+ SMK_CONNECTING);
2885
+ }
2886
+ if (__is_defined(SMACK_IPV6_PORT_LABELING))
2887
+ rc = smk_ipv6_port_check(sock->sk, sip, SMK_CONNECTING);
2888
+
2889
+ return rc;
29442890 }
2891
+ if (sap->sa_family != AF_INET || addrlen < sizeof(struct sockaddr_in))
2892
+ return 0;
2893
+ rc = smk_ipv4_check(sock->sk, (struct sockaddr_in *)sap);
29452894 return rc;
29462895 }
29472896
....@@ -2973,21 +2922,10 @@
29732922 */
29742923 static int smack_msg_msg_alloc_security(struct msg_msg *msg)
29752924 {
2976
- struct smack_known *skp = smk_of_current();
2925
+ struct smack_known **blob = smack_msg_msg(msg);
29772926
2978
- msg->security = skp;
2927
+ *blob = smk_of_current();
29792928 return 0;
2980
-}
2981
-
2982
-/**
2983
- * smack_msg_msg_free_security - Clear the security blob for msg_msg
2984
- * @msg: the object
2985
- *
2986
- * Clears the blob pointer
2987
- */
2988
-static void smack_msg_msg_free_security(struct msg_msg *msg)
2989
-{
2990
- msg->security = NULL;
29912929 }
29922930
29932931 /**
....@@ -2998,7 +2936,9 @@
29982936 */
29992937 static struct smack_known *smack_of_ipc(struct kern_ipc_perm *isp)
30002938 {
3001
- return (struct smack_known *)isp->security;
2939
+ struct smack_known **blob = smack_ipc(isp);
2940
+
2941
+ return *blob;
30022942 }
30032943
30042944 /**
....@@ -3009,21 +2949,10 @@
30092949 */
30102950 static int smack_ipc_alloc_security(struct kern_ipc_perm *isp)
30112951 {
3012
- struct smack_known *skp = smk_of_current();
2952
+ struct smack_known **blob = smack_ipc(isp);
30132953
3014
- isp->security = skp;
2954
+ *blob = smk_of_current();
30152955 return 0;
3016
-}
3017
-
3018
-/**
3019
- * smack_ipc_free_security - Clear the security blob for ipc
3020
- * @isp: the object
3021
- *
3022
- * Clears the blob pointer
3023
- */
3024
-static void smack_ipc_free_security(struct kern_ipc_perm *isp)
3025
-{
3026
- isp->security = NULL;
30272956 }
30282957
30292958 /**
....@@ -3106,13 +3035,13 @@
31063035 *
31073036 * Returns 0 if current has the requested access, error code otherwise
31083037 */
3109
-static int smack_shm_shmat(struct kern_ipc_perm *ipc, char __user *shmaddr,
3038
+static int smack_shm_shmat(struct kern_ipc_perm *isp, char __user *shmaddr,
31103039 int shmflg)
31113040 {
31123041 int may;
31133042
31143043 may = smack_flags_to_may(shmflg);
3115
- return smk_curacc_shm(ipc, may);
3044
+ return smk_curacc_shm(isp, may);
31163045 }
31173046
31183047 /**
....@@ -3323,7 +3252,8 @@
33233252 */
33243253 static int smack_ipc_permission(struct kern_ipc_perm *ipp, short flag)
33253254 {
3326
- struct smack_known *iskp = ipp->security;
3255
+ struct smack_known **blob = smack_ipc(ipp);
3256
+ struct smack_known *iskp = *blob;
33273257 int may = smack_flags_to_may(flag);
33283258 struct smk_audit_info ad;
33293259 int rc;
....@@ -3344,7 +3274,8 @@
33443274 */
33453275 static void smack_ipc_getsecid(struct kern_ipc_perm *ipp, u32 *secid)
33463276 {
3347
- struct smack_known *iskp = ipp->security;
3277
+ struct smack_known **blob = smack_ipc(ipp);
3278
+ struct smack_known *iskp = *blob;
33483279
33493280 *secid = iskp->smk_secid;
33503281 }
....@@ -3372,15 +3303,14 @@
33723303 if (inode == NULL)
33733304 return;
33743305
3375
- isp = inode->i_security;
3306
+ isp = smack_inode(inode);
33763307
3377
- mutex_lock(&isp->smk_lock);
33783308 /*
33793309 * If the inode is already instantiated
33803310 * take the quick way out
33813311 */
33823312 if (isp->smk_flags & SMK_INODE_INSTANT)
3383
- goto unlockandout;
3313
+ return;
33843314
33853315 sbp = inode->i_sb;
33863316 sbsp = sbp->s_security;
....@@ -3431,7 +3361,7 @@
34313361 break;
34323362 }
34333363 isp->smk_flags |= SMK_INODE_INSTANT;
3434
- goto unlockandout;
3364
+ return;
34353365 }
34363366
34373367 /*
....@@ -3475,13 +3405,12 @@
34753405 */
34763406 final = &smack_known_star;
34773407 /*
3478
- * No break.
3479
- *
34803408 * If a smack value has been set we want to use it,
34813409 * but since tmpfs isn't giving us the opportunity
34823410 * to set mount options simulate setting the
34833411 * superblock default.
34843412 */
3413
+ fallthrough;
34853414 default:
34863415 /*
34873416 * This isn't an understood special case.
....@@ -3533,7 +3462,7 @@
35333462 } else {
35343463 rc = __vfs_getxattr(dp, inode,
35353464 XATTR_NAME_SMACKTRANSMUTE, trattr,
3536
- TRANS_TRUE_SIZE);
3465
+ TRANS_TRUE_SIZE, XATTR_NOSECURITY);
35373466 if (rc >= 0 && strncmp(trattr, TRANS_TRUE,
35383467 TRANS_TRUE_SIZE) != 0)
35393468 rc = -EINVAL;
....@@ -3567,8 +3496,6 @@
35673496
35683497 isp->smk_flags |= (SMK_INODE_INSTANT | transflag);
35693498
3570
-unlockandout:
3571
- mutex_unlock(&isp->smk_lock);
35723499 return;
35733500 }
35743501
....@@ -3613,7 +3540,7 @@
36133540 */
36143541 static int smack_setprocattr(const char *name, void *value, size_t size)
36153542 {
3616
- struct task_smack *tsp = current_security();
3543
+ struct task_smack *tsp = smack_cred(current_cred());
36173544 struct cred *new;
36183545 struct smack_known *skp;
36193546 struct smack_known_list_elem *sklep;
....@@ -3654,7 +3581,7 @@
36543581 if (new == NULL)
36553582 return -ENOMEM;
36563583
3657
- tsp = new->security;
3584
+ tsp = smack_cred(new);
36583585 tsp->smk_task = skp;
36593586 /*
36603587 * process can change its label only once
....@@ -3778,9 +3705,16 @@
37783705
37793706 switch (sock->sk->sk_family) {
37803707 case AF_INET:
3781
- rc = smack_netlabel_send(sock->sk, sip);
3708
+ if (msg->msg_namelen < sizeof(struct sockaddr_in) ||
3709
+ sip->sin_family != AF_INET)
3710
+ return -EINVAL;
3711
+ rc = smk_ipv4_check(sock->sk, sip);
37823712 break;
3713
+#if IS_ENABLED(CONFIG_IPV6)
37833714 case AF_INET6:
3715
+ if (msg->msg_namelen < SIN6_LEN_RFC2133 ||
3716
+ sap->sin6_family != AF_INET6)
3717
+ return -EINVAL;
37843718 #ifdef SMACK_IPV6_SECMARK_LABELING
37853719 rsp = smack_ipv6host_label(sap);
37863720 if (rsp != NULL)
....@@ -3790,6 +3724,7 @@
37903724 #ifdef SMACK_IPV6_PORT_LABELING
37913725 rc = smk_ipv6_port_check(sock->sk, sap, SMK_SENDING);
37923726 #endif
3727
+#endif /* IS_ENABLED(CONFIG_IPV6) */
37933728 break;
37943729 }
37953730 return rc;
....@@ -3809,6 +3744,18 @@
38093744 int found = 0;
38103745 int acat;
38113746 int kcat;
3747
+
3748
+ /*
3749
+ * Netlabel found it in the cache.
3750
+ */
3751
+ if ((sap->flags & NETLBL_SECATTR_CACHE) != 0)
3752
+ return (struct smack_known *)sap->cache->data;
3753
+
3754
+ if ((sap->flags & NETLBL_SECATTR_SECID) != 0)
3755
+ /*
3756
+ * Looks like a fallback, which gives us a secid.
3757
+ */
3758
+ return smack_from_secid(sap->attr.secid);
38123759
38133760 if ((sap->flags & NETLBL_SECATTR_MLS_LVL) != 0) {
38143761 /*
....@@ -3857,11 +3804,6 @@
38573804 return &smack_known_web;
38583805 return &smack_known_star;
38593806 }
3860
- if ((sap->flags & NETLBL_SECATTR_SECID) != 0)
3861
- /*
3862
- * Looks like a fallback, which gives us a secid.
3863
- */
3864
- return smack_from_secid(sap->attr.secid);
38653807 /*
38663808 * Without guidance regarding the smack value
38673809 * for the packet fall back on the network
....@@ -3921,6 +3863,62 @@
39213863 #endif /* CONFIG_IPV6 */
39223864
39233865 /**
3866
+ * smack_from_skb - Smack data from the secmark in an skb
3867
+ * @skb: packet
3868
+ *
3869
+ * Returns smack_known of the secmark or NULL if that won't work.
3870
+ */
3871
+#ifdef CONFIG_NETWORK_SECMARK
3872
+static struct smack_known *smack_from_skb(struct sk_buff *skb)
3873
+{
3874
+ if (skb == NULL || skb->secmark == 0)
3875
+ return NULL;
3876
+
3877
+ return smack_from_secid(skb->secmark);
3878
+}
3879
+#else
3880
+static inline struct smack_known *smack_from_skb(struct sk_buff *skb)
3881
+{
3882
+ return NULL;
3883
+}
3884
+#endif
3885
+
3886
+/**
3887
+ * smack_from_netlbl - Smack data from the IP options in an skb
3888
+ * @sk: socket data came in on
3889
+ * @family: address family
3890
+ * @skb: packet
3891
+ *
3892
+ * Find the Smack label in the IP options. If it hasn't been
3893
+ * added to the netlabel cache, add it here.
3894
+ *
3895
+ * Returns smack_known of the IP options or NULL if that won't work.
3896
+ */
3897
+static struct smack_known *smack_from_netlbl(struct sock *sk, u16 family,
3898
+ struct sk_buff *skb)
3899
+{
3900
+ struct netlbl_lsm_secattr secattr;
3901
+ struct socket_smack *ssp = NULL;
3902
+ struct smack_known *skp = NULL;
3903
+ int rc;
3904
+
3905
+ netlbl_secattr_init(&secattr);
3906
+
3907
+ if (sk)
3908
+ ssp = sk->sk_security;
3909
+
3910
+ if (netlbl_skbuff_getattr(skb, family, &secattr) == 0) {
3911
+ skp = smack_from_secattr(&secattr, ssp);
3912
+ if (secattr.flags & NETLBL_SECATTR_CACHEABLE)
3913
+ rc = netlbl_cache_add(skb, family, &skp->smk_netlabel);
3914
+ }
3915
+
3916
+ netlbl_secattr_destroy(&secattr);
3917
+
3918
+ return skp;
3919
+}
3920
+
3921
+/**
39243922 * smack_socket_sock_rcv_skb - Smack packet delivery access check
39253923 * @sk: socket
39263924 * @skb: packet
....@@ -3929,7 +3927,6 @@
39293927 */
39303928 static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
39313929 {
3932
- struct netlbl_lsm_secattr secattr;
39333930 struct socket_smack *ssp = sk->sk_security;
39343931 struct smack_known *skp = NULL;
39353932 int rc = 0;
....@@ -3948,33 +3945,18 @@
39483945
39493946 switch (family) {
39503947 case PF_INET:
3951
-#ifdef CONFIG_SECURITY_SMACK_NETFILTER
39523948 /*
39533949 * If there is a secmark use it rather than the CIPSO label.
39543950 * If there is no secmark fall back to CIPSO.
39553951 * The secmark is assumed to reflect policy better.
39563952 */
3957
- if (skb && skb->secmark != 0) {
3958
- skp = smack_from_secid(skb->secmark);
3959
- goto access_check;
3953
+ skp = smack_from_skb(skb);
3954
+ if (skp == NULL) {
3955
+ skp = smack_from_netlbl(sk, family, skb);
3956
+ if (skp == NULL)
3957
+ skp = smack_net_ambient;
39603958 }
3961
-#endif /* CONFIG_SECURITY_SMACK_NETFILTER */
3962
- /*
3963
- * Translate what netlabel gave us.
3964
- */
3965
- netlbl_secattr_init(&secattr);
39663959
3967
- rc = netlbl_skbuff_getattr(skb, family, &secattr);
3968
- if (rc == 0)
3969
- skp = smack_from_secattr(&secattr, ssp);
3970
- else
3971
- skp = smack_net_ambient;
3972
-
3973
- netlbl_secattr_destroy(&secattr);
3974
-
3975
-#ifdef CONFIG_SECURITY_SMACK_NETFILTER
3976
-access_check:
3977
-#endif
39783960 #ifdef CONFIG_AUDIT
39793961 smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
39803962 ad.a.u.net->family = family;
....@@ -4000,14 +3982,14 @@
40003982 proto != IPPROTO_TCP && proto != IPPROTO_DCCP)
40013983 break;
40023984 #ifdef SMACK_IPV6_SECMARK_LABELING
4003
- if (skb && skb->secmark != 0)
4004
- skp = smack_from_secid(skb->secmark);
4005
- else
3985
+ skp = smack_from_skb(skb);
3986
+ if (skp == NULL) {
3987
+ if (smk_ipv6_localhost(&sadd))
3988
+ break;
40063989 skp = smack_ipv6host_label(&sadd);
4007
- if (skp == NULL)
4008
- skp = smack_net_ambient;
4009
- if (skb == NULL)
4010
- break;
3990
+ if (skp == NULL)
3991
+ skp = smack_net_ambient;
3992
+ }
40113993 #ifdef CONFIG_AUDIT
40123994 smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
40133995 ad.a.u.net->family = family;
....@@ -4079,12 +4061,11 @@
40794061 struct sk_buff *skb, u32 *secid)
40804062
40814063 {
4082
- struct netlbl_lsm_secattr secattr;
40834064 struct socket_smack *ssp = NULL;
40844065 struct smack_known *skp;
4066
+ struct sock *sk = NULL;
40854067 int family = PF_UNSPEC;
40864068 u32 s = 0; /* 0 is the invalid secid */
4087
- int rc;
40884069
40894070 if (skb != NULL) {
40904071 if (skb->protocol == htons(ETH_P_IP))
....@@ -4103,27 +4084,25 @@
41034084 s = ssp->smk_out->smk_secid;
41044085 break;
41054086 case PF_INET:
4106
-#ifdef CONFIG_SECURITY_SMACK_NETFILTER
4107
- s = skb->secmark;
4108
- if (s != 0)
4087
+ skp = smack_from_skb(skb);
4088
+ if (skp) {
4089
+ s = skp->smk_secid;
41094090 break;
4110
-#endif
4091
+ }
41114092 /*
41124093 * Translate what netlabel gave us.
41134094 */
4114
- if (sock != NULL && sock->sk != NULL)
4115
- ssp = sock->sk->sk_security;
4116
- netlbl_secattr_init(&secattr);
4117
- rc = netlbl_skbuff_getattr(skb, family, &secattr);
4118
- if (rc == 0) {
4119
- skp = smack_from_secattr(&secattr, ssp);
4095
+ if (sock != NULL)
4096
+ sk = sock->sk;
4097
+ skp = smack_from_netlbl(sk, family, skb);
4098
+ if (skp != NULL)
41204099 s = skp->smk_secid;
4121
- }
4122
- netlbl_secattr_destroy(&secattr);
41234100 break;
41244101 case PF_INET6:
41254102 #ifdef SMACK_IPV6_SECMARK_LABELING
4126
- s = skb->secmark;
4103
+ skp = smack_from_skb(skb);
4104
+ if (skp)
4105
+ s = skp->smk_secid;
41274106 #endif
41284107 break;
41294108 }
....@@ -4171,7 +4150,6 @@
41714150 u16 family = sk->sk_family;
41724151 struct smack_known *skp;
41734152 struct socket_smack *ssp = sk->sk_security;
4174
- struct netlbl_lsm_secattr secattr;
41754153 struct sockaddr_in addr;
41764154 struct iphdr *hdr;
41774155 struct smack_known *hskp;
....@@ -4195,29 +4173,17 @@
41954173 }
41964174 #endif /* CONFIG_IPV6 */
41974175
4198
-#ifdef CONFIG_SECURITY_SMACK_NETFILTER
41994176 /*
42004177 * If there is a secmark use it rather than the CIPSO label.
42014178 * If there is no secmark fall back to CIPSO.
42024179 * The secmark is assumed to reflect policy better.
42034180 */
4204
- if (skb && skb->secmark != 0) {
4205
- skp = smack_from_secid(skb->secmark);
4206
- goto access_check;
4181
+ skp = smack_from_skb(skb);
4182
+ if (skp == NULL) {
4183
+ skp = smack_from_netlbl(sk, family, skb);
4184
+ if (skp == NULL)
4185
+ skp = &smack_known_huh;
42074186 }
4208
-#endif /* CONFIG_SECURITY_SMACK_NETFILTER */
4209
-
4210
- netlbl_secattr_init(&secattr);
4211
- rc = netlbl_skbuff_getattr(skb, family, &secattr);
4212
- if (rc == 0)
4213
- skp = smack_from_secattr(&secattr, ssp);
4214
- else
4215
- skp = &smack_known_huh;
4216
- netlbl_secattr_destroy(&secattr);
4217
-
4218
-#ifdef CONFIG_SECURITY_SMACK_NETFILTER
4219
-access_check:
4220
-#endif
42214187
42224188 #ifdef CONFIG_AUDIT
42234189 smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
....@@ -4301,7 +4267,7 @@
43014267 static int smack_key_alloc(struct key *key, const struct cred *cred,
43024268 unsigned long flags)
43034269 {
4304
- struct smack_known *skp = smk_of_task(cred->security);
4270
+ struct smack_known *skp = smk_of_task(smack_cred(cred));
43054271
43064272 key->security = skp;
43074273 return 0;
....@@ -4322,25 +4288,44 @@
43224288 * smack_key_permission - Smack access on a key
43234289 * @key_ref: gets to the object
43244290 * @cred: the credentials to use
4325
- * @perm: requested key permissions
4291
+ * @need_perm: requested key permission
43264292 *
43274293 * Return 0 if the task has read and write to the object,
43284294 * an error code otherwise
43294295 */
43304296 static int smack_key_permission(key_ref_t key_ref,
4331
- const struct cred *cred, unsigned perm)
4297
+ const struct cred *cred,
4298
+ enum key_need_perm need_perm)
43324299 {
43334300 struct key *keyp;
43344301 struct smk_audit_info ad;
4335
- struct smack_known *tkp = smk_of_task(cred->security);
4302
+ struct smack_known *tkp = smk_of_task(smack_cred(cred));
43364303 int request = 0;
43374304 int rc;
43384305
43394306 /*
43404307 * Validate requested permissions
43414308 */
4342
- if (perm & ~KEY_NEED_ALL)
4309
+ switch (need_perm) {
4310
+ case KEY_NEED_READ:
4311
+ case KEY_NEED_SEARCH:
4312
+ case KEY_NEED_VIEW:
4313
+ request |= MAY_READ;
4314
+ break;
4315
+ case KEY_NEED_WRITE:
4316
+ case KEY_NEED_LINK:
4317
+ case KEY_NEED_SETATTR:
4318
+ request |= MAY_WRITE;
4319
+ break;
4320
+ case KEY_NEED_UNSPECIFIED:
4321
+ case KEY_NEED_UNLINK:
4322
+ case KEY_SYSADMIN_OVERRIDE:
4323
+ case KEY_AUTHTOKEN_OVERRIDE:
4324
+ case KEY_DEFER_PERM_CHECK:
4325
+ return 0;
4326
+ default:
43434327 return -EINVAL;
4328
+ }
43444329
43454330 keyp = key_ref_to_ptr(key_ref);
43464331 if (keyp == NULL)
....@@ -4357,7 +4342,7 @@
43574342 if (tkp == NULL)
43584343 return -EACCES;
43594344
4360
- if (smack_privileged_cred(CAP_MAC_OVERRIDE, cred))
4345
+ if (smack_privileged(CAP_MAC_OVERRIDE))
43614346 return 0;
43624347
43634348 #ifdef CONFIG_AUDIT
....@@ -4365,10 +4350,6 @@
43654350 ad.a.u.key_struct.key = keyp->serial;
43664351 ad.a.u.key_struct.key_desc = keyp->description;
43674352 #endif
4368
- if (perm & (KEY_NEED_READ | KEY_NEED_SEARCH | KEY_NEED_VIEW))
4369
- request |= MAY_READ;
4370
- if (perm & (KEY_NEED_WRITE | KEY_NEED_LINK | KEY_NEED_SETATTR))
4371
- request |= MAY_WRITE;
43724353 rc = smk_access(tkp, keyp->security, request, &ad);
43734354 rc = smk_bu_note("key access", tkp, keyp->security, request, rc);
43744355 return rc;
....@@ -4403,7 +4384,80 @@
44034384 return length;
44044385 }
44054386
4387
+
4388
+#ifdef CONFIG_KEY_NOTIFICATIONS
4389
+/**
4390
+ * smack_watch_key - Smack access to watch a key for notifications.
4391
+ * @key: The key to be watched
4392
+ *
4393
+ * Return 0 if the @watch->cred has permission to read from the key object and
4394
+ * an error otherwise.
4395
+ */
4396
+static int smack_watch_key(struct key *key)
4397
+{
4398
+ struct smk_audit_info ad;
4399
+ struct smack_known *tkp = smk_of_current();
4400
+ int rc;
4401
+
4402
+ if (key == NULL)
4403
+ return -EINVAL;
4404
+ /*
4405
+ * If the key hasn't been initialized give it access so that
4406
+ * it may do so.
4407
+ */
4408
+ if (key->security == NULL)
4409
+ return 0;
4410
+ /*
4411
+ * This should not occur
4412
+ */
4413
+ if (tkp == NULL)
4414
+ return -EACCES;
4415
+
4416
+ if (smack_privileged_cred(CAP_MAC_OVERRIDE, current_cred()))
4417
+ return 0;
4418
+
4419
+#ifdef CONFIG_AUDIT
4420
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_KEY);
4421
+ ad.a.u.key_struct.key = key->serial;
4422
+ ad.a.u.key_struct.key_desc = key->description;
4423
+#endif
4424
+ rc = smk_access(tkp, key->security, MAY_READ, &ad);
4425
+ rc = smk_bu_note("key watch", tkp, key->security, MAY_READ, rc);
4426
+ return rc;
4427
+}
4428
+#endif /* CONFIG_KEY_NOTIFICATIONS */
44064429 #endif /* CONFIG_KEYS */
4430
+
4431
+#ifdef CONFIG_WATCH_QUEUE
4432
+/**
4433
+ * smack_post_notification - Smack access to post a notification to a queue
4434
+ * @w_cred: The credentials of the watcher.
4435
+ * @cred: The credentials of the event source (may be NULL).
4436
+ * @n: The notification message to be posted.
4437
+ */
4438
+static int smack_post_notification(const struct cred *w_cred,
4439
+ const struct cred *cred,
4440
+ struct watch_notification *n)
4441
+{
4442
+ struct smk_audit_info ad;
4443
+ struct smack_known *subj, *obj;
4444
+ int rc;
4445
+
4446
+ /* Always let maintenance notifications through. */
4447
+ if (n->type == WATCH_TYPE_META)
4448
+ return 0;
4449
+
4450
+ if (!cred)
4451
+ return 0;
4452
+ subj = smk_of_task(smack_cred(cred));
4453
+ obj = smk_of_task(smack_cred(w_cred));
4454
+
4455
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NOTIFICATION);
4456
+ rc = smk_access(subj, obj, MAY_WRITE, &ad);
4457
+ rc = smk_bu_note("notification", subj, obj, MAY_WRITE, rc);
4458
+ return rc;
4459
+}
4460
+#endif /* CONFIG_WATCH_QUEUE */
44074461
44084462 /*
44094463 * Smack Audit hooks
....@@ -4480,13 +4534,11 @@
44804534 * @field: audit rule flags given from user-space
44814535 * @op: required testing operator
44824536 * @vrule: smack internal rule presentation
4483
- * @actx: audit context associated with the check
44844537 *
44854538 * The core Audit hook. It's used to take the decision of
44864539 * whether to audit or not to audit a given object.
44874540 */
4488
-static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule,
4489
- struct audit_context *actx)
4541
+static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule)
44904542 {
44914543 struct smack_known *skp;
44924544 char *rule = vrule;
....@@ -4607,12 +4659,12 @@
46074659 return -ENOMEM;
46084660 }
46094661
4610
- tsp = new_creds->security;
4662
+ tsp = smack_cred(new_creds);
46114663
46124664 /*
46134665 * Get label from overlay inode and set it in create_sid
46144666 */
4615
- isp = d_inode(dentry->d_parent)->i_security;
4667
+ isp = smack_inode(d_inode(dentry));
46164668 skp = isp->smk_inode;
46174669 tsp->smk_task = skp;
46184670 *new = new_creds;
....@@ -4635,8 +4687,8 @@
46354687 const struct cred *old,
46364688 struct cred *new)
46374689 {
4638
- struct task_smack *otsp = old->security;
4639
- struct task_smack *ntsp = new->security;
4690
+ struct task_smack *otsp = smack_cred(old);
4691
+ struct task_smack *ntsp = smack_cred(new);
46404692 struct inode_smack *isp;
46414693 int may;
46424694
....@@ -4649,7 +4701,7 @@
46494701 /*
46504702 * the attribute of the containing directory
46514703 */
4652
- isp = d_inode(dentry->d_parent)->i_security;
4704
+ isp = smack_inode(d_inode(dentry->d_parent));
46534705
46544706 if (isp->smk_flags & SMK_INODE_TRANSMUTE) {
46554707 rcu_read_lock();
....@@ -4663,29 +4715,40 @@
46634715 * providing access is transmuting use the containing
46644716 * directory label instead of the process label.
46654717 */
4666
- if (may > 0 && (may & MAY_TRANSMUTE))
4718
+ if (may > 0 && (may & MAY_TRANSMUTE)) {
46674719 ntsp->smk_task = isp->smk_inode;
4720
+ ntsp->smk_transmuted = ntsp->smk_task;
4721
+ }
46684722 }
46694723 return 0;
46704724 }
4725
+
4726
+struct lsm_blob_sizes smack_blob_sizes __lsm_ro_after_init = {
4727
+ .lbs_cred = sizeof(struct task_smack),
4728
+ .lbs_file = sizeof(struct smack_known *),
4729
+ .lbs_inode = sizeof(struct inode_smack),
4730
+ .lbs_ipc = sizeof(struct smack_known *),
4731
+ .lbs_msg_msg = sizeof(struct smack_known *),
4732
+};
46714733
46724734 static struct security_hook_list smack_hooks[] __lsm_ro_after_init = {
46734735 LSM_HOOK_INIT(ptrace_access_check, smack_ptrace_access_check),
46744736 LSM_HOOK_INIT(ptrace_traceme, smack_ptrace_traceme),
46754737 LSM_HOOK_INIT(syslog, smack_syslog),
46764738
4739
+ LSM_HOOK_INIT(fs_context_dup, smack_fs_context_dup),
4740
+ LSM_HOOK_INIT(fs_context_parse_param, smack_fs_context_parse_param),
4741
+
46774742 LSM_HOOK_INIT(sb_alloc_security, smack_sb_alloc_security),
46784743 LSM_HOOK_INIT(sb_free_security, smack_sb_free_security),
4679
- LSM_HOOK_INIT(sb_copy_data, smack_sb_copy_data),
4680
- LSM_HOOK_INIT(sb_kern_mount, smack_sb_kern_mount),
4744
+ LSM_HOOK_INIT(sb_free_mnt_opts, smack_free_mnt_opts),
4745
+ LSM_HOOK_INIT(sb_eat_lsm_opts, smack_sb_eat_lsm_opts),
46814746 LSM_HOOK_INIT(sb_statfs, smack_sb_statfs),
46824747 LSM_HOOK_INIT(sb_set_mnt_opts, smack_set_mnt_opts),
4683
- LSM_HOOK_INIT(sb_parse_opts_str, smack_parse_opts_str),
46844748
4685
- LSM_HOOK_INIT(bprm_set_creds, smack_bprm_set_creds),
4749
+ LSM_HOOK_INIT(bprm_creds_for_exec, smack_bprm_creds_for_exec),
46864750
46874751 LSM_HOOK_INIT(inode_alloc_security, smack_inode_alloc_security),
4688
- LSM_HOOK_INIT(inode_free_security, smack_inode_free_security),
46894752 LSM_HOOK_INIT(inode_init_security, smack_inode_init_security),
46904753 LSM_HOOK_INIT(inode_link, smack_inode_link),
46914754 LSM_HOOK_INIT(inode_unlink, smack_inode_unlink),
....@@ -4704,7 +4767,6 @@
47044767 LSM_HOOK_INIT(inode_getsecid, smack_inode_getsecid),
47054768
47064769 LSM_HOOK_INIT(file_alloc_security, smack_file_alloc_security),
4707
- LSM_HOOK_INIT(file_free_security, smack_file_free_security),
47084770 LSM_HOOK_INIT(file_ioctl, smack_file_ioctl),
47094771 LSM_HOOK_INIT(file_lock, smack_file_lock),
47104772 LSM_HOOK_INIT(file_fcntl, smack_file_fcntl),
....@@ -4740,23 +4802,19 @@
47404802 LSM_HOOK_INIT(ipc_getsecid, smack_ipc_getsecid),
47414803
47424804 LSM_HOOK_INIT(msg_msg_alloc_security, smack_msg_msg_alloc_security),
4743
- LSM_HOOK_INIT(msg_msg_free_security, smack_msg_msg_free_security),
47444805
47454806 LSM_HOOK_INIT(msg_queue_alloc_security, smack_ipc_alloc_security),
4746
- LSM_HOOK_INIT(msg_queue_free_security, smack_ipc_free_security),
47474807 LSM_HOOK_INIT(msg_queue_associate, smack_msg_queue_associate),
47484808 LSM_HOOK_INIT(msg_queue_msgctl, smack_msg_queue_msgctl),
47494809 LSM_HOOK_INIT(msg_queue_msgsnd, smack_msg_queue_msgsnd),
47504810 LSM_HOOK_INIT(msg_queue_msgrcv, smack_msg_queue_msgrcv),
47514811
47524812 LSM_HOOK_INIT(shm_alloc_security, smack_ipc_alloc_security),
4753
- LSM_HOOK_INIT(shm_free_security, smack_ipc_free_security),
47544813 LSM_HOOK_INIT(shm_associate, smack_shm_associate),
47554814 LSM_HOOK_INIT(shm_shmctl, smack_shm_shmctl),
47564815 LSM_HOOK_INIT(shm_shmat, smack_shm_shmat),
47574816
47584817 LSM_HOOK_INIT(sem_alloc_security, smack_ipc_alloc_security),
4759
- LSM_HOOK_INIT(sem_free_security, smack_ipc_free_security),
47604818 LSM_HOOK_INIT(sem_associate, smack_sem_associate),
47614819 LSM_HOOK_INIT(sem_semctl, smack_sem_semctl),
47624820 LSM_HOOK_INIT(sem_semop, smack_sem_semop),
....@@ -4791,7 +4849,14 @@
47914849 LSM_HOOK_INIT(key_free, smack_key_free),
47924850 LSM_HOOK_INIT(key_permission, smack_key_permission),
47934851 LSM_HOOK_INIT(key_getsecurity, smack_key_getsecurity),
4852
+#ifdef CONFIG_KEY_NOTIFICATIONS
4853
+ LSM_HOOK_INIT(watch_key, smack_watch_key),
4854
+#endif
47944855 #endif /* CONFIG_KEYS */
4856
+
4857
+#ifdef CONFIG_WATCH_QUEUE
4858
+ LSM_HOOK_INIT(post_notification, smack_post_notification),
4859
+#endif
47954860
47964861 /* Audit hooks */
47974862 #ifdef CONFIG_AUDIT
....@@ -4843,27 +4908,27 @@
48434908 /**
48444909 * smack_init - initialize the smack system
48454910 *
4846
- * Returns 0
4911
+ * Returns 0 on success, -ENOMEM is there's no memory
48474912 */
48484913 static __init int smack_init(void)
48494914 {
4850
- struct cred *cred;
4915
+ struct cred *cred = (struct cred *) current->cred;
48514916 struct task_smack *tsp;
48524917
4853
- if (!security_module_enable("smack"))
4854
- return 0;
4855
-
4856
- smack_inode_cache = KMEM_CACHE(inode_smack, 0);
4857
- if (!smack_inode_cache)
4918
+ smack_rule_cache = KMEM_CACHE(smack_rule, 0);
4919
+ if (!smack_rule_cache)
48584920 return -ENOMEM;
48594921
4860
- tsp = new_task_smack(&smack_known_floor, &smack_known_floor,
4861
- GFP_KERNEL);
4862
- if (tsp == NULL) {
4863
- kmem_cache_destroy(smack_inode_cache);
4864
- return -ENOMEM;
4865
- }
4922
+ /*
4923
+ * Set the security state for the initial task.
4924
+ */
4925
+ tsp = smack_cred(cred);
4926
+ init_task_smack(tsp, &smack_known_floor, &smack_known_floor);
48664927
4928
+ /*
4929
+ * Register with LSM
4930
+ */
4931
+ security_add_hooks(smack_hooks, ARRAY_SIZE(smack_hooks), "smack");
48674932 smack_enabled = 1;
48684933
48694934 pr_info("Smack: Initializing.\n");
....@@ -4877,19 +4942,8 @@
48774942 pr_info("Smack: IPv6 Netfilter enabled.\n");
48784943 #endif
48794944
4880
- /*
4881
- * Set the security state for the initial task.
4882
- */
4883
- cred = (struct cred *) current->cred;
4884
- cred->security = tsp;
4885
-
48864945 /* initialize the smack_known_list */
48874946 init_smack_known_list();
4888
-
4889
- /*
4890
- * Register with LSM
4891
- */
4892
- security_add_hooks(smack_hooks, ARRAY_SIZE(smack_hooks), "smack");
48934947
48944948 return 0;
48954949 }
....@@ -4898,4 +4952,9 @@
48984952 * Smack requires early initialization in order to label
48994953 * all processes and objects when they are created.
49004954 */
4901
-security_initcall(smack_init);
4955
+DEFINE_LSM(smack) = {
4956
+ .name = "smack",
4957
+ .flags = LSM_FLAG_LEGACY_MAJOR | LSM_FLAG_EXCLUSIVE,
4958
+ .blobs = &smack_blob_sizes,
4959
+ .init = smack_init,
4960
+};