.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (C) 2007 Casey Schaufler <casey@schaufler-ca.com> |
---|
3 | | - * |
---|
4 | | - * This program is free software; you can redistribute it and/or modify |
---|
5 | | - * it under the terms of the GNU General Public License as published by |
---|
6 | | - * the Free Software Foundation, version 2. |
---|
7 | 4 | * |
---|
8 | 5 | * Authors: |
---|
9 | 6 | * Casey Schaufler <casey@schaufler-ca.com> |
---|
.. | .. |
---|
13 | 10 | * |
---|
14 | 11 | * Karl MacMillan <kmacmillan@tresys.com> |
---|
15 | 12 | * James Morris <jmorris@redhat.com> |
---|
16 | | - * |
---|
17 | 13 | */ |
---|
18 | 14 | |
---|
19 | 15 | #include <linux/kernel.h> |
---|
.. | .. |
---|
27 | 23 | #include <linux/ctype.h> |
---|
28 | 24 | #include <linux/audit.h> |
---|
29 | 25 | #include <linux/magic.h> |
---|
| 26 | +#include <linux/fs_context.h> |
---|
30 | 27 | #include "smack.h" |
---|
31 | 28 | |
---|
32 | 29 | #define BEBITS (sizeof(__be32) * 8) |
---|
.. | .. |
---|
67 | 64 | /* |
---|
68 | 65 | * List locks |
---|
69 | 66 | */ |
---|
70 | | -static DEFINE_MUTEX(smack_master_list_lock); |
---|
71 | 67 | static DEFINE_MUTEX(smack_cipso_lock); |
---|
72 | 68 | static DEFINE_MUTEX(smack_ambient_lock); |
---|
73 | 69 | static DEFINE_MUTEX(smk_net4addr_lock); |
---|
.. | .. |
---|
134 | 130 | |
---|
135 | 131 | /* |
---|
136 | 132 | * Rule lists are maintained for each label. |
---|
137 | | - * This master list is just for reading /smack/load and /smack/load2. |
---|
138 | 133 | */ |
---|
139 | | -struct smack_master_list { |
---|
140 | | - struct list_head list; |
---|
141 | | - struct smack_rule *smk_rule; |
---|
142 | | -}; |
---|
143 | | - |
---|
144 | | -static LIST_HEAD(smack_rule_list); |
---|
145 | | - |
---|
146 | 134 | struct smack_parsed_rule { |
---|
147 | 135 | struct smack_known *smk_subject; |
---|
148 | 136 | struct smack_known *smk_object; |
---|
.. | .. |
---|
211 | 199 | * @srp: the rule to add or replace |
---|
212 | 200 | * @rule_list: the list of rules |
---|
213 | 201 | * @rule_lock: the rule list lock |
---|
214 | | - * @global: if non-zero, indicates a global rule |
---|
215 | 202 | * |
---|
216 | 203 | * Looks through the current subject/object/access list for |
---|
217 | 204 | * the subject/object pair and replaces the access that was |
---|
.. | .. |
---|
223 | 210 | */ |
---|
224 | 211 | static int smk_set_access(struct smack_parsed_rule *srp, |
---|
225 | 212 | struct list_head *rule_list, |
---|
226 | | - struct mutex *rule_lock, int global) |
---|
| 213 | + struct mutex *rule_lock) |
---|
227 | 214 | { |
---|
228 | 215 | struct smack_rule *sp; |
---|
229 | | - struct smack_master_list *smlp; |
---|
230 | 216 | int found = 0; |
---|
231 | 217 | int rc = 0; |
---|
232 | 218 | |
---|
.. | .. |
---|
247 | 233 | } |
---|
248 | 234 | |
---|
249 | 235 | if (found == 0) { |
---|
250 | | - sp = kzalloc(sizeof(*sp), GFP_KERNEL); |
---|
| 236 | + sp = kmem_cache_zalloc(smack_rule_cache, GFP_KERNEL); |
---|
251 | 237 | if (sp == NULL) { |
---|
252 | 238 | rc = -ENOMEM; |
---|
253 | 239 | goto out; |
---|
.. | .. |
---|
258 | 244 | sp->smk_access = srp->smk_access1 & ~srp->smk_access2; |
---|
259 | 245 | |
---|
260 | 246 | list_add_rcu(&sp->list, rule_list); |
---|
261 | | - /* |
---|
262 | | - * If this is a global as opposed to self and a new rule |
---|
263 | | - * it needs to get added for reporting. |
---|
264 | | - */ |
---|
265 | | - if (global) { |
---|
266 | | - mutex_unlock(rule_lock); |
---|
267 | | - smlp = kzalloc(sizeof(*smlp), GFP_KERNEL); |
---|
268 | | - if (smlp != NULL) { |
---|
269 | | - smlp->smk_rule = sp; |
---|
270 | | - mutex_lock(&smack_master_list_lock); |
---|
271 | | - list_add_rcu(&smlp->list, &smack_rule_list); |
---|
272 | | - mutex_unlock(&smack_master_list_lock); |
---|
273 | | - } else |
---|
274 | | - rc = -ENOMEM; |
---|
275 | | - return rc; |
---|
276 | | - } |
---|
277 | 247 | } |
---|
278 | 248 | |
---|
279 | 249 | out: |
---|
.. | .. |
---|
540 | 510 | |
---|
541 | 511 | if (rule_list == NULL) |
---|
542 | 512 | rc = smk_set_access(&rule, &rule.smk_subject->smk_rules, |
---|
543 | | - &rule.smk_subject->smk_rules_lock, 1); |
---|
| 513 | + &rule.smk_subject->smk_rules_lock); |
---|
544 | 514 | else |
---|
545 | | - rc = smk_set_access(&rule, rule_list, rule_lock, 0); |
---|
| 515 | + rc = smk_set_access(&rule, rule_list, rule_lock); |
---|
546 | 516 | |
---|
547 | 517 | if (rc) |
---|
548 | 518 | goto out; |
---|
.. | .. |
---|
636 | 606 | |
---|
637 | 607 | static void *load2_seq_start(struct seq_file *s, loff_t *pos) |
---|
638 | 608 | { |
---|
639 | | - return smk_seq_start(s, pos, &smack_rule_list); |
---|
| 609 | + return smk_seq_start(s, pos, &smack_known_list); |
---|
640 | 610 | } |
---|
641 | 611 | |
---|
642 | 612 | static void *load2_seq_next(struct seq_file *s, void *v, loff_t *pos) |
---|
643 | 613 | { |
---|
644 | | - return smk_seq_next(s, v, pos, &smack_rule_list); |
---|
| 614 | + return smk_seq_next(s, v, pos, &smack_known_list); |
---|
645 | 615 | } |
---|
646 | 616 | |
---|
647 | 617 | static int load_seq_show(struct seq_file *s, void *v) |
---|
648 | 618 | { |
---|
649 | 619 | struct list_head *list = v; |
---|
650 | | - struct smack_master_list *smlp = |
---|
651 | | - list_entry_rcu(list, struct smack_master_list, list); |
---|
| 620 | + struct smack_rule *srp; |
---|
| 621 | + struct smack_known *skp = |
---|
| 622 | + list_entry_rcu(list, struct smack_known, list); |
---|
652 | 623 | |
---|
653 | | - smk_rule_show(s, smlp->smk_rule, SMK_LABELLEN); |
---|
| 624 | + list_for_each_entry_rcu(srp, &skp->smk_rules, list) |
---|
| 625 | + smk_rule_show(s, srp, SMK_LABELLEN); |
---|
654 | 626 | |
---|
655 | 627 | return 0; |
---|
656 | 628 | } |
---|
.. | .. |
---|
923 | 895 | } |
---|
924 | 896 | |
---|
925 | 897 | ret = sscanf(rule, "%d", &catlen); |
---|
926 | | - if (ret != 1 || catlen > SMACK_CIPSO_MAXCATNUM) |
---|
| 898 | + if (ret != 1 || catlen < 0 || catlen > SMACK_CIPSO_MAXCATNUM) |
---|
927 | 899 | goto out; |
---|
928 | 900 | |
---|
929 | 901 | if (format == SMK_FIXED24_FMT && |
---|
.. | .. |
---|
953 | 925 | synchronize_rcu(); |
---|
954 | 926 | netlbl_catmap_free(old_cat); |
---|
955 | 927 | rc = count; |
---|
| 928 | + /* |
---|
| 929 | + * This mapping may have been cached, so clear the cache. |
---|
| 930 | + */ |
---|
| 931 | + netlbl_cache_invalidate(); |
---|
956 | 932 | } |
---|
957 | 933 | |
---|
958 | 934 | out: |
---|
.. | .. |
---|
2235 | 2211 | |
---|
2236 | 2212 | static void *load_self_seq_start(struct seq_file *s, loff_t *pos) |
---|
2237 | 2213 | { |
---|
2238 | | - struct task_smack *tsp = current_security(); |
---|
| 2214 | + struct task_smack *tsp = smack_cred(current_cred()); |
---|
2239 | 2215 | |
---|
2240 | 2216 | return smk_seq_start(s, pos, &tsp->smk_rules); |
---|
2241 | 2217 | } |
---|
2242 | 2218 | |
---|
2243 | 2219 | static void *load_self_seq_next(struct seq_file *s, void *v, loff_t *pos) |
---|
2244 | 2220 | { |
---|
2245 | | - struct task_smack *tsp = current_security(); |
---|
| 2221 | + struct task_smack *tsp = smack_cred(current_cred()); |
---|
2246 | 2222 | |
---|
2247 | 2223 | return smk_seq_next(s, v, pos, &tsp->smk_rules); |
---|
2248 | 2224 | } |
---|
.. | .. |
---|
2289 | 2265 | static ssize_t smk_write_load_self(struct file *file, const char __user *buf, |
---|
2290 | 2266 | size_t count, loff_t *ppos) |
---|
2291 | 2267 | { |
---|
2292 | | - struct task_smack *tsp = current_security(); |
---|
| 2268 | + struct task_smack *tsp = smack_cred(current_cred()); |
---|
2293 | 2269 | |
---|
2294 | 2270 | return smk_write_rules_list(file, buf, count, ppos, &tsp->smk_rules, |
---|
2295 | 2271 | &tsp->smk_rules_lock, SMK_FIXED24_FMT); |
---|
.. | .. |
---|
2379 | 2355 | static int load2_seq_show(struct seq_file *s, void *v) |
---|
2380 | 2356 | { |
---|
2381 | 2357 | struct list_head *list = v; |
---|
2382 | | - struct smack_master_list *smlp = |
---|
2383 | | - list_entry_rcu(list, struct smack_master_list, list); |
---|
| 2358 | + struct smack_rule *srp; |
---|
| 2359 | + struct smack_known *skp = |
---|
| 2360 | + list_entry_rcu(list, struct smack_known, list); |
---|
2384 | 2361 | |
---|
2385 | | - smk_rule_show(s, smlp->smk_rule, SMK_LONGLABEL); |
---|
| 2362 | + list_for_each_entry_rcu(srp, &skp->smk_rules, list) |
---|
| 2363 | + smk_rule_show(s, srp, SMK_LONGLABEL); |
---|
2386 | 2364 | |
---|
2387 | 2365 | return 0; |
---|
2388 | 2366 | } |
---|
.. | .. |
---|
2441 | 2419 | |
---|
2442 | 2420 | static void *load_self2_seq_start(struct seq_file *s, loff_t *pos) |
---|
2443 | 2421 | { |
---|
2444 | | - struct task_smack *tsp = current_security(); |
---|
| 2422 | + struct task_smack *tsp = smack_cred(current_cred()); |
---|
2445 | 2423 | |
---|
2446 | 2424 | return smk_seq_start(s, pos, &tsp->smk_rules); |
---|
2447 | 2425 | } |
---|
2448 | 2426 | |
---|
2449 | 2427 | static void *load_self2_seq_next(struct seq_file *s, void *v, loff_t *pos) |
---|
2450 | 2428 | { |
---|
2451 | | - struct task_smack *tsp = current_security(); |
---|
| 2429 | + struct task_smack *tsp = smack_cred(current_cred()); |
---|
2452 | 2430 | |
---|
2453 | 2431 | return smk_seq_next(s, v, pos, &tsp->smk_rules); |
---|
2454 | 2432 | } |
---|
.. | .. |
---|
2494 | 2472 | static ssize_t smk_write_load_self2(struct file *file, const char __user *buf, |
---|
2495 | 2473 | size_t count, loff_t *ppos) |
---|
2496 | 2474 | { |
---|
2497 | | - struct task_smack *tsp = current_security(); |
---|
| 2475 | + struct task_smack *tsp = smack_cred(current_cred()); |
---|
2498 | 2476 | |
---|
2499 | 2477 | return smk_write_rules_list(file, buf, count, ppos, &tsp->smk_rules, |
---|
2500 | 2478 | &tsp->smk_rules_lock, SMK_LONG_FMT); |
---|
.. | .. |
---|
2712 | 2690 | |
---|
2713 | 2691 | static void *relabel_self_seq_start(struct seq_file *s, loff_t *pos) |
---|
2714 | 2692 | { |
---|
2715 | | - struct task_smack *tsp = current_security(); |
---|
| 2693 | + struct task_smack *tsp = smack_cred(current_cred()); |
---|
2716 | 2694 | |
---|
2717 | 2695 | return smk_seq_start(s, pos, &tsp->smk_relabel); |
---|
2718 | 2696 | } |
---|
2719 | 2697 | |
---|
2720 | 2698 | static void *relabel_self_seq_next(struct seq_file *s, void *v, loff_t *pos) |
---|
2721 | 2699 | { |
---|
2722 | | - struct task_smack *tsp = current_security(); |
---|
| 2700 | + struct task_smack *tsp = smack_cred(current_cred()); |
---|
2723 | 2701 | |
---|
2724 | 2702 | return smk_seq_next(s, v, pos, &tsp->smk_relabel); |
---|
2725 | 2703 | } |
---|
.. | .. |
---|
2802 | 2780 | rc = -ENOMEM; |
---|
2803 | 2781 | goto out; |
---|
2804 | 2782 | } |
---|
2805 | | - tsp = new->security; |
---|
| 2783 | + tsp = smack_cred(new); |
---|
2806 | 2784 | smk_destroy_label_list(&tsp->smk_relabel); |
---|
2807 | 2785 | list_splice(&list_tmp, &tsp->smk_relabel); |
---|
2808 | 2786 | commit_creds(new); |
---|
.. | .. |
---|
2886 | 2864 | /** |
---|
2887 | 2865 | * smk_fill_super - fill the smackfs superblock |
---|
2888 | 2866 | * @sb: the empty superblock |
---|
2889 | | - * @data: unused |
---|
2890 | | - * @silent: unused |
---|
| 2867 | + * @fc: unused |
---|
2891 | 2868 | * |
---|
2892 | 2869 | * Fill in the well known entries for the smack filesystem |
---|
2893 | 2870 | * |
---|
2894 | 2871 | * Returns 0 on success, an error code on failure |
---|
2895 | 2872 | */ |
---|
2896 | | -static int smk_fill_super(struct super_block *sb, void *data, int silent) |
---|
| 2873 | +static int smk_fill_super(struct super_block *sb, struct fs_context *fc) |
---|
2897 | 2874 | { |
---|
2898 | 2875 | int rc; |
---|
2899 | | - struct inode *root_inode; |
---|
2900 | 2876 | |
---|
2901 | 2877 | static const struct tree_descr smack_files[] = { |
---|
2902 | 2878 | [SMK_LOAD] = { |
---|
.. | .. |
---|
2960 | 2936 | return rc; |
---|
2961 | 2937 | } |
---|
2962 | 2938 | |
---|
2963 | | - root_inode = d_inode(sb->s_root); |
---|
2964 | | - |
---|
2965 | 2939 | return 0; |
---|
2966 | 2940 | } |
---|
2967 | 2941 | |
---|
2968 | 2942 | /** |
---|
2969 | | - * smk_mount - get the smackfs superblock |
---|
2970 | | - * @fs_type: passed along without comment |
---|
2971 | | - * @flags: passed along without comment |
---|
2972 | | - * @dev_name: passed along without comment |
---|
2973 | | - * @data: passed along without comment |
---|
| 2943 | + * smk_get_tree - get the smackfs superblock |
---|
| 2944 | + * @fc: The mount context, including any options |
---|
2974 | 2945 | * |
---|
2975 | 2946 | * Just passes everything along. |
---|
2976 | 2947 | * |
---|
2977 | 2948 | * Returns what the lower level code does. |
---|
2978 | 2949 | */ |
---|
2979 | | -static struct dentry *smk_mount(struct file_system_type *fs_type, |
---|
2980 | | - int flags, const char *dev_name, void *data) |
---|
| 2950 | +static int smk_get_tree(struct fs_context *fc) |
---|
2981 | 2951 | { |
---|
2982 | | - return mount_single(fs_type, flags, data, smk_fill_super); |
---|
| 2952 | + return get_tree_single(fc, smk_fill_super); |
---|
| 2953 | +} |
---|
| 2954 | + |
---|
| 2955 | +static const struct fs_context_operations smk_context_ops = { |
---|
| 2956 | + .get_tree = smk_get_tree, |
---|
| 2957 | +}; |
---|
| 2958 | + |
---|
| 2959 | +/** |
---|
| 2960 | + * smk_init_fs_context - Initialise a filesystem context for smackfs |
---|
| 2961 | + * @fc: The blank mount context |
---|
| 2962 | + */ |
---|
| 2963 | +static int smk_init_fs_context(struct fs_context *fc) |
---|
| 2964 | +{ |
---|
| 2965 | + fc->ops = &smk_context_ops; |
---|
| 2966 | + return 0; |
---|
2983 | 2967 | } |
---|
2984 | 2968 | |
---|
2985 | 2969 | static struct file_system_type smk_fs_type = { |
---|
2986 | 2970 | .name = "smackfs", |
---|
2987 | | - .mount = smk_mount, |
---|
| 2971 | + .init_fs_context = smk_init_fs_context, |
---|
2988 | 2972 | .kill_sb = kill_litter_super, |
---|
2989 | 2973 | }; |
---|
2990 | 2974 | |
---|
2991 | 2975 | static struct vfsmount *smackfs_mount; |
---|
2992 | | - |
---|
2993 | | -static int __init smk_preset_netlabel(struct smack_known *skp) |
---|
2994 | | -{ |
---|
2995 | | - skp->smk_netlabel.domain = skp->smk_known; |
---|
2996 | | - skp->smk_netlabel.flags = |
---|
2997 | | - NETLBL_SECATTR_DOMAIN | NETLBL_SECATTR_MLS_LVL; |
---|
2998 | | - return smk_netlbl_mls(smack_cipso_direct, skp->smk_known, |
---|
2999 | | - &skp->smk_netlabel, strlen(skp->smk_known)); |
---|
3000 | | -} |
---|
3001 | 2976 | |
---|
3002 | 2977 | /** |
---|
3003 | 2978 | * init_smk_fs - get the smackfs superblock |
---|
.. | .. |
---|
3037 | 3012 | smk_cipso_doi(); |
---|
3038 | 3013 | smk_unlbl_ambient(NULL); |
---|
3039 | 3014 | |
---|
3040 | | - rc = smk_preset_netlabel(&smack_known_floor); |
---|
| 3015 | + rc = smack_populate_secattr(&smack_known_floor); |
---|
3041 | 3016 | if (err == 0 && rc < 0) |
---|
3042 | 3017 | err = rc; |
---|
3043 | | - rc = smk_preset_netlabel(&smack_known_hat); |
---|
| 3018 | + rc = smack_populate_secattr(&smack_known_hat); |
---|
3044 | 3019 | if (err == 0 && rc < 0) |
---|
3045 | 3020 | err = rc; |
---|
3046 | | - rc = smk_preset_netlabel(&smack_known_huh); |
---|
| 3021 | + rc = smack_populate_secattr(&smack_known_huh); |
---|
3047 | 3022 | if (err == 0 && rc < 0) |
---|
3048 | 3023 | err = rc; |
---|
3049 | | - rc = smk_preset_netlabel(&smack_known_star); |
---|
| 3024 | + rc = smack_populate_secattr(&smack_known_star); |
---|
3050 | 3025 | if (err == 0 && rc < 0) |
---|
3051 | 3026 | err = rc; |
---|
3052 | | - rc = smk_preset_netlabel(&smack_known_web); |
---|
| 3027 | + rc = smack_populate_secattr(&smack_known_web); |
---|
3053 | 3028 | if (err == 0 && rc < 0) |
---|
3054 | 3029 | err = rc; |
---|
3055 | 3030 | |
---|