Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 7 Sep 2013 21:34:07 +0000 (14:34 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 7 Sep 2013 21:34:07 +0000 (14:34 -0700)
Pull security subsystem updates from James Morris:
 "Nothing major for this kernel, just maintenance updates"

* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: (21 commits)
  apparmor: add the ability to report a sha1 hash of loaded policy
  apparmor: export set of capabilities supported by the apparmor module
  apparmor: add the profile introspection file to interface
  apparmor: add an optional profile attachment string for profiles
  apparmor: add interface files for profiles and namespaces
  apparmor: allow setting any profile into the unconfined state
  apparmor: make free_profile available outside of policy.c
  apparmor: rework namespace free path
  apparmor: update how unconfined is handled
  apparmor: change how profile replacement update is done
  apparmor: convert profile lists to RCU based locking
  apparmor: provide base for multiple profiles to be replaced at once
  apparmor: add a features/policy dir to interface
  apparmor: enable users to query whether apparmor is enabled
  apparmor: remove minimum size check for vmalloc()
  Smack: parse multiple rules per write to load2, up to PAGE_SIZE-1 bytes
  Smack: network label match fix
  security: smack: add a hash table to quicken smk_find_entry()
  security: smack: fix memleak in smk_write_rules_list()
  xattr: Constify ->name member of "struct xattr".
  ...

1  2 
security/apparmor/lsm.c
security/smack/smack_lsm.c

diff --combined security/apparmor/lsm.c
index e3a704c75ef68e74b5dadad2be437f8c2b6640d4,edb3ce15e92d9df51b2e1459ac6aeda9a508678c..fb99e18123b41b4f049fd98078e88aafccb7729b
@@@ -508,19 -508,21 +508,21 @@@ static int apparmor_getprocattr(struct 
        /* released below */
        const struct cred *cred = get_task_cred(task);
        struct aa_task_cxt *cxt = cred_cxt(cred);
+       struct aa_profile *profile = NULL;
  
        if (strcmp(name, "current") == 0)
-               error = aa_getprocattr(aa_newest_version(cxt->profile),
-                                      value);
+               profile = aa_get_newest_profile(cxt->profile);
        else if (strcmp(name, "prev") == 0  && cxt->previous)
-               error = aa_getprocattr(aa_newest_version(cxt->previous),
-                                      value);
+               profile = aa_get_newest_profile(cxt->previous);
        else if (strcmp(name, "exec") == 0 && cxt->onexec)
-               error = aa_getprocattr(aa_newest_version(cxt->onexec),
-                                      value);
+               profile = aa_get_newest_profile(cxt->onexec);
        else
                error = -EINVAL;
  
+       if (profile)
+               error = aa_getprocattr(profile, value);
+       aa_put_profile(profile);
        put_cred(cred);
  
        return error;
@@@ -666,7 -668,6 +668,7 @@@ static int param_set_aabool(const char 
  static int param_get_aabool(char *buffer, const struct kernel_param *kp);
  #define param_check_aabool param_check_bool
  static struct kernel_param_ops param_ops_aabool = {
 +      .flags = KERNEL_PARAM_FL_NOARG,
        .set = param_set_aabool,
        .get = param_get_aabool
  };
@@@ -683,7 -684,6 +685,7 @@@ static int param_set_aalockpolicy(cons
  static int param_get_aalockpolicy(char *buffer, const struct kernel_param *kp);
  #define param_check_aalockpolicy param_check_bool
  static struct kernel_param_ops param_ops_aalockpolicy = {
 +      .flags = KERNEL_PARAM_FL_NOARG,
        .set = param_set_aalockpolicy,
        .get = param_get_aalockpolicy
  };
@@@ -744,7 -744,7 +746,7 @@@ module_param_named(paranoid_load, aa_g_
  
  /* Boot time disable flag */
  static bool apparmor_enabled = CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE;
- module_param_named(enabled, apparmor_enabled, aabool, S_IRUSR);
+ module_param_named(enabled, apparmor_enabled, bool, S_IRUGO);
  
  static int __init apparmor_enabled_setup(char *str)
  {
@@@ -843,7 -843,7 +845,7 @@@ static int param_get_mode(char *buffer
        if (!apparmor_enabled)
                return -EINVAL;
  
-       return sprintf(buffer, "%s", profile_mode_names[aa_g_profile_mode]);
+       return sprintf(buffer, "%s", aa_profile_mode_names[aa_g_profile_mode]);
  }
  
  static int param_set_mode(const char *val, struct kernel_param *kp)
        if (!val)
                return -EINVAL;
  
-       for (i = 0; i < APPARMOR_NAMES_MAX_INDEX; i++) {
-               if (strcmp(val, profile_mode_names[i]) == 0) {
+       for (i = 0; i < APPARMOR_MODE_NAMES_MAX_INDEX; i++) {
+               if (strcmp(val, aa_profile_mode_names[i]) == 0) {
                        aa_g_profile_mode = i;
                        return 0;
                }
index eefbd10e408f18b87d35c35d729fabf088734d65,19de5e2376830bf7474968ac9e753379a5ce5fd2..8825375cc031709b3918cd073cd574708c3f0405
@@@ -582,7 -582,7 +582,7 @@@ static void smack_inode_free_security(s
   * Returns 0 if it all works out, -ENOMEM if there's no memory
   */
  static int smack_inode_init_security(struct inode *inode, struct inode *dir,
-                                    const struct qstr *qstr, char **name,
+                                    const struct qstr *qstr, const char **name,
                                     void **value, size_t *len)
  {
        struct inode_smack *issp = inode->i_security;
        char *dsp = smk_of_inode(dir);
        int may;
  
-       if (name) {
-               *name = kstrdup(XATTR_SMACK_SUFFIX, GFP_NOFS);
-               if (*name == NULL)
-                       return -ENOMEM;
-       }
+       if (name)
+               *name = XATTR_SMACK_SUFFIX;
  
        if (value) {
                rcu_read_lock();
@@@ -1998,11 -1995,12 +1995,11 @@@ static void smk_ipv6_port_label(struct 
   *
   * Create or update the port list entry
   */
 -static int smk_ipv6_port_check(struct sock *sk, struct sockaddr *address,
 +static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address,
                                int act)
  {
        __be16 *bep;
        __be32 *be32p;
 -      struct sockaddr_in6 *addr6;
        struct smk_port_label *spp;
        struct socket_smack *ssp = sk->sk_security;
        struct smack_known *skp;
        /*
         * Get the IP address and port from the address.
         */
 -      addr6 = (struct sockaddr_in6 *)address;
 -      port = ntohs(addr6->sin6_port);
 -      bep = (__be16 *)(&addr6->sin6_addr);
 -      be32p = (__be32 *)(&addr6->sin6_addr);
 +      port = ntohs(address->sin6_port);
 +      bep = (__be16 *)(&address->sin6_addr);
 +      be32p = (__be32 *)(&address->sin6_addr);
  
        /*
         * It's remote, so port lookup does no good.
@@@ -2058,9 -2057,9 +2055,9 @@@ auditout
        ad.a.u.net->family = sk->sk_family;
        ad.a.u.net->dport = port;
        if (act == SMK_RECEIVING)
 -              ad.a.u.net->v6info.saddr = addr6->sin6_addr;
 +              ad.a.u.net->v6info.saddr = address->sin6_addr;
        else
 -              ad.a.u.net->v6info.daddr = addr6->sin6_addr;
 +              ad.a.u.net->v6info.daddr = address->sin6_addr;
  #endif
        return smk_access(skp, object, MAY_WRITE, &ad);
  }
@@@ -2199,8 -2198,7 +2196,8 @@@ static int smack_socket_connect(struct 
        case PF_INET6:
                if (addrlen < sizeof(struct sockaddr_in6))
                        return -EINVAL;
 -              rc = smk_ipv6_port_check(sock->sk, sap, SMK_CONNECTING);
 +              rc = smk_ipv6_port_check(sock->sk, (struct sockaddr_in6 *)sap,
 +                                              SMK_CONNECTING);
                break;
        }
        return rc;
@@@ -3033,7 -3031,7 +3030,7 @@@ static int smack_socket_sendmsg(struct 
                                int size)
  {
        struct sockaddr_in *sip = (struct sockaddr_in *) msg->msg_name;
 -      struct sockaddr *sap = (struct sockaddr *) msg->msg_name;
 +      struct sockaddr_in6 *sap = (struct sockaddr_in6 *) msg->msg_name;
        int rc = 0;
  
        /*
@@@ -3065,6 -3063,8 +3062,8 @@@ static struct smack_known *smack_from_s
  {
        struct smack_known *skp;
        int found = 0;
+       int acat;
+       int kcat;
  
        if ((sap->flags & NETLBL_SECATTR_MLS_LVL) != 0) {
                /*
                list_for_each_entry(skp, &smack_known_list, list) {
                        if (sap->attr.mls.lvl != skp->smk_netlabel.attr.mls.lvl)
                                continue;
-                       if (memcmp(sap->attr.mls.cat,
-                               skp->smk_netlabel.attr.mls.cat,
-                               SMK_CIPSOLEN) != 0)
-                               continue;
-                       found = 1;
-                       break;
+                       /*
+                        * Compare the catsets. Use the netlbl APIs.
+                        */
+                       if ((sap->flags & NETLBL_SECATTR_MLS_CAT) == 0) {
+                               if ((skp->smk_netlabel.flags &
+                                    NETLBL_SECATTR_MLS_CAT) == 0)
+                                       found = 1;
+                               break;
+                       }
+                       for (acat = -1, kcat = -1; acat == kcat; ) {
+                               acat = netlbl_secattr_catmap_walk(
+                                       sap->attr.mls.cat, acat + 1);
+                               kcat = netlbl_secattr_catmap_walk(
+                                       skp->smk_netlabel.attr.mls.cat,
+                                       kcat + 1);
+                               if (acat < 0 || kcat < 0)
+                                       break;
+                       }
+                       if (acat == kcat) {
+                               found = 1;
+                               break;
+                       }
                }
                rcu_read_unlock();
  
        return smack_net_ambient;
  }
  
 -static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr *sap)
 +static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr_in6 *sip)
  {
 -      struct sockaddr_in6 *sip = (struct sockaddr_in6 *)sap;
        u8 nexthdr;
        int offset;
        int proto = -EINVAL;
@@@ -3179,7 -3196,7 +3194,7 @@@ static int smack_socket_sock_rcv_skb(st
        struct netlbl_lsm_secattr secattr;
        struct socket_smack *ssp = sk->sk_security;
        struct smack_known *skp;
 -      struct sockaddr sadd;
 +      struct sockaddr_in6 sadd;
        int rc = 0;
        struct smk_audit_info ad;
  #ifdef CONFIG_AUDIT
@@@ -3877,12 -3894,12 +3892,12 @@@ static __init void init_smack_known_lis
        /*
         * Create the known labels list
         */
-       list_add(&smack_known_huh.list, &smack_known_list);
-       list_add(&smack_known_hat.list, &smack_known_list);
-       list_add(&smack_known_star.list, &smack_known_list);
-       list_add(&smack_known_floor.list, &smack_known_list);
-       list_add(&smack_known_invalid.list, &smack_known_list);
-       list_add(&smack_known_web.list, &smack_known_list);
+       smk_insert_entry(&smack_known_huh);
+       smk_insert_entry(&smack_known_hat);
+       smk_insert_entry(&smack_known_star);
+       smk_insert_entry(&smack_known_floor);
+       smk_insert_entry(&smack_known_invalid);
+       smk_insert_entry(&smack_known_web);
  }
  
  /**