diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2023-06-28 03:18:48 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2023-06-28 03:18:48 +0300 |
commit | 729b39ec1bdb7e1ca594e14069d05f682d9ab868 (patch) | |
tree | 026492d4365a7c222d3221fba29e1517a270f938 /security | |
parent | cae72026b5ecf059687ccb431cb0e5965e863fea (diff) | |
parent | 447a5688005e5b789633bd080016517a08f9fd8d (diff) | |
download | linux-729b39ec1bdb7e1ca594e14069d05f682d9ab868.tar.xz |
Merge tag 'selinux-pr-20230626' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux
Pull selinux updates from Paul Moore:
- Thanks to help from the MPTCP folks, it looks like we have finally
sorted out a proper solution to the MPTCP socket labeling issue, see
the new security_mptcp_add_subflow() LSM hook.
- Fix the labeled NFS handling such that a labeled NFS share mounted
prior to the initial SELinux policy load is properly labeled once a
policy is loaded; more information in the commit description.
- Two patches to security/selinux/Makefile, the first took the cleanups
in v6.4 a bit further and the second removed the grouped targets
support as that functionality doesn't appear to be properly supported
prior to make v4.3.
- Deprecate the "fs" object context type in SELinux policies. The fs
object context type was an old vestige that was introduced back in
v2.6.12-rc2 but never really used.
- A number of small changes that remove dead code, clean up some
awkward bits, and generally improve the quality of the code. See the
individual commit descriptions for more information.
* tag 'selinux-pr-20230626' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux:
selinux: avoid bool as identifier name
selinux: fix Makefile for versions of make < v4.3
selinux: make labeled NFS work when mounted before policy load
selinux: cleanup exit_sel_fs() declaration
selinux: deprecated fs ocon
selinux: make header files self-including
selinux: keep context struct members in sync
selinux: Implement mptcp_add_subflow hook
security, lsm: Introduce security_mptcp_add_subflow()
selinux: small cleanups in selinux_audit_rule_init()
selinux: declare read-only data arrays const
selinux: retain const qualifier on string literal in avtab_hash_eval()
selinux: drop return at end of void function avc_insert()
selinux: avc: drop unused function avc_disable()
selinux: adjust typos in comments
selinux: do not leave dangling pointer behind
selinux: more Makefile tweaks
Diffstat (limited to 'security')
-rw-r--r-- | security/security.c | 17 | ||||
-rw-r--r-- | security/selinux/Makefile | 30 | ||||
-rw-r--r-- | security/selinux/avc.c | 20 | ||||
-rw-r--r-- | security/selinux/hooks.c | 78 | ||||
-rw-r--r-- | security/selinux/ima.c | 2 | ||||
-rw-r--r-- | security/selinux/include/audit.h | 2 | ||||
-rw-r--r-- | security/selinux/include/avc.h | 3 | ||||
-rw-r--r-- | security/selinux/include/ibpkey.h | 1 | ||||
-rw-r--r-- | security/selinux/include/ima.h | 2 | ||||
-rw-r--r-- | security/selinux/include/initial_sid_to_string.h | 3 | ||||
-rw-r--r-- | security/selinux/include/security.h | 2 | ||||
-rw-r--r-- | security/selinux/netlabel.c | 8 | ||||
-rw-r--r-- | security/selinux/selinuxfs.c | 4 | ||||
-rw-r--r-- | security/selinux/ss/avtab.c | 2 | ||||
-rw-r--r-- | security/selinux/ss/avtab.h | 2 | ||||
-rw-r--r-- | security/selinux/ss/conditional.c | 8 | ||||
-rw-r--r-- | security/selinux/ss/conditional.h | 2 | ||||
-rw-r--r-- | security/selinux/ss/context.h | 2 | ||||
-rw-r--r-- | security/selinux/ss/policydb.c | 6 | ||||
-rw-r--r-- | security/selinux/ss/policydb.h | 2 | ||||
-rw-r--r-- | security/selinux/ss/services.c | 40 |
21 files changed, 144 insertions, 92 deletions
diff --git a/security/security.c b/security/security.c index d5ff7ff45b77..0e7be1da0b3d 100644 --- a/security/security.c +++ b/security/security.c @@ -4667,6 +4667,23 @@ int security_sctp_assoc_established(struct sctp_association *asoc, } EXPORT_SYMBOL(security_sctp_assoc_established); +/** + * security_mptcp_add_subflow() - Inherit the LSM label from the MPTCP socket + * @sk: the owning MPTCP socket + * @ssk: the new subflow + * + * Update the labeling for the given MPTCP subflow, to match the one of the + * owning MPTCP socket. This hook has to be called after the socket creation and + * initialization via the security_socket_create() and + * security_socket_post_create() LSM hooks. + * + * Return: Returns 0 on success or a negative error code on failure. + */ +int security_mptcp_add_subflow(struct sock *sk, struct sock *ssk) +{ + return call_int_hook(mptcp_add_subflow, 0, sk, ssk); +} + #endif /* CONFIG_SECURITY_NETWORK */ #ifdef CONFIG_SECURITY_INFINIBAND diff --git a/security/selinux/Makefile b/security/selinux/Makefile index 8b21520bd4b9..836379639058 100644 --- a/security/selinux/Makefile +++ b/security/selinux/Makefile @@ -3,32 +3,38 @@ # Makefile for building the SELinux module as part of the kernel tree. # +# NOTE: There are a number of improvements that can be made to this Makefile +# once the kernel requires make v4.3 or greater; the most important feature +# lacking in older versions of make is support for grouped targets. These +# improvements are noted inline in the Makefile below ... + obj-$(CONFIG_SECURITY_SELINUX) := selinux.o +ccflags-y := -I$(srctree)/security/selinux -I$(srctree)/security/selinux/include + selinux-y := avc.o hooks.o selinuxfs.o netlink.o nlmsgtab.o netif.o \ netnode.o netport.o status.o \ ss/ebitmap.o ss/hashtab.o ss/symtab.o ss/sidtab.o ss/avtab.o \ ss/policydb.o ss/services.o ss/conditional.o ss/mls.o ss/context.o selinux-$(CONFIG_SECURITY_NETWORK_XFRM) += xfrm.o - selinux-$(CONFIG_NETLABEL) += netlabel.o - selinux-$(CONFIG_SECURITY_INFINIBAND) += ibpkey.o - selinux-$(CONFIG_IMA) += ima.o -ccflags-y := -I$(srctree)/security/selinux -I$(srctree)/security/selinux/include +genhdrs := flask.h av_permissions.h +# see the note above, replace the dependency rule with the one below: +# $(addprefix $(obj)/,$(selinux-y)): $(addprefix $(obj)/,$(genhdrs)) $(addprefix $(obj)/,$(selinux-y)): $(obj)/flask.h -quiet_cmd_flask = GEN $(obj)/flask.h $(obj)/av_permissions.h - cmd_flask = $< $(obj)/flask.h $(obj)/av_permissions.h +quiet_cmd_genhdrs = GEN $(addprefix $(obj)/,$(genhdrs)) + cmd_genhdrs = $< $(addprefix $(obj)/,$(genhdrs)) -targets += flask.h av_permissions.h -# once make >= 4.3 is required, we can use grouped targets in the rule below, -# which basically involves adding both headers and a '&' before the colon, see -# the example below: -# $(obj)/flask.h $(obj)/av_permissions.h &: scripts/selinux/... +# see the note above, replace the $targets and 'flask.h' rule with the lines +# below: +# targets += $(genhdrs) +# $(addprefix $(obj)/,$(genhdrs)) &: scripts/selinux/... +targets += flask.h $(obj)/flask.h: scripts/selinux/genheaders/genheaders FORCE - $(call if_changed,flask) + $(call if_changed,genhdrs) diff --git a/security/selinux/avc.c b/security/selinux/avc.c index eaed5c2da02b..1074db66e5ff 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c @@ -642,7 +642,6 @@ static void avc_insert(u32 ssid, u32 tsid, u16 tclass, hlist_add_head_rcu(&node->list, head); found: spin_unlock_irqrestore(lock, flag); - return; } /** @@ -1203,22 +1202,3 @@ u32 avc_policy_seqno(void) { return selinux_avc.avc_cache.latest_notif; } - -void avc_disable(void) -{ - /* - * If you are looking at this because you have realized that we are - * not destroying the avc_node_cachep it might be easy to fix, but - * I don't know the memory barrier semantics well enough to know. It's - * possible that some other task dereferenced security_ops when - * it still pointed to selinux operations. If that is the case it's - * possible that it is about to use the avc and is about to need the - * avc_node_cachep. I know I could wrap the security.c security_ops call - * in an rcu_lock, but seriously, it's not worth it. Instead I just flush - * the cache and get that memory back. - */ - if (avc_node_cachep) { - avc_flush(); - /* kmem_cache_destroy(avc_node_cachep); */ - } -} diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 79b4890e9936..d06e350fedee 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -357,7 +357,7 @@ enum { }; #define A(s, has_arg) {#s, sizeof(#s) - 1, Opt_##s, has_arg} -static struct { +static const struct { const char *name; int len; int opt; @@ -605,6 +605,13 @@ static int selinux_set_mnt_opts(struct super_block *sb, u32 defcontext_sid = 0; int rc = 0; + /* + * Specifying internal flags without providing a place to + * place the results is not allowed + */ + if (kern_flags && !set_kern_flags) + return -EINVAL; + mutex_lock(&sbsec->lock); if (!selinux_initialized()) { @@ -612,6 +619,10 @@ static int selinux_set_mnt_opts(struct super_block *sb, /* Defer initialization until selinux_complete_init, after the initial policy is loaded and the security server is ready to handle calls. */ + if (kern_flags & SECURITY_LSM_NATIVE_LABELS) { + sbsec->flags |= SE_SBNATIVE; + *set_kern_flags |= SECURITY_LSM_NATIVE_LABELS; + } goto out; } rc = -EINVAL; @@ -619,12 +630,6 @@ static int selinux_set_mnt_opts(struct super_block *sb, "before the security server is initialized\n"); goto out; } - if (kern_flags && !set_kern_flags) { - /* Specifying internal flags without providing a place to - * place the results is not allowed */ - rc = -EINVAL; - goto out; - } /* * Binary mount data FS will come through this function twice. Once @@ -757,7 +762,17 @@ static int selinux_set_mnt_opts(struct super_block *sb, * sets the label used on all file below the mountpoint, and will set * the superblock context if not already set. */ - if (kern_flags & SECURITY_LSM_NATIVE_LABELS && !context_sid) { + if (sbsec->flags & SE_SBNATIVE) { + /* + * This means we are initializing a superblock that has been + * mounted before the SELinux was initialized and the + * filesystem requested native labeling. We had already + * returned SECURITY_LSM_NATIVE_LABELS in *set_kern_flags + * in the original mount attempt, so now we just need to set + * the SECURITY_FS_USE_NATIVE behavior. + */ + sbsec->behavior = SECURITY_FS_USE_NATIVE; + } else if (kern_flags & SECURITY_LSM_NATIVE_LABELS && !context_sid) { sbsec->behavior = SECURITY_FS_USE_NATIVE; *set_kern_flags |= SECURITY_LSM_NATIVE_LABELS; } @@ -869,31 +884,37 @@ static int selinux_sb_clone_mnt_opts(const struct super_block *oldsb, int set_rootcontext = (oldsbsec->flags & ROOTCONTEXT_MNT); /* - * if the parent was able to be mounted it clearly had no special lsm - * mount options. thus we can safely deal with this superblock later - */ - if (!selinux_initialized()) - return 0; - - /* * Specifying internal flags without providing a place to * place the results is not allowed. */ if (kern_flags && !set_kern_flags) return -EINVAL; + mutex_lock(&newsbsec->lock); + + /* + * if the parent was able to be mounted it clearly had no special lsm + * mount options. thus we can safely deal with this superblock later + */ + if (!selinux_initialized()) { + if (kern_flags & SECURITY_LSM_NATIVE_LABELS) { + newsbsec->flags |= SE_SBNATIVE; + *set_kern_flags |= SECURITY_LSM_NATIVE_LABELS; + } + goto out; + } + /* how can we clone if the old one wasn't set up?? */ BUG_ON(!(oldsbsec->flags & SE_SBINITIALIZED)); /* if fs is reusing a sb, make sure that the contexts match */ if (newsbsec->flags & SE_SBINITIALIZED) { + mutex_unlock(&newsbsec->lock); if ((kern_flags & SECURITY_LSM_NATIVE_LABELS) && !set_context) *set_kern_flags |= SECURITY_LSM_NATIVE_LABELS; return selinux_cmp_sb_context(oldsb, newsb); } - mutex_lock(&newsbsec->lock); - newsbsec->flags = oldsbsec->flags; newsbsec->sid = oldsbsec->sid; @@ -937,7 +958,7 @@ out: } /* - * NOTE: the caller is resposible for freeing the memory even if on error. + * NOTE: the caller is responsible for freeing the memory even if on error. */ static int selinux_add_opt(int token, const char *s, void **mnt_opts) { @@ -1394,8 +1415,11 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent spin_unlock(&isec->lock); switch (sbsec->behavior) { + /* + * In case of SECURITY_FS_USE_NATIVE we need to re-fetch the labels + * via xattr when called from delayed_superblock_init(). + */ case SECURITY_FS_USE_NATIVE: - break; case SECURITY_FS_USE_XATTR: if (!(inode->i_opflags & IOP_XATTR)) { sid = sbsec->def_sid; @@ -5379,6 +5403,21 @@ static void selinux_sctp_sk_clone(struct sctp_association *asoc, struct sock *sk selinux_netlbl_sctp_sk_clone(sk, newsk); } +static int selinux_mptcp_add_subflow(struct sock *sk, struct sock *ssk) +{ + struct sk_security_struct *ssksec = ssk->sk_security; + struct sk_security_struct *sksec = sk->sk_security; + + ssksec->sclass = sksec->sclass; + ssksec->sid = sksec->sid; + + /* replace the existing subflow label deleting the existing one + * and re-recreating a new label using the updated context + */ + selinux_netlbl_sk_security_free(ssksec); + return selinux_netlbl_socket_post_create(ssk, ssk->sk_family); +} + static int selinux_inet_conn_request(const struct sock *sk, struct sk_buff *skb, struct request_sock *req) { @@ -7074,6 +7113,7 @@ static struct security_hook_list selinux_hooks[] __ro_after_init = { LSM_HOOK_INIT(sctp_sk_clone, selinux_sctp_sk_clone), LSM_HOOK_INIT(sctp_bind_connect, selinux_sctp_bind_connect), LSM_HOOK_INIT(sctp_assoc_established, selinux_sctp_assoc_established), + LSM_HOOK_INIT(mptcp_add_subflow, selinux_mptcp_add_subflow), LSM_HOOK_INIT(inet_conn_request, selinux_inet_conn_request), LSM_HOOK_INIT(inet_csk_clone, selinux_inet_csk_clone), LSM_HOOK_INIT(inet_conn_established, selinux_inet_conn_established), diff --git a/security/selinux/ima.c b/security/selinux/ima.c index 7daf59667f59..aa34da9b0aeb 100644 --- a/security/selinux/ima.c +++ b/security/selinux/ima.c @@ -4,7 +4,7 @@ * * Author: Lakshmi Ramasubramanian (nramas@linux.microsoft.com) * - * Measure critical data structures maintainted by SELinux + * Measure critical data structures maintained by SELinux * using IMA subsystem. */ #include <linux/vmalloc.h> diff --git a/security/selinux/include/audit.h b/security/selinux/include/audit.h index 406bceb90c6c..d5495134a5b9 100644 --- a/security/selinux/include/audit.h +++ b/security/selinux/include/audit.h @@ -41,7 +41,7 @@ void selinux_audit_rule_free(void *rule); * selinux_audit_rule_match - determine if a context ID matches a rule. * @sid: the context ID to check * @field: the field this rule refers to - * @op: the operater the rule uses + * @op: the operator the rule uses * @rule: pointer to the audit rule to check against * * Returns 1 if the context id matches the rule, 0 if it does not, and diff --git a/security/selinux/include/avc.h b/security/selinux/include/avc.h index 9301222c8e55..9e055f74daf6 100644 --- a/security/selinux/include/avc.h +++ b/security/selinux/include/avc.h @@ -168,9 +168,6 @@ int avc_get_hash_stats(char *page); unsigned int avc_get_cache_threshold(void); void avc_set_cache_threshold(unsigned int cache_threshold); -/* Attempt to free avc node cache */ -void avc_disable(void); - #ifdef CONFIG_SECURITY_SELINUX_AVC_STATS DECLARE_PER_CPU(struct avc_cache_stats, avc_cache_stats); #endif diff --git a/security/selinux/include/ibpkey.h b/security/selinux/include/ibpkey.h index c992f83b0aae..875b055849e1 100644 --- a/security/selinux/include/ibpkey.h +++ b/security/selinux/include/ibpkey.h @@ -15,6 +15,7 @@ #define _SELINUX_IB_PKEY_H #include <linux/types.h> +#include "flask.h" #ifdef CONFIG_SECURITY_INFINIBAND void sel_ib_pkey_flush(void); diff --git a/security/selinux/include/ima.h b/security/selinux/include/ima.h index 05e04172c86d..93c05e97eb7f 100644 --- a/security/selinux/include/ima.h +++ b/security/selinux/include/ima.h @@ -4,7 +4,7 @@ * * Author: Lakshmi Ramasubramanian (nramas@linux.microsoft.com) * - * Measure critical data structures maintainted by SELinux + * Measure critical data structures maintained by SELinux * using IMA subsystem. */ diff --git a/security/selinux/include/initial_sid_to_string.h b/security/selinux/include/initial_sid_to_string.h index 60820517aa43..ecc6e74fa09b 100644 --- a/security/selinux/include/initial_sid_to_string.h +++ b/security/selinux/include/initial_sid_to_string.h @@ -1,4 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 */ + +#include <linux/stddef.h> + static const char *const initial_sid_to_string[] = { NULL, "kernel", diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index 8746fafeb778..3b605f39e040 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h @@ -65,6 +65,7 @@ #define SE_SBPROC 0x0200 #define SE_SBGENFS 0x0400 #define SE_SBGENFS_XATTR 0x0800 +#define SE_SBNATIVE 0x1000 #define CONTEXT_STR "context" #define FSCONTEXT_STR "fscontext" @@ -384,7 +385,6 @@ struct selinux_kernel_status { extern void selinux_status_update_setenforce(int enforcing); extern void selinux_status_update_policyload(int seqno); extern void selinux_complete_init(void); -extern void exit_sel_fs(void); extern struct path selinux_null; extern void selnl_notify_setenforce(int val); extern void selnl_notify_policyload(u32 seqno); diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c index 767c670d33ea..528f5186e912 100644 --- a/security/selinux/netlabel.c +++ b/security/selinux/netlabel.c @@ -154,8 +154,12 @@ void selinux_netlbl_err(struct sk_buff *skb, u16 family, int error, int gateway) */ void selinux_netlbl_sk_security_free(struct sk_security_struct *sksec) { - if (sksec->nlbl_secattr != NULL) - netlbl_secattr_free(sksec->nlbl_secattr); + if (!sksec->nlbl_secattr) + return; + + netlbl_secattr_free(sksec->nlbl_secattr); + sksec->nlbl_secattr = NULL; + sksec->nlbl_state = NLBL_UNSET; } /** diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index 69a583b91fc5..bad1f6b685fd 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c @@ -951,7 +951,7 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size) * either whitespace or multibyte characters, they shall be * encoded based on the percentage-encoding rule. * If not encoded, the sscanf logic picks up only left-half - * of the supplied name; splitted by a whitespace unexpectedly. + * of the supplied name; split by a whitespace unexpectedly. */ char *r, *w; int c1, c2; @@ -1649,7 +1649,7 @@ static int sel_make_ss_files(struct dentry *dir) struct super_block *sb = dir->d_sb; struct selinux_fs_info *fsi = sb->s_fs_info; int i; - static struct tree_descr files[] = { + static const struct tree_descr files[] = { { "sidtab_hash_stats", &sel_sidtab_hash_stats_ops, S_IRUGO }, }; diff --git a/security/selinux/ss/avtab.c b/security/selinux/ss/avtab.c index 8480ec6c6e75..6766edc0fe68 100644 --- a/security/selinux/ss/avtab.c +++ b/security/selinux/ss/avtab.c @@ -354,7 +354,7 @@ int avtab_alloc_dup(struct avtab *new, const struct avtab *orig) return avtab_alloc_common(new, orig->nslot); } -void avtab_hash_eval(struct avtab *h, char *tag) +void avtab_hash_eval(struct avtab *h, const char *tag) { int i, chain_len, slots_used, max_chain_len; unsigned long long chain2_len_sum; diff --git a/security/selinux/ss/avtab.h b/security/selinux/ss/avtab.h index d3ebea8d146f..d6742fd9c560 100644 --- a/security/selinux/ss/avtab.h +++ b/security/selinux/ss/avtab.h @@ -92,7 +92,7 @@ int avtab_alloc(struct avtab *, u32); int avtab_alloc_dup(struct avtab *new, const struct avtab *orig); struct avtab_datum *avtab_search(struct avtab *h, const struct avtab_key *k); void avtab_destroy(struct avtab *h); -void avtab_hash_eval(struct avtab *h, char *tag); +void avtab_hash_eval(struct avtab *h, const char *tag); struct policydb; int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol, diff --git a/security/selinux/ss/conditional.c b/security/selinux/ss/conditional.c index e11219fdf9f7..b156c181c3c1 100644 --- a/security/selinux/ss/conditional.c +++ b/security/selinux/ss/conditional.c @@ -38,7 +38,7 @@ static int cond_evaluate_expr(struct policydb *p, struct cond_expr *expr) if (sp == (COND_EXPR_MAXDEPTH - 1)) return -1; sp++; - s[sp] = p->bool_val_to_struct[node->bool - 1]->state; + s[sp] = p->bool_val_to_struct[node->boolean - 1]->state; break; case COND_NOT: if (sp < 0) @@ -366,7 +366,7 @@ static int expr_node_isvalid(struct policydb *p, struct cond_expr_node *expr) return 0; } - if (expr->bool > p->p_bools.nprim) { + if (expr->boolean > p->p_bools.nprim) { pr_err("SELinux: conditional expressions uses unknown bool.\n"); return 0; } @@ -401,7 +401,7 @@ static int cond_read_node(struct policydb *p, struct cond_node *node, void *fp) return rc; expr->expr_type = le32_to_cpu(buf[0]); - expr->bool = le32_to_cpu(buf[1]); + expr->boolean = le32_to_cpu(buf[1]); if (!expr_node_isvalid(p, expr)) return -EINVAL; @@ -518,7 +518,7 @@ static int cond_write_node(struct policydb *p, struct cond_node *node, for (i = 0; i < node->expr.len; i++) { buf[0] = cpu_to_le32(node->expr.nodes[i].expr_type); - buf[1] = cpu_to_le32(node->expr.nodes[i].bool); + buf[1] = cpu_to_le32(node->expr.nodes[i].boolean); rc = put_entry(buf, sizeof(u32), 2, fp); if (rc) return rc; diff --git a/security/selinux/ss/conditional.h b/security/selinux/ss/conditional.h index e47ec6ddeaf6..5a7b51278dc6 100644 --- a/security/selinux/ss/conditional.h +++ b/security/selinux/ss/conditional.h @@ -29,7 +29,7 @@ struct cond_expr_node { #define COND_NEQ 7 /* bool != bool */ #define COND_LAST COND_NEQ u32 expr_type; - u32 bool; + u32 boolean; }; struct cond_expr { diff --git a/security/selinux/ss/context.h b/security/selinux/ss/context.h index eda32c3d4c0a..aed704b8c642 100644 --- a/security/selinux/ss/context.h +++ b/security/selinux/ss/context.h @@ -167,6 +167,8 @@ static inline int context_cpy(struct context *dst, const struct context *src) rc = mls_context_cpy(dst, src); if (rc) { kfree(dst->str); + dst->str = NULL; + dst->len = 0; return rc; } return 0; diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c index adcfb63b3550..31b08b34c722 100644 --- a/security/selinux/ss/policydb.c +++ b/security/selinux/ss/policydb.c @@ -42,7 +42,7 @@ #include "services.h" #ifdef DEBUG_HASHES -static const char *symtab_name[SYM_NUM] = { +static const char *const symtab_name[SYM_NUM] = { "common prefixes", "classes", "roles", @@ -2257,6 +2257,10 @@ static int ocontext_read(struct policydb *p, const struct policydb_compat_info * if (rc) goto out; + if (i == OCON_FS) + pr_warn("SELinux: void and deprecated fs ocon %s\n", + c->u.name); + rc = context_read_and_validate(&c->context[0], p, fp); if (rc) goto out; diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h index ffc4e7bad205..74b63ed1173f 100644 --- a/security/selinux/ss/policydb.h +++ b/security/selinux/ss/policydb.h @@ -225,7 +225,7 @@ struct genfs { /* object context array indices */ #define OCON_ISID 0 /* initial SIDs */ -#define OCON_FS 1 /* unlabeled file systems */ +#define OCON_FS 1 /* unlabeled file systems (deprecated) */ #define OCON_PORT 2 /* TCP and UDP port numbers */ #define OCON_NETIF 3 /* network interfaces */ #define OCON_NODE 4 /* nodes */ diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index f14d1ffe54c5..78946b71c1c1 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -583,7 +583,7 @@ static void type_attribute_bounds_av(struct policydb *policydb, /* * flag which drivers have permissions - * only looking for ioctl based extended permssions + * only looking for ioctl based extended permissions */ void services_compute_xperms_drivers( struct extended_perms *xperms, @@ -3541,38 +3541,38 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) tmprule = kzalloc(sizeof(struct selinux_audit_rule), GFP_KERNEL); if (!tmprule) return -ENOMEM; - context_init(&tmprule->au_ctxt); rcu_read_lock(); policy = rcu_dereference(state->policy); policydb = &policy->policydb; - tmprule->au_seqno = policy->latest_granting; - switch (field) { case AUDIT_SUBJ_USER: case AUDIT_OBJ_USER: - rc = -EINVAL; userdatum = symtab_search(&policydb->p_users, rulestr); - if (!userdatum) - goto out; + if (!userdatum) { + rc = -EINVAL; + goto err; + } tmprule->au_ctxt.user = userdatum->value; break; case AUDIT_SUBJ_ROLE: case AUDIT_OBJ_ROLE: - rc = -EINVAL; roledatum = symtab_search(&policydb->p_roles, rulestr); - if (!roledatum) - goto out; + if (!roledatum) { + rc = -EINVAL; + goto err; + } tmprule->au_ctxt.role = roledatum->value; break; case AUDIT_SUBJ_TYPE: case AUDIT_OBJ_TYPE: - rc = -EINVAL; typedatum = symtab_search(&policydb->p_types, rulestr); - if (!typedatum) - goto out; + if (!typedatum) { + rc = -EINVAL; + goto err; + } tmprule->au_ctxt.type = typedatum->value; break; case AUDIT_SUBJ_SEN: @@ -3582,20 +3582,18 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) rc = mls_from_string(policydb, rulestr, &tmprule->au_ctxt, GFP_ATOMIC); if (rc) - goto out; + goto err; break; } - rc = 0; -out: rcu_read_unlock(); - if (rc) { - selinux_audit_rule_free(tmprule); - tmprule = NULL; - } - *rule = tmprule; + return 0; +err: + rcu_read_unlock(); + selinux_audit_rule_free(tmprule); + *rule = NULL; return rc; } |