Merge commit 'v3.15' into next
authorJames Morris <james.l.morris@oracle.com>
Tue, 24 Jun 2014 08:46:07 +0000 (18:46 +1000)
committerJames Morris <james.l.morris@oracle.com>
Tue, 24 Jun 2014 08:46:07 +0000 (18:46 +1000)
1  2 
Documentation/security/Smack.txt
include/linux/security.h
security/security.c
security/selinux/hooks.c

index 5597917703e08080783cc4cbfe558f350cac6521,5ea996f21d6c91734b5196e2d62c34a537379fec..b6ef7e9dba30f52a0c0c222a08158fa543bef211
@@@ -3,7 -3,7 +3,7 @@@
      "Good for you, you've decided to clean the elevator!"
      - The Elevator, from Dark Star
  
- Smack is the the Simplified Mandatory Access Control Kernel.
+ Smack is the Simplified Mandatory Access Control Kernel.
  Smack is a kernel based implementation of mandatory access
  control that includes simplicity in its primary design goals.
  
@@@ -204,16 -204,6 +204,16 @@@ onlyca
        these capabilities are effective at for processes with any
        label. The value is set by writing the desired label to the
        file or cleared by writing "-" to the file.
 +ptrace
 +      This is used to define the current ptrace policy
 +      0 - default: this is the policy that relies on smack access rules.
 +          For the PTRACE_READ a subject needs to have a read access on
 +          object. For the PTRACE_ATTACH a read-write access is required.
 +      1 - exact: this is the policy that limits PTRACE_ATTACH. Attach is
 +          only allowed when subject's and object's labels are equal.
 +          PTRACE_READ is not affected. Can be overriden with CAP_SYS_PTRACE.
 +      2 - draconian: this policy behaves like the 'exact' above with an
 +          exception that it can't be overriden with CAP_SYS_PTRACE.
  revoke-subject
        Writing a Smack label here sets the access to '-' for all access
        rules with that subject label.
diff --combined include/linux/security.h
index 6726006bc766596deee7d14f52220d29c3ebccbe,6478ce3252c7d83fdd853ff2797a54d3cc591db6..9c6b9722ff48d5a2304367f5f2448a7201ea55b4
@@@ -1708,7 -1708,7 +1708,7 @@@ struct security_operations 
        void (*key_free) (struct key *key);
        int (*key_permission) (key_ref_t key_ref,
                               const struct cred *cred,
 -                             key_perm_t perm);
 +                             unsigned perm);
        int (*key_getsecurity)(struct key *key, char **_buffer);
  #endif        /* CONFIG_KEYS */
  
@@@ -1793,7 -1793,8 +1793,8 @@@ int security_inode_mkdir(struct inode *
  int security_inode_rmdir(struct inode *dir, struct dentry *dentry);
  int security_inode_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev);
  int security_inode_rename(struct inode *old_dir, struct dentry *old_dentry,
-                         struct inode *new_dir, struct dentry *new_dentry);
+                         struct inode *new_dir, struct dentry *new_dentry,
+                         unsigned int flags);
  int security_inode_readlink(struct dentry *dentry);
  int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd);
  int security_inode_permission(struct inode *inode, int mask);
@@@ -2161,7 -2162,8 +2162,8 @@@ static inline int security_inode_mknod(
  static inline int security_inode_rename(struct inode *old_dir,
                                         struct dentry *old_dentry,
                                         struct inode *new_dir,
-                                        struct dentry *new_dentry)
+                                        struct dentry *new_dentry,
+                                        unsigned int flags)
  {
        return 0;
  }
@@@ -2955,7 -2957,8 +2957,8 @@@ int security_path_symlink(struct path *
  int security_path_link(struct dentry *old_dentry, struct path *new_dir,
                       struct dentry *new_dentry);
  int security_path_rename(struct path *old_dir, struct dentry *old_dentry,
-                        struct path *new_dir, struct dentry *new_dentry);
+                        struct path *new_dir, struct dentry *new_dentry,
+                        unsigned int flags);
  int security_path_chmod(struct path *path, umode_t mode);
  int security_path_chown(struct path *path, kuid_t uid, kgid_t gid);
  int security_path_chroot(struct path *path);
@@@ -3003,7 -3006,8 +3006,8 @@@ static inline int security_path_link(st
  static inline int security_path_rename(struct path *old_dir,
                                       struct dentry *old_dentry,
                                       struct path *new_dir,
-                                      struct dentry *new_dentry)
+                                      struct dentry *new_dentry,
+                                      unsigned int flags)
  {
        return 0;
  }
@@@ -3030,7 -3034,7 +3034,7 @@@ static inline int security_path_chroot(
  int security_key_alloc(struct key *key, const struct cred *cred, unsigned long flags);
  void security_key_free(struct key *key);
  int security_key_permission(key_ref_t key_ref,
 -                          const struct cred *cred, key_perm_t perm);
 +                          const struct cred *cred, unsigned perm);
  int security_key_getsecurity(struct key *key, char **_buffer);
  
  #else
