Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux...
Linus Torvalds [Wed, 3 Oct 2012 04:38:48 +0000 (21:38 -0700)]
Pull security subsystem updates from James Morris:
 "Highlights:

   - Integrity: add local fs integrity verification to detect offline
     attacks
   - Integrity: add digital signature verification
   - Simple stacking of Yama with other LSMs (per LSS discussions)
   - IBM vTPM support on ppc64
   - Add new driver for Infineon I2C TIS TPM
   - Smack: add rule revocation for subject labels"

Fixed conflicts with the user namespace support in kernel/auditsc.c and
security/integrity/ima/ima_policy.c.

* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: (39 commits)
  Documentation: Update git repository URL for Smack userland tools
  ima: change flags container data type
  Smack: setprocattr memory leak fix
  Smack: implement revoking all rules for a subject label
  Smack: remove task_wait() hook.
  ima: audit log hashes
  ima: generic IMA action flag handling
  ima: rename ima_must_appraise_or_measure
  audit: export audit_log_task_info
  tpm: fix tpm_acpi sparse warning on different address spaces
  samples/seccomp: fix 31 bit build on s390
  ima: digital signature verification support
  ima: add support for different security.ima data types
  ima: add ima_inode_setxattr/removexattr function and calls
  ima: add inode_post_setattr call
  ima: replace iint spinblock with rwlock/read_lock
  ima: allocating iint improvements
  ima: add appraise action keywords and default rules
  ima: integrity appraisal extension
  vfs: move ima_file_free before releasing the file
  ...

1  2 
Documentation/kernel-parameters.txt
drivers/char/tpm/tpm.c
fs/file_table.c
fs/xattr.c
include/linux/audit.h
include/linux/security.h
include/linux/xattr.h
kernel/auditsc.c
security/integrity/ima/ima_policy.c
security/security.c

