Smack: domain transition protections (v3)
Jarkko Sakkinen [Fri, 7 Oct 2011 06:27:53 +0000 (09:27 +0300)]
Protections for domain transition:

- BPRM unsafe flags
- Secureexec
- Clear unsafe personality bits.
- Clear parent death signal

Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@intel.com>

security/smack/smack_lsm.c

index dab8af1..d55b991 100644 (file)
@@ -5,12 +5,13 @@
  *
  *  Authors:
  *     Casey Schaufler <casey@schaufler-ca.com>
- *     Jarkko Sakkinen <ext-jarkko.2.sakkinen@nokia.com>
+ *     Jarkko Sakkinen <jarkko.sakkinen@intel.com>
  *
  *  Copyright (C) 2007 Casey Schaufler <casey@schaufler-ca.com>
  *  Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
  *                Paul Moore <paul@paul-moore.com>
  *  Copyright (C) 2010 Nokia Corporation
+ *  Copyright (C) 2011 Intel Corporation.
  *
  *     This program is free software; you can redistribute it and/or modify
  *     it under the terms of the GNU General Public License version 2,
@@ -449,9 +450,9 @@ static int smack_sb_umount(struct vfsmount *mnt, int flags)
  */
 static int smack_bprm_set_creds(struct linux_binprm *bprm)
 {
-       struct task_smack *tsp = bprm->cred->security;
+       struct inode *inode = bprm->file->f_path.dentry->d_inode;
+       struct task_smack *bsp = bprm->cred->security;
        struct inode_smack *isp;
-       struct dentry *dp;
        int rc;
 
        rc = cap_bprm_set_creds(bprm);
@@ -461,20 +462,48 @@ static int smack_bprm_set_creds(struct linux_binprm *bprm)
        if (bprm->cred_prepared)
                return 0;
 
-       if (bprm->file == NULL || bprm->file->f_dentry == NULL)
+       isp = inode->i_security;
+       if (isp->smk_task == NULL || isp->smk_task == bsp->smk_task)
                return 0;
 
-       dp = bprm->file->f_dentry;
+       if (bprm->unsafe)
+               return -EPERM;
 
-       if (dp->d_inode == NULL)
-               return 0;
+       bsp->smk_task = isp->smk_task;
+       bprm->per_clear |= PER_CLEAR_ON_SETID;
 
-       isp = dp->d_inode->i_security;
+       return 0;
+}
 
-       if (isp->smk_task != NULL)
-               tsp->smk_task = isp->smk_task;
+/**
+ * smack_bprm_committing_creds - Prepare to install the new credentials
+ * from bprm.
+ *
+ * @bprm: binprm for exec
+ */
+static void smack_bprm_committing_creds(struct linux_binprm *bprm)
+{
+       struct task_smack *bsp = bprm->cred->security;
 
-       return 0;
+       if (bsp->smk_task != bsp->smk_forked)
+               current->pdeath_signal = 0;
+}
+
+/**
+ * smack_bprm_secureexec - Return the decision to use secureexec.
+ * @bprm: binprm for exec
+ *
+ * Returns 0 on success.
+ */
+static int smack_bprm_secureexec(struct linux_binprm *bprm)
+{
+       struct task_smack *tsp = current_security();
+       int ret = cap_bprm_secureexec(bprm);
+
+       if (!ret && (tsp->smk_task != tsp->smk_forked))
+               ret = 1;
+
+       return ret;
 }
 
 /*
@@ -3467,6 +3496,8 @@ struct security_operations smack_ops = {
        .sb_umount =                    smack_sb_umount,
 
        .bprm_set_creds =               smack_bprm_set_creds,
+       .bprm_committing_creds =        smack_bprm_committing_creds,
+       .bprm_secureexec =              smack_bprm_secureexec,
 
        .inode_alloc_security =         smack_inode_alloc_security,
        .inode_free_security =          smack_inode_free_security,