@@@ -3048,7 -3052,7 +3052,7 @@@ static inline void security_key_free(st
  
  static inline int security_key_permission(key_ref_t key_ref,
                                          const struct cred *cred,
 -                                        key_perm_t perm)
 +                                        unsigned perm)
  {
        return 0;
  }
diff --combined security/security.c
index d91fec458e905053872cd9737b819ea142de9989,8b774f362a3d4ed252f626c8e6de5634a5820148..31614e9e96e556883aa947fc1360e9e03127883d
@@@ -433,11 -433,20 +433,20 @@@ int security_path_link(struct dentry *o
  }
  
  int security_path_rename(struct path *old_dir, struct dentry *old_dentry,
-                        struct path *new_dir, struct dentry *new_dentry)
+                        struct path *new_dir, struct dentry *new_dentry,
+                        unsigned int flags)
  {
        if (unlikely(IS_PRIVATE(old_dentry->d_inode) ||
                     (new_dentry->d_inode && IS_PRIVATE(new_dentry->d_inode))))
                return 0;
+       if (flags & RENAME_EXCHANGE) {
+               int err = security_ops->path_rename(new_dir, new_dentry,
+                                                   old_dir, old_dentry);
+               if (err)
+                       return err;
+       }
        return security_ops->path_rename(old_dir, old_dentry, new_dir,
                                         new_dentry);
  }
@@@ -524,11 -533,20 +533,20 @@@ int security_inode_mknod(struct inode *
  }
  
  int security_inode_rename(struct inode *old_dir, struct dentry *old_dentry,
-                          struct inode *new_dir, struct dentry *new_dentry)
+                          struct inode *new_dir, struct dentry *new_dentry,
+                          unsigned int flags)
  {
          if (unlikely(IS_PRIVATE(old_dentry->d_inode) ||
              (new_dentry->d_inode && IS_PRIVATE(new_dentry->d_inode))))
                return 0;
+       if (flags & RENAME_EXCHANGE) {
+               int err = security_ops->inode_rename(new_dir, new_dentry,
+                                                    old_dir, old_dentry);
+               if (err)
+                       return err;
+       }
        return security_ops->inode_rename(old_dir, old_dentry,
                                           new_dir, new_dentry);
  }
@@@ -1407,7 -1425,7 +1425,7 @@@ void security_key_free(struct key *key
  }
  
  int security_key_permission(key_ref_t key_ref,
 -                          const struct cred *cred, key_perm_t perm)
 +                          const struct cred *cred, unsigned perm)
  {
        return security_ops->key_permission(key_ref, cred, perm);
  }
diff --combined security/selinux/hooks.c
index d4cbf7d16f075e43b6675828903baee5d2088dde,2c7341dbc5d68d1948ad0efa713ad3a85307608e..83d06db34d0358df289f8337b37f200d800b6c41
@@@ -2123,13 -2123,11 +2123,13 @@@ static int selinux_bprm_set_creds(struc
                new_tsec->exec_sid = 0;
  
                /*
 -               * Minimize confusion: if no_new_privs and a transition is
 -               * explicitly requested, then fail the exec.
 +               * Minimize confusion: if no_new_privs or nosuid and a
 +               * transition is explicitly requested, then fail the exec.
                 */
                if (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS)
                        return -EPERM;
 +              if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID)
 +                      return -EACCES;
        } else {
                /* Check for a default transition on this program. */
                rc = security_transition_sid(old_tsec->sid, isec->sid,
@@@ -2772,7 -2770,6 +2772,7 @@@ static int selinux_inode_follow_link(st
  
  static noinline int audit_inode_permission(struct inode *inode,
                                           u32 perms, u32 audited, u32 denied,
 +                                         int result,
                                           unsigned flags)
  {
        struct common_audit_data ad;
        ad.u.inode = inode;
  
        rc = slow_avc_audit(current_sid(), isec->sid, isec->sclass, perms,
 -                          audited, denied, &ad, flags);
 +                          audited, denied, result, &ad, flags);
        if (rc)
                return rc;
        return 0;
@@@ -2825,7 -2822,7 +2825,7 @@@ static int selinux_inode_permission(str
        if (likely(!audited))
                return rc;
  
 -      rc2 = audit_inode_permission(inode, perms, audited, denied, flags);
 +      rc2 = audit_inode_permission(inode, perms, audited, denied, rc, flags);
        if (rc2)
                return rc2;
        return rc;
@@@ -3320,6 -3317,9 +3320,9 @@@ static int selinux_file_fcntl(struct fi
        case F_GETLK:
        case F_SETLK:
        case F_SETLKW:
+       case F_OFD_GETLK:
+       case F_OFD_SETLK:
+       case F_OFD_SETLKW:
  #if BITS_PER_LONG == 32
        case F_GETLK64:
        case F_SETLK64:
@@@ -5722,7 -5722,7 +5725,7 @@@ static void selinux_key_free(struct ke
  
  static int selinux_key_permission(key_ref_t key_ref,
                                  const struct cred *cred,
 -                                key_perm_t perm)
 +                                unsigned perm)
  {
        struct key *key;
        struct key_security_struct *ksec;