forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 1f93a7dfd1f8d5ff7a5c53246c7534fe2332d6f4
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,7 +973,7 @@
1032973 const struct qstr *qstr, const char **name,
1033974 void **value, size_t *len)
1034975 {
1035
- struct inode_smack *issp = inode->i_security;
976
+ struct inode_smack *issp = smack_inode(inode);
1036977 struct smack_known *skp = smk_of_current();
1037978 struct smack_known *isp = smk_of_inode(inode);
1038979 struct smack_known *dsp = smk_of_inode(dir);
....@@ -1213,7 +1154,7 @@
12131154 *
12141155 * This is the important Smack hook.
12151156 *
1216
- * Returns 0 if access is permitted, -EACCES otherwise
1157
+ * Returns 0 if access is permitted, an error code otherwise
12171158 */
12181159 static int smack_inode_permission(struct inode *inode, int mask)
12191160 {
....@@ -1271,8 +1212,7 @@
12711212
12721213 /**
12731214 * smack_inode_getattr - Smack check for getting attributes
1274
- * @mnt: vfsmount of the object
1275
- * @dentry: the object
1215
+ * @path: path to extract the info from
12761216 *
12771217 * Returns 0 if access is permitted, an error code otherwise
12781218 */
....@@ -1370,7 +1310,7 @@
13701310 const void *value, size_t size, int flags)
13711311 {
13721312 struct smack_known *skp;
1373
- struct inode_smack *isp = d_backing_inode(dentry)->i_security;
1313
+ struct inode_smack *isp = smack_inode(d_backing_inode(dentry));
13741314
13751315 if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) {
13761316 isp->smk_flags |= SMK_INODE_TRANSMUTE;
....@@ -1451,7 +1391,7 @@
14511391 if (rc != 0)
14521392 return rc;
14531393
1454
- isp = d_backing_inode(dentry)->i_security;
1394
+ isp = smack_inode(d_backing_inode(dentry));
14551395 /*
14561396 * Don't do anything special for these.
14571397 * XATTR_NAME_SMACKIPIN
....@@ -1583,22 +1523,10 @@
15831523 */
15841524 static int smack_file_alloc_security(struct file *file)
15851525 {
1586
- struct smack_known *skp = smk_of_current();
1526
+ struct smack_known **blob = smack_file(file);
15871527
1588
- file->f_security = skp;
1528
+ *blob = smk_of_current();
15891529 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;
16021530 }
16031531
16041532 /**
....@@ -1738,7 +1666,7 @@
17381666 if (unlikely(IS_PRIVATE(file_inode(file))))
17391667 return 0;
17401668
1741
- isp = file_inode(file)->i_security;
1669
+ isp = smack_inode(file_inode(file));
17421670 if (isp->smk_mmap == NULL)
17431671 return 0;
17441672 sbsp = file_inode(file)->i_sb->s_security;
....@@ -1747,7 +1675,7 @@
17471675 return -EACCES;
17481676 mkp = isp->smk_mmap;
17491677
1750
- tsp = current_security();
1678
+ tsp = smack_cred(current_cred());
17511679 skp = smk_of_current();
17521680 rc = 0;
17531681
....@@ -1825,7 +1753,9 @@
18251753 */
18261754 static void smack_file_set_fowner(struct file *file)
18271755 {
1828
- file->f_security = smk_of_current();
1756
+ struct smack_known **blob = smack_file(file);
1757
+
1758
+ *blob = smk_of_current();
18291759 }
18301760
18311761 /**
....@@ -1842,8 +1772,9 @@
18421772 static int smack_file_send_sigiotask(struct task_struct *tsk,
18431773 struct fown_struct *fown, int signum)
18441774 {
1775
+ struct smack_known **blob;
18451776 struct smack_known *skp;
1846
- struct smack_known *tkp = smk_of_task(tsk->cred->security);
1777
+ struct smack_known *tkp = smk_of_task(smack_cred(tsk->cred));
18471778 const struct cred *tcred;
18481779 struct file *file;
18491780 int rc;
....@@ -1855,7 +1786,8 @@
18551786 file = container_of(fown, struct file, f_owner);
18561787
18571788 /* we don't log here as rc can be overriden */
1858
- skp = file->f_security;
1789
+ blob = smack_file(file);
1790
+ skp = *blob;
18591791 rc = smk_access(skp, tkp, MAY_DELIVER, NULL);
18601792 rc = smk_bu_note("sigiotask", skp, tkp, MAY_DELIVER, rc);
18611793
....@@ -1896,7 +1828,7 @@
18961828 if (inode->i_sb->s_magic == SOCKFS_MAGIC) {
18971829 sock = SOCKET_I(inode);
18981830 ssp = sock->sk->sk_security;
1899
- tsp = current_security();
1831
+ tsp = smack_cred(current_cred());
19001832 /*
19011833 * If the receiving process can't write to the
19021834 * passed socket or if the passed socket can't
....@@ -1927,18 +1859,17 @@
19271859 /**
19281860 * smack_file_open - Smack dentry open processing
19291861 * @file: the object
1930
- * @cred: task credential
19311862 *
19321863 * Set the security blob in the file structure.
19331864 * Allow the open only if the task has read access. There are
19341865 * many read operations (e.g. fstat) that you can do with an
19351866 * fd even if you have the file open write-only.
19361867 *
1937
- * Returns 0
1868
+ * Returns 0 if current has access, error code otherwise
19381869 */
19391870 static int smack_file_open(struct file *file)
19401871 {
1941
- struct task_smack *tsp = file->f_cred->security;
1872
+ struct task_smack *tsp = smack_cred(file->f_cred);
19421873 struct inode *inode = file_inode(file);
19431874 struct smk_audit_info ad;
19441875 int rc;
....@@ -1957,7 +1888,7 @@
19571888
19581889 /**
19591890 * smack_cred_alloc_blank - "allocate" blank task-level security credentials
1960
- * @new: the new credentials
1891
+ * @cred: the new credentials
19611892 * @gfp: the atomicity of any memory allocations
19621893 *
19631894 * Prepare a blank set of credentials for modification. This must allocate all
....@@ -1966,14 +1897,7 @@
19661897 */
19671898 static int smack_cred_alloc_blank(struct cred *cred, gfp_t gfp)
19681899 {
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
-
1900
+ init_task_smack(smack_cred(cred), NULL, NULL);
19771901 return 0;
19781902 }
19791903
....@@ -1985,23 +1909,18 @@
19851909 */
19861910 static void smack_cred_free(struct cred *cred)
19871911 {
1988
- struct task_smack *tsp = cred->security;
1912
+ struct task_smack *tsp = smack_cred(cred);
19891913 struct smack_rule *rp;
19901914 struct list_head *l;
19911915 struct list_head *n;
1992
-
1993
- if (tsp == NULL)
1994
- return;
1995
- cred->security = NULL;
19961916
19971917 smk_destroy_label_list(&tsp->smk_relabel);
19981918
19991919 list_for_each_safe(l, n, &tsp->smk_rules) {
20001920 rp = list_entry(l, struct smack_rule, list);
20011921 list_del(&rp->list);
2002
- kfree(rp);
1922
+ kmem_cache_free(smack_rule_cache, rp);
20031923 }
2004
- kfree(tsp);
20051924 }
20061925
20071926 /**
....@@ -2015,15 +1934,11 @@
20151934 static int smack_cred_prepare(struct cred *new, const struct cred *old,
20161935 gfp_t gfp)
20171936 {
2018
- struct task_smack *old_tsp = old->security;
2019
- struct task_smack *new_tsp;
1937
+ struct task_smack *old_tsp = smack_cred(old);
1938
+ struct task_smack *new_tsp = smack_cred(new);
20201939 int rc;
20211940
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;
1941
+ init_task_smack(new_tsp, old_tsp->smk_task, old_tsp->smk_task);
20271942
20281943 rc = smk_copy_rules(&new_tsp->smk_rules, &old_tsp->smk_rules, gfp);
20291944 if (rc != 0)
....@@ -2031,10 +1946,7 @@
20311946
20321947 rc = smk_copy_relabel(&new_tsp->smk_relabel, &old_tsp->smk_relabel,
20331948 gfp);
2034
- if (rc != 0)
2035
- return rc;
2036
-
2037
- return 0;
1949
+ return rc;
20381950 }
20391951
20401952 /**
....@@ -2046,31 +1958,30 @@
20461958 */
20471959 static void smack_cred_transfer(struct cred *new, const struct cred *old)
20481960 {
2049
- struct task_smack *old_tsp = old->security;
2050
- struct task_smack *new_tsp = new->security;
1961
+ struct task_smack *old_tsp = smack_cred(old);
1962
+ struct task_smack *new_tsp = smack_cred(new);
20511963
20521964 new_tsp->smk_task = old_tsp->smk_task;
20531965 new_tsp->smk_forked = old_tsp->smk_task;
20541966 mutex_init(&new_tsp->smk_rules_lock);
20551967 INIT_LIST_HEAD(&new_tsp->smk_rules);
20561968
2057
-
20581969 /* cbs copy rule list */
20591970 }
20601971
20611972 /**
20621973 * smack_cred_getsecid - get the secid corresponding to a creds structure
2063
- * @c: the object creds
1974
+ * @cred: the object creds
20641975 * @secid: where to put the result
20651976 *
20661977 * Sets the secid to contain a u32 version of the smack label.
20671978 */
2068
-static void smack_cred_getsecid(const struct cred *c, u32 *secid)
1979
+static void smack_cred_getsecid(const struct cred *cred, u32 *secid)
20691980 {
20701981 struct smack_known *skp;
20711982
20721983 rcu_read_lock();
2073
- skp = smk_of_task(c->security);
1984
+ skp = smk_of_task(smack_cred(cred));
20741985 *secid = skp->smk_secid;
20751986 rcu_read_unlock();
20761987 }
....@@ -2084,7 +1995,7 @@
20841995 */
20851996 static int smack_kernel_act_as(struct cred *new, u32 secid)
20861997 {
2087
- struct task_smack *new_tsp = new->security;
1998
+ struct task_smack *new_tsp = smack_cred(new);
20881999
20892000 new_tsp->smk_task = smack_from_secid(secid);
20902001 return 0;
....@@ -2101,8 +2012,8 @@
21012012 static int smack_kernel_create_files_as(struct cred *new,
21022013 struct inode *inode)
21032014 {
2104
- struct inode_smack *isp = inode->i_security;
2105
- struct task_smack *tsp = new->security;
2015
+ struct inode_smack *isp = smack_inode(inode);
2016
+ struct task_smack *tsp = smack_cred(new);
21062017
21072018 tsp->smk_forked = isp->smk_inode;
21082019 tsp->smk_task = tsp->smk_forked;
....@@ -2217,8 +2128,6 @@
22172128 /**
22182129 * smack_task_setscheduler - Smack check on setting scheduler
22192130 * @p: the task object
2220
- * @policy: unused
2221
- * @lp: unused
22222131 *
22232132 * Return 0 if read access is permitted
22242133 */
....@@ -2259,7 +2168,7 @@
22592168 * Return 0 if write access is permitted
22602169 *
22612170 */
2262
-static int smack_task_kill(struct task_struct *p, struct siginfo *info,
2171
+static int smack_task_kill(struct task_struct *p, struct kernel_siginfo *info,
22632172 int sig, const struct cred *cred)
22642173 {
22652174 struct smk_audit_info ad;
....@@ -2286,7 +2195,7 @@
22862195 * specific behavior. This is not clean. For one thing
22872196 * we can't take privilege into account.
22882197 */
2289
- skp = smk_of_task(cred->security);
2198
+ skp = smk_of_task(smack_cred(cred));
22902199 rc = smk_access(skp, tkp, MAY_DELIVER, &ad);
22912200 rc = smk_bu_note("USB signal", skp, tkp, MAY_DELIVER, rc);
22922201 return rc;
....@@ -2301,7 +2210,7 @@
23012210 */
23022211 static void smack_task_to_inode(struct task_struct *p, struct inode *inode)
23032212 {
2304
- struct inode_smack *isp = inode->i_security;
2213
+ struct inode_smack *isp = smack_inode(inode);
23052214 struct smack_known *skp = smk_of_task_struct(p);
23062215
23072216 isp->smk_inode = skp;
....@@ -2406,7 +2315,6 @@
24062315 return NULL;
24072316 }
24082317
2409
-#if IS_ENABLED(CONFIG_IPV6)
24102318 /*
24112319 * smk_ipv6_localhost - Check for local ipv6 host address
24122320 * @sip: the address
....@@ -2474,41 +2382,33 @@
24742382
24752383 return NULL;
24762384 }
2477
-#endif /* CONFIG_IPV6 */
24782385
24792386 /**
2480
- * smack_netlabel - Set the secattr on a socket
2387
+ * smack_netlbl_add - Set the secattr on a socket
24812388 * @sk: the socket
2482
- * @labeled: socket label scheme
24832389 *
2484
- * Convert the outbound smack value (smk_out) to a
2485
- * secattr and attach it to the socket.
2390
+ * Attach the outbound smack value (smk_out) to the socket.
24862391 *
24872392 * Returns 0 on success or an error code
24882393 */
2489
-static int smack_netlabel(struct sock *sk, int labeled)
2394
+static int smack_netlbl_add(struct sock *sk)
24902395 {
2491
- struct smack_known *skp;
24922396 struct socket_smack *ssp = sk->sk_security;
2493
- int rc = 0;
2397
+ struct smack_known *skp = ssp->smk_out;
2398
+ int rc;
24942399
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
- */
25032400 local_bh_disable();
25042401 bh_lock_sock_nested(sk);
25052402
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);
2403
+ rc = netlbl_sock_setattr(sk, sk->sk_family, &skp->smk_netlabel);
2404
+ switch (rc) {
2405
+ case 0:
2406
+ ssp->smk_state = SMK_NETLBL_LABELED;
2407
+ break;
2408
+ case -EDESTADDRREQ:
2409
+ ssp->smk_state = SMK_NETLBL_REQSKB;
2410
+ rc = 0;
2411
+ break;
25122412 }
25132413
25142414 bh_unlock_sock(sk);
....@@ -2518,7 +2418,31 @@
25182418 }
25192419
25202420 /**
2521
- * smack_netlbel_send - Set the secattr on a socket and perform access checks
2421
+ * smack_netlbl_delete - Remove the secattr from a socket
2422
+ * @sk: the socket
2423
+ *
2424
+ * Remove the outbound smack value from a socket
2425
+ */
2426
+static void smack_netlbl_delete(struct sock *sk)
2427
+{
2428
+ struct socket_smack *ssp = sk->sk_security;
2429
+
2430
+ /*
2431
+ * Take the label off the socket if one is set.
2432
+ */
2433
+ if (ssp->smk_state != SMK_NETLBL_LABELED)
2434
+ return;
2435
+
2436
+ local_bh_disable();
2437
+ bh_lock_sock_nested(sk);
2438
+ netlbl_sock_delattr(sk);
2439
+ bh_unlock_sock(sk);
2440
+ local_bh_enable();
2441
+ ssp->smk_state = SMK_NETLBL_UNLABELED;
2442
+}
2443
+
2444
+/**
2445
+ * smk_ipv4_check - Perform IPv4 host access checks
25222446 * @sk: the socket
25232447 * @sap: the destination address
25242448 *
....@@ -2528,11 +2452,10 @@
25282452 * Returns 0 on success or an error code.
25292453 *
25302454 */
2531
-static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap)
2455
+static int smk_ipv4_check(struct sock *sk, struct sockaddr_in *sap)
25322456 {
25332457 struct smack_known *skp;
2534
- int rc;
2535
- int sk_lbl;
2458
+ int rc = 0;
25362459 struct smack_known *hkp;
25372460 struct socket_smack *ssp = sk->sk_security;
25382461 struct smk_audit_info ad;
....@@ -2548,22 +2471,20 @@
25482471 ad.a.u.net->dport = sap->sin_port;
25492472 ad.a.u.net->v4info.daddr = sap->sin_addr.s_addr;
25502473 #endif
2551
- sk_lbl = SMACK_UNLABELED_SOCKET;
25522474 skp = ssp->smk_out;
25532475 rc = smk_access(skp, hkp, MAY_WRITE, &ad);
25542476 rc = smk_bu_note("IPv4 host check", skp, hkp, MAY_WRITE, rc);
2555
- } else {
2556
- sk_lbl = SMACK_CIPSO_SOCKET;
2557
- rc = 0;
2477
+ /*
2478
+ * Clear the socket netlabel if it's set.
2479
+ */
2480
+ if (!rc)
2481
+ smack_netlbl_delete(sk);
25582482 }
25592483 rcu_read_unlock();
2560
- if (rc != 0)
2561
- return rc;
25622484
2563
- return smack_netlabel(sk, sk_lbl);
2485
+ return rc;
25642486 }
25652487
2566
-#if IS_ENABLED(CONFIG_IPV6)
25672488 /**
25682489 * smk_ipv6_check - check Smack access
25692490 * @subject: subject Smack label
....@@ -2586,7 +2507,7 @@
25862507 #ifdef CONFIG_AUDIT
25872508 smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
25882509 ad.a.u.net->family = PF_INET6;
2589
- ad.a.u.net->dport = ntohs(address->sin6_port);
2510
+ ad.a.u.net->dport = address->sin6_port;
25902511 if (act == SMK_RECEIVING)
25912512 ad.a.u.net->v6info.saddr = address->sin6_addr;
25922513 else
....@@ -2596,7 +2517,6 @@
25962517 rc = smk_bu_note("IPv6 check", subject, object, MAY_WRITE, rc);
25972518 return rc;
25982519 }
2599
-#endif /* CONFIG_IPV6 */
26002520
26012521 #ifdef SMACK_IPV6_PORT_LABELING
26022522 /**
....@@ -2685,11 +2605,13 @@
26852605 mutex_unlock(&smack_ipv6_lock);
26862606 return;
26872607 }
2608
+#endif
26882609
26892610 /**
26902611 * smk_ipv6_port_check - check Smack port access
2691
- * @sock: socket
2612
+ * @sk: socket
26922613 * @address: address
2614
+ * @act: the action being taken
26932615 *
26942616 * Create or update the port list entry
26952617 */
....@@ -2746,7 +2668,6 @@
27462668
27472669 return smk_ipv6_check(skp, object, address, act);
27482670 }
2749
-#endif /* SMACK_IPV6_PORT_LABELING */
27502671
27512672 /**
27522673 * smack_inode_setsecurity - set smack xattrs
....@@ -2764,7 +2685,7 @@
27642685 const void *value, size_t size, int flags)
27652686 {
27662687 struct smack_known *skp;
2767
- struct inode_smack *nsp = inode->i_security;
2688
+ struct inode_smack *nsp = smack_inode(inode);
27682689 struct socket_smack *ssp;
27692690 struct socket *sock;
27702691 int rc = 0;
....@@ -2798,7 +2719,7 @@
27982719 else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) {
27992720 ssp->smk_out = skp;
28002721 if (sock->sk->sk_family == PF_INET) {
2801
- rc = smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET);
2722
+ rc = smack_netlbl_add(sock->sk);
28022723 if (rc != 0)
28032724 printk(KERN_WARNING
28042725 "Smack: \"%s\" netlbl error %d.\n",
....@@ -2849,7 +2770,7 @@
28492770 /*
28502771 * Set the outbound netlbl.
28512772 */
2852
- return smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET);
2773
+ return smack_netlbl_add(sock->sk);
28532774 }
28542775
28552776 /**
....@@ -2859,7 +2780,7 @@
28592780 *
28602781 * Cross reference the peer labels for SO_PEERSEC
28612782 *
2862
- * Returns 0 on success, and error code otherwise
2783
+ * Returns 0
28632784 */
28642785 static int smack_socket_socketpair(struct socket *socka,
28652786 struct socket *sockb)
....@@ -2882,13 +2803,17 @@
28822803 *
28832804 * Records the label bound to a port.
28842805 *
2885
- * Returns 0
2806
+ * Returns 0 on success, and error code otherwise
28862807 */
28872808 static int smack_socket_bind(struct socket *sock, struct sockaddr *address,
28882809 int addrlen)
28892810 {
2890
- if (sock->sk != NULL && sock->sk->sk_family == PF_INET6)
2811
+ if (sock->sk != NULL && sock->sk->sk_family == PF_INET6) {
2812
+ if (addrlen < SIN6_LEN_RFC2133 ||
2813
+ address->sa_family != AF_INET6)
2814
+ return -EINVAL;
28912815 smk_ipv6_port_label(sock, address);
2816
+ }
28922817 return 0;
28932818 }
28942819 #endif /* SMACK_IPV6_PORT_LABELING */
....@@ -2907,41 +2832,36 @@
29072832 int addrlen)
29082833 {
29092834 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
29172835
29182836 if (sock->sk == NULL)
29192837 return 0;
2838
+ if (sock->sk->sk_family != PF_INET &&
2839
+ (!IS_ENABLED(CONFIG_IPV6) || sock->sk->sk_family != PF_INET6))
2840
+ return 0;
2841
+ if (addrlen < offsetofend(struct sockaddr, sa_family))
2842
+ return 0;
2843
+ if (IS_ENABLED(CONFIG_IPV6) && sap->sa_family == AF_INET6) {
2844
+ struct sockaddr_in6 *sip = (struct sockaddr_in6 *)sap;
2845
+ struct smack_known *rsp = NULL;
29202846
2921
-#ifdef SMACK_IPV6_SECMARK_LABELING
2922
- ssp = sock->sk->sk_security;
2923
-#endif
2847
+ if (addrlen < SIN6_LEN_RFC2133)
2848
+ return 0;
2849
+ if (__is_defined(SMACK_IPV6_SECMARK_LABELING))
2850
+ rsp = smack_ipv6host_label(sip);
2851
+ if (rsp != NULL) {
2852
+ struct socket_smack *ssp = sock->sk->sk_security;
29242853
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)
29372854 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;
2855
+ SMK_CONNECTING);
2856
+ }
2857
+ if (__is_defined(SMACK_IPV6_PORT_LABELING))
2858
+ rc = smk_ipv6_port_check(sock->sk, sip, SMK_CONNECTING);
2859
+
2860
+ return rc;
29442861 }
2862
+ if (sap->sa_family != AF_INET || addrlen < sizeof(struct sockaddr_in))
2863
+ return 0;
2864
+ rc = smk_ipv4_check(sock->sk, (struct sockaddr_in *)sap);
29452865 return rc;
29462866 }
29472867
....@@ -2973,21 +2893,10 @@
29732893 */
29742894 static int smack_msg_msg_alloc_security(struct msg_msg *msg)
29752895 {
2976
- struct smack_known *skp = smk_of_current();
2896
+ struct smack_known **blob = smack_msg_msg(msg);
29772897
2978
- msg->security = skp;
2898
+ *blob = smk_of_current();
29792899 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;
29912900 }
29922901
29932902 /**
....@@ -2998,7 +2907,9 @@
29982907 */
29992908 static struct smack_known *smack_of_ipc(struct kern_ipc_perm *isp)
30002909 {
3001
- return (struct smack_known *)isp->security;
2910
+ struct smack_known **blob = smack_ipc(isp);
2911
+
2912
+ return *blob;
30022913 }
30032914
30042915 /**
....@@ -3009,21 +2920,10 @@
30092920 */
30102921 static int smack_ipc_alloc_security(struct kern_ipc_perm *isp)
30112922 {
3012
- struct smack_known *skp = smk_of_current();
2923
+ struct smack_known **blob = smack_ipc(isp);
30132924
3014
- isp->security = skp;
2925
+ *blob = smk_of_current();
30152926 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;
30272927 }
30282928
30292929 /**
....@@ -3106,13 +3006,13 @@
31063006 *
31073007 * Returns 0 if current has the requested access, error code otherwise
31083008 */
3109
-static int smack_shm_shmat(struct kern_ipc_perm *ipc, char __user *shmaddr,
3009
+static int smack_shm_shmat(struct kern_ipc_perm *isp, char __user *shmaddr,
31103010 int shmflg)
31113011 {
31123012 int may;
31133013
31143014 may = smack_flags_to_may(shmflg);
3115
- return smk_curacc_shm(ipc, may);
3015
+ return smk_curacc_shm(isp, may);
31163016 }
31173017
31183018 /**
....@@ -3323,7 +3223,8 @@
33233223 */
33243224 static int smack_ipc_permission(struct kern_ipc_perm *ipp, short flag)
33253225 {
3326
- struct smack_known *iskp = ipp->security;
3226
+ struct smack_known **blob = smack_ipc(ipp);
3227
+ struct smack_known *iskp = *blob;
33273228 int may = smack_flags_to_may(flag);
33283229 struct smk_audit_info ad;
33293230 int rc;
....@@ -3344,7 +3245,8 @@
33443245 */
33453246 static void smack_ipc_getsecid(struct kern_ipc_perm *ipp, u32 *secid)
33463247 {
3347
- struct smack_known *iskp = ipp->security;
3248
+ struct smack_known **blob = smack_ipc(ipp);
3249
+ struct smack_known *iskp = *blob;
33483250
33493251 *secid = iskp->smk_secid;
33503252 }
....@@ -3372,15 +3274,14 @@
33723274 if (inode == NULL)
33733275 return;
33743276
3375
- isp = inode->i_security;
3277
+ isp = smack_inode(inode);
33763278
3377
- mutex_lock(&isp->smk_lock);
33783279 /*
33793280 * If the inode is already instantiated
33803281 * take the quick way out
33813282 */
33823283 if (isp->smk_flags & SMK_INODE_INSTANT)
3383
- goto unlockandout;
3284
+ return;
33843285
33853286 sbp = inode->i_sb;
33863287 sbsp = sbp->s_security;
....@@ -3431,7 +3332,7 @@
34313332 break;
34323333 }
34333334 isp->smk_flags |= SMK_INODE_INSTANT;
3434
- goto unlockandout;
3335
+ return;
34353336 }
34363337
34373338 /*
....@@ -3475,13 +3376,12 @@
34753376 */
34763377 final = &smack_known_star;
34773378 /*
3478
- * No break.
3479
- *
34803379 * If a smack value has been set we want to use it,
34813380 * but since tmpfs isn't giving us the opportunity
34823381 * to set mount options simulate setting the
34833382 * superblock default.
34843383 */
3384
+ fallthrough;
34853385 default:
34863386 /*
34873387 * This isn't an understood special case.
....@@ -3533,7 +3433,7 @@
35333433 } else {
35343434 rc = __vfs_getxattr(dp, inode,
35353435 XATTR_NAME_SMACKTRANSMUTE, trattr,
3536
- TRANS_TRUE_SIZE);
3436
+ TRANS_TRUE_SIZE, XATTR_NOSECURITY);
35373437 if (rc >= 0 && strncmp(trattr, TRANS_TRUE,
35383438 TRANS_TRUE_SIZE) != 0)
35393439 rc = -EINVAL;
....@@ -3567,8 +3467,6 @@
35673467
35683468 isp->smk_flags |= (SMK_INODE_INSTANT | transflag);
35693469
3570
-unlockandout:
3571
- mutex_unlock(&isp->smk_lock);
35723470 return;
35733471 }
35743472
....@@ -3613,7 +3511,7 @@
36133511 */
36143512 static int smack_setprocattr(const char *name, void *value, size_t size)
36153513 {
3616
- struct task_smack *tsp = current_security();
3514
+ struct task_smack *tsp = smack_cred(current_cred());
36173515 struct cred *new;
36183516 struct smack_known *skp;
36193517 struct smack_known_list_elem *sklep;
....@@ -3654,7 +3552,7 @@
36543552 if (new == NULL)
36553553 return -ENOMEM;
36563554
3657
- tsp = new->security;
3555
+ tsp = smack_cred(new);
36583556 tsp->smk_task = skp;
36593557 /*
36603558 * process can change its label only once
....@@ -3778,9 +3676,16 @@
37783676
37793677 switch (sock->sk->sk_family) {
37803678 case AF_INET:
3781
- rc = smack_netlabel_send(sock->sk, sip);
3679
+ if (msg->msg_namelen < sizeof(struct sockaddr_in) ||
3680
+ sip->sin_family != AF_INET)
3681
+ return -EINVAL;
3682
+ rc = smk_ipv4_check(sock->sk, sip);
37823683 break;
3684
+#if IS_ENABLED(CONFIG_IPV6)
37833685 case AF_INET6:
3686
+ if (msg->msg_namelen < SIN6_LEN_RFC2133 ||
3687
+ sap->sin6_family != AF_INET6)
3688
+ return -EINVAL;
37843689 #ifdef SMACK_IPV6_SECMARK_LABELING
37853690 rsp = smack_ipv6host_label(sap);
37863691 if (rsp != NULL)
....@@ -3790,6 +3695,7 @@
37903695 #ifdef SMACK_IPV6_PORT_LABELING
37913696 rc = smk_ipv6_port_check(sock->sk, sap, SMK_SENDING);
37923697 #endif
3698
+#endif /* IS_ENABLED(CONFIG_IPV6) */
37933699 break;
37943700 }
37953701 return rc;
....@@ -3809,6 +3715,18 @@
38093715 int found = 0;
38103716 int acat;
38113717 int kcat;
3718
+
3719
+ /*
3720
+ * Netlabel found it in the cache.
3721
+ */
3722
+ if ((sap->flags & NETLBL_SECATTR_CACHE) != 0)
3723
+ return (struct smack_known *)sap->cache->data;
3724
+
3725
+ if ((sap->flags & NETLBL_SECATTR_SECID) != 0)
3726
+ /*
3727
+ * Looks like a fallback, which gives us a secid.
3728
+ */
3729
+ return smack_from_secid(sap->attr.secid);
38123730
38133731 if ((sap->flags & NETLBL_SECATTR_MLS_LVL) != 0) {
38143732 /*
....@@ -3857,11 +3775,6 @@
38573775 return &smack_known_web;
38583776 return &smack_known_star;
38593777 }
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);
38653778 /*
38663779 * Without guidance regarding the smack value
38673780 * for the packet fall back on the network
....@@ -3921,6 +3834,62 @@
39213834 #endif /* CONFIG_IPV6 */
39223835
39233836 /**
3837
+ * smack_from_skb - Smack data from the secmark in an skb
3838
+ * @skb: packet
3839
+ *
3840
+ * Returns smack_known of the secmark or NULL if that won't work.
3841
+ */
3842
+#ifdef CONFIG_NETWORK_SECMARK
3843
+static struct smack_known *smack_from_skb(struct sk_buff *skb)
3844
+{
3845
+ if (skb == NULL || skb->secmark == 0)
3846
+ return NULL;
3847
+
3848
+ return smack_from_secid(skb->secmark);
3849
+}
3850
+#else
3851
+static inline struct smack_known *smack_from_skb(struct sk_buff *skb)
3852
+{
3853
+ return NULL;
3854
+}
3855
+#endif
3856
+
3857
+/**
3858
+ * smack_from_netlbl - Smack data from the IP options in an skb
3859
+ * @sk: socket data came in on
3860
+ * @family: address family
3861
+ * @skb: packet
3862
+ *
3863
+ * Find the Smack label in the IP options. If it hasn't been
3864
+ * added to the netlabel cache, add it here.
3865
+ *
3866
+ * Returns smack_known of the IP options or NULL if that won't work.
3867
+ */
3868
+static struct smack_known *smack_from_netlbl(struct sock *sk, u16 family,
3869
+ struct sk_buff *skb)
3870
+{
3871
+ struct netlbl_lsm_secattr secattr;
3872
+ struct socket_smack *ssp = NULL;
3873
+ struct smack_known *skp = NULL;
3874
+ int rc;
3875
+
3876
+ netlbl_secattr_init(&secattr);
3877
+
3878
+ if (sk)
3879
+ ssp = sk->sk_security;
3880
+
3881
+ if (netlbl_skbuff_getattr(skb, family, &secattr) == 0) {
3882
+ skp = smack_from_secattr(&secattr, ssp);
3883
+ if (secattr.flags & NETLBL_SECATTR_CACHEABLE)
3884
+ rc = netlbl_cache_add(skb, family, &skp->smk_netlabel);
3885
+ }
3886
+
3887
+ netlbl_secattr_destroy(&secattr);
3888
+
3889
+ return skp;
3890
+}
3891
+
3892
+/**
39243893 * smack_socket_sock_rcv_skb - Smack packet delivery access check
39253894 * @sk: socket
39263895 * @skb: packet
....@@ -3929,7 +3898,6 @@
39293898 */
39303899 static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
39313900 {
3932
- struct netlbl_lsm_secattr secattr;
39333901 struct socket_smack *ssp = sk->sk_security;
39343902 struct smack_known *skp = NULL;
39353903 int rc = 0;
....@@ -3948,33 +3916,18 @@
39483916
39493917 switch (family) {
39503918 case PF_INET:
3951
-#ifdef CONFIG_SECURITY_SMACK_NETFILTER
39523919 /*
39533920 * If there is a secmark use it rather than the CIPSO label.
39543921 * If there is no secmark fall back to CIPSO.
39553922 * The secmark is assumed to reflect policy better.
39563923 */
3957
- if (skb && skb->secmark != 0) {
3958
- skp = smack_from_secid(skb->secmark);
3959
- goto access_check;
3924
+ skp = smack_from_skb(skb);
3925
+ if (skp == NULL) {
3926
+ skp = smack_from_netlbl(sk, family, skb);
3927
+ if (skp == NULL)
3928
+ skp = smack_net_ambient;
39603929 }
3961
-#endif /* CONFIG_SECURITY_SMACK_NETFILTER */
3962
- /*
3963
- * Translate what netlabel gave us.
3964
- */
3965
- netlbl_secattr_init(&secattr);
39663930
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
39783931 #ifdef CONFIG_AUDIT
39793932 smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
39803933 ad.a.u.net->family = family;
....@@ -4000,14 +3953,14 @@
40003953 proto != IPPROTO_TCP && proto != IPPROTO_DCCP)
40013954 break;
40023955 #ifdef SMACK_IPV6_SECMARK_LABELING
4003
- if (skb && skb->secmark != 0)
4004
- skp = smack_from_secid(skb->secmark);
4005
- else
3956
+ skp = smack_from_skb(skb);
3957
+ if (skp == NULL) {
3958
+ if (smk_ipv6_localhost(&sadd))
3959
+ break;
40063960 skp = smack_ipv6host_label(&sadd);
4007
- if (skp == NULL)
4008
- skp = smack_net_ambient;
4009
- if (skb == NULL)
4010
- break;
3961
+ if (skp == NULL)
3962
+ skp = smack_net_ambient;
3963
+ }
40113964 #ifdef CONFIG_AUDIT
40123965 smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
40133966 ad.a.u.net->family = family;
....@@ -4079,12 +4032,11 @@
40794032 struct sk_buff *skb, u32 *secid)
40804033
40814034 {
4082
- struct netlbl_lsm_secattr secattr;
40834035 struct socket_smack *ssp = NULL;
40844036 struct smack_known *skp;
4037
+ struct sock *sk = NULL;
40854038 int family = PF_UNSPEC;
40864039 u32 s = 0; /* 0 is the invalid secid */
4087
- int rc;
40884040
40894041 if (skb != NULL) {
40904042 if (skb->protocol == htons(ETH_P_IP))
....@@ -4103,27 +4055,25 @@
41034055 s = ssp->smk_out->smk_secid;
41044056 break;
41054057 case PF_INET:
4106
-#ifdef CONFIG_SECURITY_SMACK_NETFILTER
4107
- s = skb->secmark;
4108
- if (s != 0)
4058
+ skp = smack_from_skb(skb);
4059
+ if (skp) {
4060
+ s = skp->smk_secid;
41094061 break;
4110
-#endif
4062
+ }
41114063 /*
41124064 * Translate what netlabel gave us.
41134065 */
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);
4066
+ if (sock != NULL)
4067
+ sk = sock->sk;
4068
+ skp = smack_from_netlbl(sk, family, skb);
4069
+ if (skp != NULL)
41204070 s = skp->smk_secid;
4121
- }
4122
- netlbl_secattr_destroy(&secattr);
41234071 break;
41244072 case PF_INET6:
41254073 #ifdef SMACK_IPV6_SECMARK_LABELING
4126
- s = skb->secmark;
4074
+ skp = smack_from_skb(skb);
4075
+ if (skp)
4076
+ s = skp->smk_secid;
41274077 #endif
41284078 break;
41294079 }
....@@ -4171,7 +4121,6 @@
41714121 u16 family = sk->sk_family;
41724122 struct smack_known *skp;
41734123 struct socket_smack *ssp = sk->sk_security;
4174
- struct netlbl_lsm_secattr secattr;
41754124 struct sockaddr_in addr;
41764125 struct iphdr *hdr;
41774126 struct smack_known *hskp;
....@@ -4195,29 +4144,17 @@
41954144 }
41964145 #endif /* CONFIG_IPV6 */
41974146
4198
-#ifdef CONFIG_SECURITY_SMACK_NETFILTER
41994147 /*
42004148 * If there is a secmark use it rather than the CIPSO label.
42014149 * If there is no secmark fall back to CIPSO.
42024150 * The secmark is assumed to reflect policy better.
42034151 */
4204
- if (skb && skb->secmark != 0) {
4205
- skp = smack_from_secid(skb->secmark);
4206
- goto access_check;
4152
+ skp = smack_from_skb(skb);
4153
+ if (skp == NULL) {
4154
+ skp = smack_from_netlbl(sk, family, skb);
4155
+ if (skp == NULL)
4156
+ skp = &smack_known_huh;
42074157 }
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
42214158
42224159 #ifdef CONFIG_AUDIT
42234160 smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
....@@ -4301,7 +4238,7 @@
43014238 static int smack_key_alloc(struct key *key, const struct cred *cred,
43024239 unsigned long flags)
43034240 {
4304
- struct smack_known *skp = smk_of_task(cred->security);
4241
+ struct smack_known *skp = smk_of_task(smack_cred(cred));
43054242
43064243 key->security = skp;
43074244 return 0;
....@@ -4322,25 +4259,44 @@
43224259 * smack_key_permission - Smack access on a key
43234260 * @key_ref: gets to the object
43244261 * @cred: the credentials to use
4325
- * @perm: requested key permissions
4262
+ * @need_perm: requested key permission
43264263 *
43274264 * Return 0 if the task has read and write to the object,
43284265 * an error code otherwise
43294266 */
43304267 static int smack_key_permission(key_ref_t key_ref,
4331
- const struct cred *cred, unsigned perm)
4268
+ const struct cred *cred,
4269
+ enum key_need_perm need_perm)
43324270 {
43334271 struct key *keyp;
43344272 struct smk_audit_info ad;
4335
- struct smack_known *tkp = smk_of_task(cred->security);
4273
+ struct smack_known *tkp = smk_of_task(smack_cred(cred));
43364274 int request = 0;
43374275 int rc;
43384276
43394277 /*
43404278 * Validate requested permissions
43414279 */
4342
- if (perm & ~KEY_NEED_ALL)
4280
+ switch (need_perm) {
4281
+ case KEY_NEED_READ:
4282
+ case KEY_NEED_SEARCH:
4283
+ case KEY_NEED_VIEW:
4284
+ request |= MAY_READ;
4285
+ break;
4286
+ case KEY_NEED_WRITE:
4287
+ case KEY_NEED_LINK:
4288
+ case KEY_NEED_SETATTR:
4289
+ request |= MAY_WRITE;
4290
+ break;
4291
+ case KEY_NEED_UNSPECIFIED:
4292
+ case KEY_NEED_UNLINK:
4293
+ case KEY_SYSADMIN_OVERRIDE:
4294
+ case KEY_AUTHTOKEN_OVERRIDE:
4295
+ case KEY_DEFER_PERM_CHECK:
4296
+ return 0;
4297
+ default:
43434298 return -EINVAL;
4299
+ }
43444300
43454301 keyp = key_ref_to_ptr(key_ref);
43464302 if (keyp == NULL)
....@@ -4357,7 +4313,7 @@
43574313 if (tkp == NULL)
43584314 return -EACCES;
43594315
4360
- if (smack_privileged_cred(CAP_MAC_OVERRIDE, cred))
4316
+ if (smack_privileged(CAP_MAC_OVERRIDE))
43614317 return 0;
43624318
43634319 #ifdef CONFIG_AUDIT
....@@ -4365,10 +4321,6 @@
43654321 ad.a.u.key_struct.key = keyp->serial;
43664322 ad.a.u.key_struct.key_desc = keyp->description;
43674323 #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;
43724324 rc = smk_access(tkp, keyp->security, request, &ad);
43734325 rc = smk_bu_note("key access", tkp, keyp->security, request, rc);
43744326 return rc;
....@@ -4403,7 +4355,80 @@
44034355 return length;
44044356 }
44054357
4358
+
4359
+#ifdef CONFIG_KEY_NOTIFICATIONS
4360
+/**
4361
+ * smack_watch_key - Smack access to watch a key for notifications.
4362
+ * @key: The key to be watched
4363
+ *
4364
+ * Return 0 if the @watch->cred has permission to read from the key object and
4365
+ * an error otherwise.
4366
+ */
4367
+static int smack_watch_key(struct key *key)
4368
+{
4369
+ struct smk_audit_info ad;
4370
+ struct smack_known *tkp = smk_of_current();
4371
+ int rc;
4372
+
4373
+ if (key == NULL)
4374
+ return -EINVAL;
4375
+ /*
4376
+ * If the key hasn't been initialized give it access so that
4377
+ * it may do so.
4378
+ */
4379
+ if (key->security == NULL)
4380
+ return 0;
4381
+ /*
4382
+ * This should not occur
4383
+ */
4384
+ if (tkp == NULL)
4385
+ return -EACCES;
4386
+
4387
+ if (smack_privileged_cred(CAP_MAC_OVERRIDE, current_cred()))
4388
+ return 0;
4389
+
4390
+#ifdef CONFIG_AUDIT
4391
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_KEY);
4392
+ ad.a.u.key_struct.key = key->serial;
4393
+ ad.a.u.key_struct.key_desc = key->description;
4394
+#endif
4395
+ rc = smk_access(tkp, key->security, MAY_READ, &ad);
4396
+ rc = smk_bu_note("key watch", tkp, key->security, MAY_READ, rc);
4397
+ return rc;
4398
+}
4399
+#endif /* CONFIG_KEY_NOTIFICATIONS */
44064400 #endif /* CONFIG_KEYS */
4401
+
4402
+#ifdef CONFIG_WATCH_QUEUE
4403
+/**
4404
+ * smack_post_notification - Smack access to post a notification to a queue
4405
+ * @w_cred: The credentials of the watcher.
4406
+ * @cred: The credentials of the event source (may be NULL).
4407
+ * @n: The notification message to be posted.
4408
+ */
4409
+static int smack_post_notification(const struct cred *w_cred,
4410
+ const struct cred *cred,
4411
+ struct watch_notification *n)
4412
+{
4413
+ struct smk_audit_info ad;
4414
+ struct smack_known *subj, *obj;
4415
+ int rc;
4416
+
4417
+ /* Always let maintenance notifications through. */
4418
+ if (n->type == WATCH_TYPE_META)
4419
+ return 0;
4420
+
4421
+ if (!cred)
4422
+ return 0;
4423
+ subj = smk_of_task(smack_cred(cred));
4424
+ obj = smk_of_task(smack_cred(w_cred));
4425
+
4426
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NOTIFICATION);
4427
+ rc = smk_access(subj, obj, MAY_WRITE, &ad);
4428
+ rc = smk_bu_note("notification", subj, obj, MAY_WRITE, rc);
4429
+ return rc;
4430
+}
4431
+#endif /* CONFIG_WATCH_QUEUE */
44074432
44084433 /*
44094434 * Smack Audit hooks
....@@ -4480,13 +4505,11 @@
44804505 * @field: audit rule flags given from user-space
44814506 * @op: required testing operator
44824507 * @vrule: smack internal rule presentation
4483
- * @actx: audit context associated with the check
44844508 *
44854509 * The core Audit hook. It's used to take the decision of
44864510 * whether to audit or not to audit a given object.
44874511 */
4488
-static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule,
4489
- struct audit_context *actx)
4512
+static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule)
44904513 {
44914514 struct smack_known *skp;
44924515 char *rule = vrule;
....@@ -4607,12 +4630,12 @@
46074630 return -ENOMEM;
46084631 }
46094632
4610
- tsp = new_creds->security;
4633
+ tsp = smack_cred(new_creds);
46114634
46124635 /*
46134636 * Get label from overlay inode and set it in create_sid
46144637 */
4615
- isp = d_inode(dentry->d_parent)->i_security;
4638
+ isp = smack_inode(d_inode(dentry->d_parent));
46164639 skp = isp->smk_inode;
46174640 tsp->smk_task = skp;
46184641 *new = new_creds;
....@@ -4635,8 +4658,8 @@
46354658 const struct cred *old,
46364659 struct cred *new)
46374660 {
4638
- struct task_smack *otsp = old->security;
4639
- struct task_smack *ntsp = new->security;
4661
+ struct task_smack *otsp = smack_cred(old);
4662
+ struct task_smack *ntsp = smack_cred(new);
46404663 struct inode_smack *isp;
46414664 int may;
46424665
....@@ -4649,7 +4672,7 @@
46494672 /*
46504673 * the attribute of the containing directory
46514674 */
4652
- isp = d_inode(dentry->d_parent)->i_security;
4675
+ isp = smack_inode(d_inode(dentry->d_parent));
46534676
46544677 if (isp->smk_flags & SMK_INODE_TRANSMUTE) {
46554678 rcu_read_lock();
....@@ -4669,23 +4692,32 @@
46694692 return 0;
46704693 }
46714694
4695
+struct lsm_blob_sizes smack_blob_sizes __lsm_ro_after_init = {
4696
+ .lbs_cred = sizeof(struct task_smack),
4697
+ .lbs_file = sizeof(struct smack_known *),
4698
+ .lbs_inode = sizeof(struct inode_smack),
4699
+ .lbs_ipc = sizeof(struct smack_known *),
4700
+ .lbs_msg_msg = sizeof(struct smack_known *),
4701
+};
4702
+
46724703 static struct security_hook_list smack_hooks[] __lsm_ro_after_init = {
46734704 LSM_HOOK_INIT(ptrace_access_check, smack_ptrace_access_check),
46744705 LSM_HOOK_INIT(ptrace_traceme, smack_ptrace_traceme),
46754706 LSM_HOOK_INIT(syslog, smack_syslog),
46764707
4708
+ LSM_HOOK_INIT(fs_context_dup, smack_fs_context_dup),
4709
+ LSM_HOOK_INIT(fs_context_parse_param, smack_fs_context_parse_param),
4710
+
46774711 LSM_HOOK_INIT(sb_alloc_security, smack_sb_alloc_security),
46784712 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),
4713
+ LSM_HOOK_INIT(sb_free_mnt_opts, smack_free_mnt_opts),
4714
+ LSM_HOOK_INIT(sb_eat_lsm_opts, smack_sb_eat_lsm_opts),
46814715 LSM_HOOK_INIT(sb_statfs, smack_sb_statfs),
46824716 LSM_HOOK_INIT(sb_set_mnt_opts, smack_set_mnt_opts),
4683
- LSM_HOOK_INIT(sb_parse_opts_str, smack_parse_opts_str),
46844717
4685
- LSM_HOOK_INIT(bprm_set_creds, smack_bprm_set_creds),
4718
+ LSM_HOOK_INIT(bprm_creds_for_exec, smack_bprm_creds_for_exec),
46864719
46874720 LSM_HOOK_INIT(inode_alloc_security, smack_inode_alloc_security),
4688
- LSM_HOOK_INIT(inode_free_security, smack_inode_free_security),
46894721 LSM_HOOK_INIT(inode_init_security, smack_inode_init_security),
46904722 LSM_HOOK_INIT(inode_link, smack_inode_link),
46914723 LSM_HOOK_INIT(inode_unlink, smack_inode_unlink),
....@@ -4704,7 +4736,6 @@
47044736 LSM_HOOK_INIT(inode_getsecid, smack_inode_getsecid),
47054737
47064738 LSM_HOOK_INIT(file_alloc_security, smack_file_alloc_security),
4707
- LSM_HOOK_INIT(file_free_security, smack_file_free_security),
47084739 LSM_HOOK_INIT(file_ioctl, smack_file_ioctl),
47094740 LSM_HOOK_INIT(file_lock, smack_file_lock),
47104741 LSM_HOOK_INIT(file_fcntl, smack_file_fcntl),
....@@ -4740,23 +4771,19 @@
47404771 LSM_HOOK_INIT(ipc_getsecid, smack_ipc_getsecid),
47414772
47424773 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),
47444774
47454775 LSM_HOOK_INIT(msg_queue_alloc_security, smack_ipc_alloc_security),
4746
- LSM_HOOK_INIT(msg_queue_free_security, smack_ipc_free_security),
47474776 LSM_HOOK_INIT(msg_queue_associate, smack_msg_queue_associate),
47484777 LSM_HOOK_INIT(msg_queue_msgctl, smack_msg_queue_msgctl),
47494778 LSM_HOOK_INIT(msg_queue_msgsnd, smack_msg_queue_msgsnd),
47504779 LSM_HOOK_INIT(msg_queue_msgrcv, smack_msg_queue_msgrcv),
47514780
47524781 LSM_HOOK_INIT(shm_alloc_security, smack_ipc_alloc_security),
4753
- LSM_HOOK_INIT(shm_free_security, smack_ipc_free_security),
47544782 LSM_HOOK_INIT(shm_associate, smack_shm_associate),
47554783 LSM_HOOK_INIT(shm_shmctl, smack_shm_shmctl),
47564784 LSM_HOOK_INIT(shm_shmat, smack_shm_shmat),
47574785
47584786 LSM_HOOK_INIT(sem_alloc_security, smack_ipc_alloc_security),
4759
- LSM_HOOK_INIT(sem_free_security, smack_ipc_free_security),
47604787 LSM_HOOK_INIT(sem_associate, smack_sem_associate),
47614788 LSM_HOOK_INIT(sem_semctl, smack_sem_semctl),
47624789 LSM_HOOK_INIT(sem_semop, smack_sem_semop),
....@@ -4791,7 +4818,14 @@
47914818 LSM_HOOK_INIT(key_free, smack_key_free),
47924819 LSM_HOOK_INIT(key_permission, smack_key_permission),
47934820 LSM_HOOK_INIT(key_getsecurity, smack_key_getsecurity),
4821
+#ifdef CONFIG_KEY_NOTIFICATIONS
4822
+ LSM_HOOK_INIT(watch_key, smack_watch_key),
4823
+#endif
47944824 #endif /* CONFIG_KEYS */
4825
+
4826
+#ifdef CONFIG_WATCH_QUEUE
4827
+ LSM_HOOK_INIT(post_notification, smack_post_notification),
4828
+#endif
47954829
47964830 /* Audit hooks */
47974831 #ifdef CONFIG_AUDIT
....@@ -4843,27 +4877,27 @@
48434877 /**
48444878 * smack_init - initialize the smack system
48454879 *
4846
- * Returns 0
4880
+ * Returns 0 on success, -ENOMEM is there's no memory
48474881 */
48484882 static __init int smack_init(void)
48494883 {
4850
- struct cred *cred;
4884
+ struct cred *cred = (struct cred *) current->cred;
48514885 struct task_smack *tsp;
48524886
4853
- if (!security_module_enable("smack"))
4854
- return 0;
4855
-
4856
- smack_inode_cache = KMEM_CACHE(inode_smack, 0);
4857
- if (!smack_inode_cache)
4887
+ smack_rule_cache = KMEM_CACHE(smack_rule, 0);
4888
+ if (!smack_rule_cache)
48584889 return -ENOMEM;
48594890
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
- }
4891
+ /*
4892
+ * Set the security state for the initial task.
4893
+ */
4894
+ tsp = smack_cred(cred);
4895
+ init_task_smack(tsp, &smack_known_floor, &smack_known_floor);
48664896
4897
+ /*
4898
+ * Register with LSM
4899
+ */
4900
+ security_add_hooks(smack_hooks, ARRAY_SIZE(smack_hooks), "smack");
48674901 smack_enabled = 1;
48684902
48694903 pr_info("Smack: Initializing.\n");
....@@ -4877,19 +4911,8 @@
48774911 pr_info("Smack: IPv6 Netfilter enabled.\n");
48784912 #endif
48794913
4880
- /*
4881
- * Set the security state for the initial task.
4882
- */
4883
- cred = (struct cred *) current->cred;
4884
- cred->security = tsp;
4885
-
48864914 /* initialize the smack_known_list */
48874915 init_smack_known_list();
4888
-
4889
- /*
4890
- * Register with LSM
4891
- */
4892
- security_add_hooks(smack_hooks, ARRAY_SIZE(smack_hooks), "smack");
48934916
48944917 return 0;
48954918 }
....@@ -4898,4 +4921,9 @@
48984921 * Smack requires early initialization in order to label
48994922 * all processes and objects when they are created.
49004923 */
4901
-security_initcall(smack_init);
4924
+DEFINE_LSM(smack) = {
4925
+ .name = "smack",
4926
+ .flags = LSM_FLAG_LEGACY_MAJOR | LSM_FLAG_EXCLUSIVE,
4927
+ .blobs = &smack_blob_sizes,
4928
+ .init = smack_init,
4929
+};