Merge tag 'selinux-pr-20230626' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 28 Jun 2023 00:18:48 +0000 (17:18 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 28 Jun 2023 00:18:48 +0000 (17:18 -0700)
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

24 files changed:
include/linux/lsm_hook_defs.h
include/linux/security.h
net/mptcp/subflow.c
security/security.c
security/selinux/Makefile
security/selinux/avc.c
security/selinux/hooks.c
security/selinux/ima.c
security/selinux/include/audit.h
security/selinux/include/avc.h
security/selinux/include/ibpkey.h
security/selinux/include/ima.h
security/selinux/include/initial_sid_to_string.h
security/selinux/include/security.h
security/selinux/netlabel.c
security/selinux/selinuxfs.c
security/selinux/ss/avtab.c
security/selinux/ss/avtab.h
security/selinux/ss/conditional.c
security/selinux/ss/conditional.h
security/selinux/ss/context.h
security/selinux/ss/policydb.c
security/selinux/ss/policydb.h
security/selinux/ss/services.c

index 6bb55e6..7308a1a 100644 (file)
@@ -343,6 +343,7 @@ LSM_HOOK(void, LSM_RET_VOID, sctp_sk_clone, struct sctp_association *asoc,
         struct sock *sk, struct sock *newsk)
 LSM_HOOK(int, 0, sctp_assoc_established, struct sctp_association *asoc,
         struct sk_buff *skb)
+LSM_HOOK(int, 0, mptcp_add_subflow, struct sock *sk, struct sock *ssk)
 #endif /* CONFIG_SECURITY_NETWORK */
 
 #ifdef CONFIG_SECURITY_INFINIBAND
index e2734e9..3282850 100644 (file)
@@ -1465,6 +1465,7 @@ void security_sctp_sk_clone(struct sctp_association *asoc, struct sock *sk,
                            struct sock *newsk);
 int security_sctp_assoc_established(struct sctp_association *asoc,
                                    struct sk_buff *skb);
+int security_mptcp_add_subflow(struct sock *sk, struct sock *ssk);
 
 #else  /* CONFIG_SECURITY_NETWORK */
 static inline int security_unix_stream_connect(struct sock *sock,
@@ -1692,6 +1693,11 @@ static inline int security_sctp_assoc_established(struct sctp_association *asoc,
 {
        return 0;
 }
+
+static inline int security_mptcp_add_subflow(struct sock *sk, struct sock *ssk)
+{
+       return 0;
+}
 #endif /* CONFIG_SECURITY_NETWORK */
 
 #ifdef CONFIG_SECURITY_INFINIBAND
index d9c8b21..8ff5c9f 100644 (file)
@@ -1668,6 +1668,10 @@ int mptcp_subflow_create_socket(struct sock *sk, unsigned short family,
 
        lock_sock_nested(sf->sk, SINGLE_DEPTH_NESTING);
 
+       err = security_mptcp_add_subflow(sk, sf->sk);
+       if (err)
+               goto release_ssk;
+
        /* the newly created socket has to be in the same cgroup as its parent */
        mptcp_attach_cgroup(sk, sf->sk);
 
@@ -1680,6 +1684,8 @@ int mptcp_subflow_create_socket(struct sock *sk, unsigned short family,
        get_net_track(net, &sf->sk->ns_tracker, GFP_KERNEL);
        sock_inuse_add(net, 1);
        err = tcp_set_ulp(sf->sk, "mptcp");
+
+release_ssk:
        release_sock(sf->sk);
 
        if (err) {
index d5ff7ff..0e7be1d 100644 (file)
@@ -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
index 8b21520..8363796 100644 (file)
@@ -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)
index eaed5c2..1074db6 100644 (file)
@@ -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); */
-       }
-}
index 79b4890..d06e350 100644 (file)
@@ -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),
index 7daf596..aa34da9 100644 (file)
@@ -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>
index 406bceb..d549513 100644 (file)
@@ -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
index 9301222..9e055f7 100644 (file)
@@ -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
index c992f83..875b055 100644 (file)
@@ -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);
index 05e0417..93c05e9 100644 (file)
@@ -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.
  */
 
index 6082051..ecc6e74 100644 (file)
@@ -1,4 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0 */
+
+#include <linux/stddef.h>
+
 static const char *const initial_sid_to_string[] = {
        NULL,
        "kernel",
index 8746faf..3b605f3 100644 (file)
@@ -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);
index 767c670..528f518 100644 (file)
@@ -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;
 }
 
 /**
index 69a583b..bad1f6b 100644 (file)
@@ -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 },
        };
 
index 8480ec6..6766edc 100644 (file)
@@ -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;
index d3ebea8..d6742fd 100644 (file)
@@ -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,
index e11219f..b156c18 100644 (file)
@@ -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;
index e47ec6d..5a7b512 100644 (file)
@@ -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 {
index eda32c3..aed704b 100644 (file)
@@ -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;
index adcfb63..31b08b3 100644 (file)
@@ -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;
index ffc4e7b..74b63ed 100644 (file)
@@ -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 */
index f14d1ff..78946b7 100644 (file)
@@ -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;
 }