Simple merge
@@@ -1172,10 -1168,10 +1168,10 @@@ int tpm_release(struct inode *inode, st
        struct tpm_chip *chip = file->private_data;
  
        del_singleshot_timer_sync(&chip->user_read_timer);
 -      flush_work_sync(&chip->work);
 +      flush_work(&chip->work);
        file->private_data = NULL;
        atomic_set(&chip->data_pending, 0);
-       kfree(chip->data_buffer);
+       kzfree(chip->data_buffer);
        clear_bit(0, &chip->is_open);
        put_device(chip->dev);
        return 0;
@@@ -1225,9 -1221,8 +1221,8 @@@ ssize_t tpm_read(struct file *file, cha
        int rc;
  
        del_singleshot_timer_sync(&chip->user_read_timer);
 -      flush_work_sync(&chip->work);
 +      flush_work(&chip->work);
        ret_size = atomic_read(&chip->data_pending);
-       atomic_set(&chip->data_pending, 0);
        if (ret_size > 0) {     /* relay data */
                ssize_t orig_ret_size = ret_size;
                if (size < ret_size)
diff --cc fs/file_table.c
Simple merge
diff --cc fs/xattr.c
Simple merge
@@@ -639,9 -638,10 +640,10 @@@ extern int audit_signals
  #define audit_core_dumps(i) do { ; } while (0)
  #define audit_seccomp(i,s,c) do { ; } while (0)
  #define auditsc_get_stamp(c,t,s) (0)
 -#define audit_get_loginuid(t) (-1)
 +#define audit_get_loginuid(t) (INVALID_UID)
  #define audit_get_sessionid(t) (-1)
  #define audit_log_task_context(b) do { ; } while (0)
+ #define audit_log_task_info(b, t) do { ; } while (0)
  #define audit_ipc_obj(i) ((void)0)
  #define audit_ipc_set_perm(q,u,g,m) ((void)0)
  #define audit_bprm(p) ({ 0; })
Simple merge
Simple merge
@@@ -1151,8 -1160,32 +1152,38 @@@ void audit_log_task_info(struct audit_b
        char name[sizeof(tsk->comm)];
        struct mm_struct *mm = tsk->mm;
        struct vm_area_struct *vma;
+       char *tty;
+       if (!ab)
+               return;
  
        /* tsk == current */
+       cred = current_cred();
+       spin_lock_irq(&tsk->sighand->siglock);
+       if (tsk->signal && tsk->signal->tty && tsk->signal->tty->name)
+               tty = tsk->signal->tty->name;
+       else
+               tty = "(none)";
+       spin_unlock_irq(&tsk->sighand->siglock);
+       audit_log_format(ab,
+                        " ppid=%ld pid=%d auid=%u uid=%u gid=%u"
+                        " euid=%u suid=%u fsuid=%u"
+                        " egid=%u sgid=%u fsgid=%u ses=%u tty=%s",
+                        sys_getppid(),
+                        tsk->pid,
 -                       tsk->loginuid, cred->uid, cred->gid,
 -                       cred->euid, cred->suid, cred->fsuid,
 -                       cred->egid, cred->sgid, cred->fsgid,
++                       from_kuid(&init_user_ns, tsk->loginuid),
++                       from_kuid(&init_user_ns, cred->uid),
++                       from_kgid(&init_user_ns, cred->gid),
++                       from_kuid(&init_user_ns, cred->euid),
++                       from_kuid(&init_user_ns, cred->suid),
++                       from_kuid(&init_user_ns, cred->fsuid),
++                       from_kgid(&init_user_ns, cred->egid),
++                       from_kgid(&init_user_ns, cred->sgid),
++                       from_kgid(&init_user_ns, cred->fsgid),
+                        tsk->sessionid, tty);
  
        get_task_comm(name, tsk);
        audit_log_format(ab, " comm=");
        audit_log_task_context(ab);
  }
  
+ EXPORT_SYMBOL(audit_log_task_info);
  static int audit_log_pid_context(struct audit_context *context, pid_t pid,
 -                               uid_t auid, uid_t uid, unsigned int sessionid,
 +                               kuid_t auid, kuid_t uid, unsigned int sessionid,
                                 u32 sid, char *comm)
  {
        struct audit_buffer *ab;
@@@ -39,7 -45,8 +45,8 @@@ struct ima_rule_entry 
        enum ima_hooks func;
        int mask;
        unsigned long fsmagic;
 -      uid_t uid;
 -      uid_t fowner;
 +      kuid_t uid;
++      kuid_t fowner;
        struct {
                void *rule;     /* LSM file metadata specific */
                int type;       /* audit type */
@@@ -75,14 -82,28 +82,28 @@@ static struct ima_rule_entry default_ru
         .flags = IMA_FUNC | IMA_MASK | IMA_UID},
  };
  
- static LIST_HEAD(measure_default_rules);
- static LIST_HEAD(measure_policy_rules);
- static struct list_head *ima_measure;
+ static struct ima_rule_entry default_appraise_rules[] = {
+       {.action = DONT_APPRAISE,.fsmagic = PROC_SUPER_MAGIC,.flags = IMA_FSMAGIC},
+       {.action = DONT_APPRAISE,.fsmagic = SYSFS_MAGIC,.flags = IMA_FSMAGIC},
+       {.action = DONT_APPRAISE,.fsmagic = DEBUGFS_MAGIC,.flags = IMA_FSMAGIC},
+       {.action = DONT_APPRAISE,.fsmagic = TMPFS_MAGIC,.flags = IMA_FSMAGIC},
+       {.action = DONT_APPRAISE,.fsmagic = RAMFS_MAGIC,.flags = IMA_FSMAGIC},
+       {.action = DONT_APPRAISE,.fsmagic = DEVPTS_SUPER_MAGIC,.flags = IMA_FSMAGIC},
+       {.action = DONT_APPRAISE,.fsmagic = BINFMTFS_MAGIC,.flags = IMA_FSMAGIC},
+       {.action = DONT_APPRAISE,.fsmagic = SECURITYFS_MAGIC,.flags = IMA_FSMAGIC},
+       {.action = DONT_APPRAISE,.fsmagic = SELINUX_MAGIC,.flags = IMA_FSMAGIC},
+       {.action = DONT_APPRAISE,.fsmagic = CGROUP_SUPER_MAGIC,.flags = IMA_FSMAGIC},
 -      {.action = APPRAISE,.fowner = 0,.flags = IMA_FOWNER},
++      {.action = APPRAISE,.fowner = GLOBAL_ROOT_UID,.flags = IMA_FOWNER},
+ };
+ static LIST_HEAD(ima_default_rules);
+ static LIST_HEAD(ima_policy_rules);
+ static struct list_head *ima_rules;
  
- static DEFINE_MUTEX(ima_measure_mutex);
+ static DEFINE_MUTEX(ima_rules_mutex);
  
  static bool ima_use_tcb __initdata;
- static int __init default_policy_setup(char *str)
+ static int __init default_measure_policy_setup(char *str)
  {
        ima_use_tcb = 1;
        return 1;
@@@ -112,8 -141,10 +141,10 @@@ static bool ima_match_rules(struct ima_
        if ((rule->flags & IMA_FSMAGIC)
            && rule->fsmagic != inode->i_sb->s_magic)
                return false;
 -      if ((rule->flags & IMA_UID) && rule->uid != cred->uid)
 +      if ((rule->flags & IMA_UID) && !uid_eq(rule->uid, cred->uid))
                return false;
 -      if ((rule->flags & IMA_FOWNER) && rule->fowner != inode->i_uid)
++      if ((rule->flags & IMA_FOWNER) && !uid_eq(rule->fowner, inode->i_uid))
+               return false;
        for (i = 0; i < MAX_LSM_RULES; i++) {
                int rc = 0;
                u32 osid, sid;
@@@ -277,7 -336,8 +336,8 @@@ static int ima_parse_rule(char *rule, s
  
        ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_INTEGRITY_RULE);
  
 -      entry->uid = -1;
 -      entry->fowner = -1;
 +      entry->uid = INVALID_UID;
++      entry->fowner = INVALID_UID;
        entry->action = UNKNOWN;
        while ((p = strsep(&rule, " \t")) != NULL) {
                substring_t args[MAX_OPT_ARGS];
                                        entry->flags |= IMA_UID;
                        }
                        break;
+               case Opt_fowner:
+                       ima_log_string(ab, "fowner", args[0].from);
 -                      if (entry->fowner != -1) {
++                      if (uid_valid(entry->fowner)) {
+                               result = -EINVAL;
+                               break;
+                       }
+                       result = strict_strtoul(args[0].from, 10, &lnum);
+                       if (!result) {
 -                              entry->fowner = (uid_t) lnum;
 -                              if (entry->fowner != lnum)
++                              entry->fowner = make_kuid(current_user_ns(), (uid_t)lnum);
++                              if (!uid_valid(entry->fowner) || (((uid_t)lnum) != lnum))
+                                       result = -EINVAL;
+                               else
+                                       entry->flags |= IMA_FOWNER;
+                       }
+                       break;
                case Opt_obj_user:
                        ima_log_string(ab, "obj_user", args[0].from);
                        result = ima_lsm_rule_init(entry, args[0].from,
Simple merge