summaryrefslogtreecommitdiffstats
path: root/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0038-Smack-Bring-up-access-mode.patch
diff options
context:
space:
mode:
authorYannick GICQUEL <yannick.gicquel@iot.bzh>2015-10-19 15:57:07 +0200
committerGerrit Code Review <gerrit@172.30.200.200>2015-11-06 15:23:36 +0000
commitede19ea0c47fb23f3fc779833d1e57cf76f3371e (patch)
tree47d6fae2283c54def1871aaf2a73828ac68b1b34 /meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0038-Smack-Bring-up-access-mode.patch
parent1cd8ab18abca96e4ee108f80225058d875b28347 (diff)
kernel: smack security backport from kernel 4
Here is the backport of all patches relating to smack support on kernel side. For more details, see file: meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/README Please note that patches are applied only if "smack" is in the ditro features. Here are the 2 lines to add in the local.conf OVERRIDES .= ":smack" DISTRO_FEATURES_append = " smack" Change-Id: I147a3532aec531f977d6ec34c576261835711f1e Signed-off-by: Yannick GICQUEL <yannick.gicquel@iot.bzh> Signed-off-by: José Bollo <jose.bollo@iot.bzh>
Diffstat (limited to 'meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0038-Smack-Bring-up-access-mode.patch')
-rw-r--r--meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0038-Smack-Bring-up-access-mode.patch805
1 files changed, 805 insertions, 0 deletions
diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0038-Smack-Bring-up-access-mode.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0038-Smack-Bring-up-access-mode.patch
new file mode 100644
index 0000000..a4aaf01
--- /dev/null
+++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0038-Smack-Bring-up-access-mode.patch
@@ -0,0 +1,805 @@
+From bf68e15045643cd5195e8d634712081d0b3b4904 Mon Sep 17 00:00:00 2001
+From: Casey Schaufler <casey@schaufler-ca.com>
+Date: Wed, 27 Aug 2014 14:51:27 -0700
+Subject: [PATCH 38/54] Smack: Bring-up access mode
+
+People keep asking me for permissive mode, and I keep saying "no".
+
+Permissive mode is wrong for more reasons than I can enumerate,
+but the compelling one is that it's once on, never off.
+
+Nonetheless, there is an argument to be made for running a
+process with lots of permissions, logging which are required,
+and then locking the process down. There wasn't a way to do
+that with Smack, but this provides it.
+
+The notion is that you start out by giving the process an
+appropriate Smack label, such as "ATBirds". You create rules
+with a wide range of access and the "b" mode. On Tizen it
+might be:
+
+ ATBirds System rwxalb
+ ATBirds User rwxalb
+ ATBirds _ rwxalb
+ User ATBirds wb
+ System ATBirds wb
+
+Accesses that fail will generate audit records. Accesses
+that succeed because of rules marked with a "b" generate
+log messages identifying the rule, the program and as much
+object information as is convenient.
+
+When the system is properly configured and the programs
+brought in line with the labeling scheme the "b" mode can
+be removed from the rules. When the system is ready for
+production the facility can be configured out.
+
+This provides the developer the convenience of permissive
+mode without creating a system that looks like it is
+enforcing a policy while it is not.
+
+Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
+---
+ security/smack/Kconfig | 16 +++
+ security/smack/smack.h | 5 +-
+ security/smack/smack_access.c | 24 +++-
+ security/smack/smack_lsm.c | 265 ++++++++++++++++++++++++++++++++++++++----
+ security/smack/smackfs.c | 11 +-
+ 5 files changed, 294 insertions(+), 27 deletions(-)
+
+diff --git a/security/smack/Kconfig b/security/smack/Kconfig
+index e69de9c..b065f97 100644
+--- a/security/smack/Kconfig
++++ b/security/smack/Kconfig
+@@ -12,3 +12,19 @@ config SECURITY_SMACK
+ of other mandatory security schemes.
+ If you are unsure how to answer this question, answer N.
+
++config SECURITY_SMACK_BRINGUP
++ bool "Reporting on access granted by Smack rules"
++ depends on SECURITY_SMACK
++ default n
++ help
++ Enable the bring-up ("b") access mode in Smack rules.
++ When access is granted by a rule with the "b" mode a
++ message about the access requested is generated. The
++ intention is that a process can be granted a wide set
++ of access initially with the bringup mode set on the
++ rules. The developer can use the information to
++ identify which rules are necessary and what accesses
++ may be inappropriate. The developer can reduce the
++ access rule set once the behavior is well understood.
++ This is a superior mechanism to the oft abused
++ "permissive" mode of other systems.
+diff --git a/security/smack/smack.h b/security/smack/smack.h
+index 020307e..2d13d5f 100644
+--- a/security/smack/smack.h
++++ b/security/smack/smack.h
+@@ -191,6 +191,7 @@ struct smk_port_label {
+ */
+ #define MAY_TRANSMUTE 0x00001000 /* Controls directory labeling */
+ #define MAY_LOCK 0x00002000 /* Locks should be writes, but ... */
++#define MAY_BRINGUP 0x00004000 /* Report use of this rule */
+
+ /*
+ * Just to make the common cases easier to deal with
+@@ -200,9 +201,9 @@ struct smk_port_label {
+ #define MAY_NOT 0
+
+ /*
+- * Number of access types used by Smack (rwxatl)
++ * Number of access types used by Smack (rwxatlb)
+ */
+-#define SMK_NUM_ACCESS_TYPE 6
++#define SMK_NUM_ACCESS_TYPE 7
+
+ /* SMACK data */
+ struct smack_audit_data {
+diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c
+index c062e94..31dbd048 100644
+--- a/security/smack/smack_access.c
++++ b/security/smack/smack_access.c
+@@ -178,16 +178,27 @@ int smk_access(struct smack_known *subject_known, char *object_label,
+ &subject_known->smk_rules);
+ rcu_read_unlock();
+
+- if (may > 0 && (request & may) == request)
++ if (may <= 0 || (request & may) != request) {
++ rc = -EACCES;
+ goto out_audit;
++ }
++#ifdef CONFIG_SECURITY_SMACK_BRINGUP
++ /*
++ * Return a positive value if using bringup mode.
++ * This allows the hooks to identify checks that
++ * succeed because of "b" rules.
++ */
++ if (may & MAY_BRINGUP)
++ rc = MAY_BRINGUP;
++#endif
+
+- rc = -EACCES;
+ out_audit:
+ #ifdef CONFIG_AUDIT
+ if (a)
+ smack_log(subject_known->smk_known, object_label, request,
+ rc, a);
+ #endif
++
+ return rc;
+ }
+
+@@ -214,7 +225,7 @@ int smk_tskacc(struct task_smack *subject, char *obj_label,
+ * Check the global rule list
+ */
+ rc = smk_access(skp, obj_label, mode, NULL);
+- if (rc == 0) {
++ if (rc >= 0) {
+ /*
+ * If there is an entry in the task's rule list
+ * it can further restrict access.
+@@ -328,6 +339,13 @@ void smack_log(char *subject_label, char *object_label, int request,
+ struct smack_audit_data *sad;
+ struct common_audit_data *a = &ad->a;
+
++#ifdef CONFIG_SECURITY_SMACK_BRINGUP
++ /*
++ * The result may be positive in bringup mode.
++ */
++ if (result > 0)
++ result = 0;
++#endif
+ /* check if we have to log the current event */
+ if (result != 0 && (log_policy & SMACK_AUDIT_DENIED) == 0)
+ return;
+diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
+index 97eab635..6f32c67 100644
+--- a/security/smack/smack_lsm.c
++++ b/security/smack/smack_lsm.c
+@@ -54,6 +54,149 @@
+
+ LIST_HEAD(smk_ipv6_port_list);
+
++#ifdef CONFIG_SECURITY_SMACK_BRINGUP
++static void smk_bu_mode(int mode, char *s)
++{
++ int i = 0;
++
++ if (mode & MAY_READ)
++ s[i++] = 'r';
++ if (mode & MAY_WRITE)
++ s[i++] = 'w';
++ if (mode & MAY_EXEC)
++ s[i++] = 'x';
++ if (mode & MAY_APPEND)
++ s[i++] = 'a';
++ if (mode & MAY_TRANSMUTE)
++ s[i++] = 't';
++ if (mode & MAY_LOCK)
++ s[i++] = 'l';
++ if (i == 0)
++ s[i++] = '-';
++ s[i] = '\0';
++}
++#endif
++
++#ifdef CONFIG_SECURITY_SMACK_BRINGUP
++static int smk_bu_note(char *note, struct smack_known *sskp, char *osp,
++ int mode, int rc)
++{
++ char acc[SMK_NUM_ACCESS_TYPE + 1];
++
++ if (rc <= 0)
++ return rc;
++
++ smk_bu_mode(mode, acc);
++ pr_info("Smack Bringup: (%s %s %s) %s\n",
++ sskp->smk_known, osp, acc, note);
++ return 0;
++}
++#else
++#define smk_bu_note(note, sskp, osp, mode, RC) (RC)
++#endif
++
++#ifdef CONFIG_SECURITY_SMACK_BRINGUP
++static int smk_bu_current(char *note, char *osp, int mode, int rc)
++{
++ struct task_smack *tsp = current_security();
++ char acc[SMK_NUM_ACCESS_TYPE + 1];
++
++ if (rc <= 0)
++ return rc;
++
++ smk_bu_mode(mode, acc);
++ pr_info("Smack Bringup: (%s %s %s) %s %s\n",
++ tsp->smk_task->smk_known, osp, acc, current->comm, note);
++ return 0;
++}
++#else
++#define smk_bu_current(note, osp, mode, RC) (RC)
++#endif
++
++#ifdef CONFIG_SECURITY_SMACK_BRINGUP
++static int smk_bu_task(struct task_struct *otp, int mode, int rc)
++{
++ struct task_smack *tsp = current_security();
++ struct task_smack *otsp = task_security(otp);
++ char acc[SMK_NUM_ACCESS_TYPE + 1];
++
++ if (rc <= 0)
++ return rc;
++
++ smk_bu_mode(mode, acc);
++ pr_info("Smack Bringup: (%s %s %s) %s to %s\n",
++ tsp->smk_task->smk_known, otsp->smk_task->smk_known, acc,
++ current->comm, otp->comm);
++ return 0;
++}
++#else
++#define smk_bu_task(otp, mode, RC) (RC)
++#endif
++
++#ifdef CONFIG_SECURITY_SMACK_BRINGUP
++static int smk_bu_inode(struct inode *inode, int mode, int rc)
++{
++ struct task_smack *tsp = current_security();
++ char acc[SMK_NUM_ACCESS_TYPE + 1];
++
++ if (rc <= 0)
++ return rc;
++
++ smk_bu_mode(mode, acc);
++ pr_info("Smack Bringup: (%s %s %s) inode=(%s %ld) %s\n",
++ tsp->smk_task->smk_known, smk_of_inode(inode), acc,
++ inode->i_sb->s_id, inode->i_ino, current->comm);
++ return 0;
++}
++#else
++#define smk_bu_inode(inode, mode, RC) (RC)
++#endif
++
++#ifdef CONFIG_SECURITY_SMACK_BRINGUP
++static int smk_bu_file(struct file *file, int mode, int rc)
++{
++ struct task_smack *tsp = current_security();
++ struct smack_known *sskp = tsp->smk_task;
++ struct inode *inode = file->f_inode;
++ char acc[SMK_NUM_ACCESS_TYPE + 1];
++
++ if (rc <= 0)
++ return rc;
++
++ smk_bu_mode(mode, acc);
++ pr_info("Smack Bringup: (%s %s %s) file=(%s %ld %s) %s\n",
++ sskp->smk_known, (char *)file->f_security, acc,
++ inode->i_sb->s_id, inode->i_ino, file->f_dentry->d_name.name,
++ current->comm);
++ return 0;
++}
++#else
++#define smk_bu_file(file, mode, RC) (RC)
++#endif
++
++#ifdef CONFIG_SECURITY_SMACK_BRINGUP
++static int smk_bu_credfile(const struct cred *cred, struct file *file,
++ int mode, int rc)
++{
++ struct task_smack *tsp = cred->security;
++ struct smack_known *sskp = tsp->smk_task;
++ struct inode *inode = file->f_inode;
++ char acc[SMK_NUM_ACCESS_TYPE + 1];
++
++ if (rc <= 0)
++ return rc;
++
++ smk_bu_mode(mode, acc);
++ pr_info("Smack Bringup: (%s %s %s) file=(%s %ld %s) %s\n",
++ sskp->smk_known, smk_of_inode(inode), acc,
++ inode->i_sb->s_id, inode->i_ino, file->f_dentry->d_name.name,
++ current->comm);
++ return 0;
++}
++#else
++#define smk_bu_credfile(cred, file, mode, RC) (RC)
++#endif
++
+ /**
+ * smk_fetch - Fetch the smack label from a file.
+ * @ip: a pointer to the inode
+@@ -507,6 +650,7 @@ static int smack_sb_statfs(struct dentry *dentry)
+ smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
+
+ rc = smk_curacc(sbp->smk_floor, MAY_READ, &ad);
++ rc = smk_bu_current("statfs", sbp->smk_floor, MAY_READ, rc);
+ return rc;
+ }
+
+@@ -697,11 +841,13 @@ static int smack_inode_link(struct dentry *old_dentry, struct inode *dir,
+
+ isp = smk_of_inode(old_dentry->d_inode);
+ rc = smk_curacc(isp, MAY_WRITE, &ad);
++ rc = smk_bu_inode(old_dentry->d_inode, MAY_WRITE, rc);
+
+ if (rc == 0 && new_dentry->d_inode != NULL) {
+ isp = smk_of_inode(new_dentry->d_inode);
+ smk_ad_setfield_u_fs_path_dentry(&ad, new_dentry);
+ rc = smk_curacc(isp, MAY_WRITE, &ad);
++ rc = smk_bu_inode(new_dentry->d_inode, MAY_WRITE, rc);
+ }
+
+ return rc;
+@@ -728,6 +874,7 @@ static int smack_inode_unlink(struct inode *dir, struct dentry *dentry)
+ * You need write access to the thing you're unlinking
+ */
+ rc = smk_curacc(smk_of_inode(ip), MAY_WRITE, &ad);
++ rc = smk_bu_inode(ip, MAY_WRITE, rc);
+ if (rc == 0) {
+ /*
+ * You also need write access to the containing directory
+@@ -735,6 +882,7 @@ static int smack_inode_unlink(struct inode *dir, struct dentry *dentry)
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_INODE);
+ smk_ad_setfield_u_fs_inode(&ad, dir);
+ rc = smk_curacc(smk_of_inode(dir), MAY_WRITE, &ad);
++ rc = smk_bu_inode(dir, MAY_WRITE, rc);
+ }
+ return rc;
+ }
+@@ -759,6 +907,7 @@ static int smack_inode_rmdir(struct inode *dir, struct dentry *dentry)
+ * You need write access to the thing you're removing
+ */
+ rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad);
++ rc = smk_bu_inode(dentry->d_inode, MAY_WRITE, rc);
+ if (rc == 0) {
+ /*
+ * You also need write access to the containing directory
+@@ -766,6 +915,7 @@ static int smack_inode_rmdir(struct inode *dir, struct dentry *dentry)
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_INODE);
+ smk_ad_setfield_u_fs_inode(&ad, dir);
+ rc = smk_curacc(smk_of_inode(dir), MAY_WRITE, &ad);
++ rc = smk_bu_inode(dir, MAY_WRITE, rc);
+ }
+
+ return rc;
+@@ -797,11 +947,13 @@ static int smack_inode_rename(struct inode *old_inode,
+
+ isp = smk_of_inode(old_dentry->d_inode);
+ rc = smk_curacc(isp, MAY_READWRITE, &ad);
++ rc = smk_bu_inode(old_dentry->d_inode, MAY_READWRITE, rc);
+
+ if (rc == 0 && new_dentry->d_inode != NULL) {
+ isp = smk_of_inode(new_dentry->d_inode);
+ smk_ad_setfield_u_fs_path_dentry(&ad, new_dentry);
+ rc = smk_curacc(isp, MAY_READWRITE, &ad);
++ rc = smk_bu_inode(new_dentry->d_inode, MAY_READWRITE, rc);
+ }
+ return rc;
+ }
+@@ -819,6 +971,7 @@ static int smack_inode_permission(struct inode *inode, int mask)
+ {
+ struct smk_audit_info ad;
+ int no_block = mask & MAY_NOT_BLOCK;
++ int rc;
+
+ mask &= (MAY_READ|MAY_WRITE|MAY_EXEC|MAY_APPEND);
+ /*
+@@ -832,7 +985,9 @@ static int smack_inode_permission(struct inode *inode, int mask)
+ return -ECHILD;
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_INODE);
+ smk_ad_setfield_u_fs_inode(&ad, inode);
+- return smk_curacc(smk_of_inode(inode), mask, &ad);
++ rc = smk_curacc(smk_of_inode(inode), mask, &ad);
++ rc = smk_bu_inode(inode, mask, rc);
++ return rc;
+ }
+
+ /**
+@@ -845,6 +1000,8 @@ static int smack_inode_permission(struct inode *inode, int mask)
+ static int smack_inode_setattr(struct dentry *dentry, struct iattr *iattr)
+ {
+ struct smk_audit_info ad;
++ int rc;
++
+ /*
+ * Need to allow for clearing the setuid bit.
+ */
+@@ -853,7 +1010,9 @@ static int smack_inode_setattr(struct dentry *dentry, struct iattr *iattr)
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
+ smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
+
+- return smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad);
++ rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad);
++ rc = smk_bu_inode(dentry->d_inode, MAY_WRITE, rc);
++ return rc;
+ }
+
+ /**
+@@ -867,13 +1026,16 @@ static int smack_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
+ {
+ struct smk_audit_info ad;
+ struct path path;
++ int rc;
+
+ path.dentry = dentry;
+ path.mnt = mnt;
+
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
+ smk_ad_setfield_u_fs_path(&ad, path);
+- return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad);
++ rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad);
++ rc = smk_bu_inode(dentry->d_inode, MAY_READ, rc);
++ return rc;
+ }
+
+ /**
+@@ -932,8 +1094,10 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name,
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
+ smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
+
+- if (rc == 0)
++ if (rc == 0) {
+ rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad);
++ rc = smk_bu_inode(dentry->d_inode, MAY_WRITE, rc);
++ }
+
+ return rc;
+ }
+@@ -993,11 +1157,14 @@ static void smack_inode_post_setxattr(struct dentry *dentry, const char *name,
+ static int smack_inode_getxattr(struct dentry *dentry, const char *name)
+ {
+ struct smk_audit_info ad;
++ int rc;
+
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
+ smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
+
+- return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad);
++ rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad);
++ rc = smk_bu_inode(dentry->d_inode, MAY_READ, rc);
++ return rc;
+ }
+
+ /**
+@@ -1033,6 +1200,7 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name)
+ smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
+
+ rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad);
++ rc = smk_bu_inode(dentry->d_inode, MAY_WRITE, rc);
+ if (rc != 0)
+ return rc;
+
+@@ -1213,11 +1381,15 @@ static int smack_file_ioctl(struct file *file, unsigned int cmd,
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
+ smk_ad_setfield_u_fs_path(&ad, file->f_path);
+
+- if (_IOC_DIR(cmd) & _IOC_WRITE)
++ if (_IOC_DIR(cmd) & _IOC_WRITE) {
+ rc = smk_curacc(file->f_security, MAY_WRITE, &ad);
++ rc = smk_bu_file(file, MAY_WRITE, rc);
++ }
+
+- if (rc == 0 && (_IOC_DIR(cmd) & _IOC_READ))
++ if (rc == 0 && (_IOC_DIR(cmd) & _IOC_READ)) {
+ rc = smk_curacc(file->f_security, MAY_READ, &ad);
++ rc = smk_bu_file(file, MAY_READ, rc);
++ }
+
+ return rc;
+ }
+@@ -1232,10 +1404,13 @@ static int smack_file_ioctl(struct file *file, unsigned int cmd,
+ static int smack_file_lock(struct file *file, unsigned int cmd)
+ {
+ struct smk_audit_info ad;
++ int rc;
+
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
+ smk_ad_setfield_u_fs_path(&ad, file->f_path);
+- return smk_curacc(file->f_security, MAY_LOCK, &ad);
++ rc = smk_curacc(file->f_security, MAY_LOCK, &ad);
++ rc = smk_bu_file(file, MAY_LOCK, rc);
++ return rc;
+ }
+
+ /**
+@@ -1265,12 +1440,14 @@ static int smack_file_fcntl(struct file *file, unsigned int cmd,
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
+ smk_ad_setfield_u_fs_path(&ad, file->f_path);
+ rc = smk_curacc(file->f_security, MAY_LOCK, &ad);
++ rc = smk_bu_file(file, MAY_LOCK, rc);
+ break;
+ case F_SETOWN:
+ case F_SETSIG:
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
+ smk_ad_setfield_u_fs_path(&ad, file->f_path);
+ rc = smk_curacc(file->f_security, MAY_WRITE, &ad);
++ rc = smk_bu_file(file, MAY_WRITE, rc);
+ break;
+ default:
+ break;
+@@ -1425,6 +1602,7 @@ static int smack_file_send_sigiotask(struct task_struct *tsk,
+ /* we don't log here as rc can be overriden */
+ skp = smk_find_entry(file->f_security);
+ rc = smk_access(skp, tkp->smk_known, MAY_WRITE, NULL);
++ rc = smk_bu_note("sigiotask", skp, tkp->smk_known, MAY_WRITE, rc);
+ if (rc != 0 && has_capability(tsk, CAP_MAC_OVERRIDE))
+ rc = 0;
+
+@@ -1442,6 +1620,7 @@ static int smack_file_send_sigiotask(struct task_struct *tsk,
+ */
+ static int smack_file_receive(struct file *file)
+ {
++ int rc;
+ int may = 0;
+ struct smk_audit_info ad;
+
+@@ -1455,7 +1634,9 @@ static int smack_file_receive(struct file *file)
+ if (file->f_mode & FMODE_WRITE)
+ may |= MAY_WRITE;
+
+- return smk_curacc(file->f_security, may, &ad);
++ rc = smk_curacc(file->f_security, may, &ad);
++ rc = smk_bu_file(file, may, rc);
++ return rc;
+ }
+
+ /**
+@@ -1485,6 +1666,7 @@ static int smack_file_open(struct file *file, const struct cred *cred)
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
+ smk_ad_setfield_u_fs_path(&ad, file->f_path);
+ rc = smk_access(tsp->smk_task, isp->smk_inode, MAY_READ, &ad);
++ rc = smk_bu_credfile(cred, file, MAY_READ, rc);
+ if (rc == 0)
+ file->f_security = isp->smk_inode;
+
+@@ -1641,10 +1823,13 @@ static int smk_curacc_on_task(struct task_struct *p, int access,
+ {
+ struct smk_audit_info ad;
+ struct smack_known *skp = smk_of_task(task_security(p));
++ int rc;
+
+ smk_ad_init(&ad, caller, LSM_AUDIT_DATA_TASK);
+ smk_ad_setfield_u_tsk(&ad, p);
+- return smk_curacc(skp->smk_known, access, &ad);
++ rc = smk_curacc(skp->smk_known, access, &ad);
++ rc = smk_bu_task(p, access, rc);
++ return rc;
+ }
+
+ /**
+@@ -1798,6 +1983,7 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info,
+ struct smk_audit_info ad;
+ struct smack_known *skp;
+ struct smack_known *tkp = smk_of_task(task_security(p));
++ int rc;
+
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
+ smk_ad_setfield_u_tsk(&ad, p);
+@@ -1805,15 +1991,20 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info,
+ * Sending a signal requires that the sender
+ * can write the receiver.
+ */
+- if (secid == 0)
+- return smk_curacc(tkp->smk_known, MAY_WRITE, &ad);
++ if (secid == 0) {
++ rc = smk_curacc(tkp->smk_known, MAY_WRITE, &ad);
++ rc = smk_bu_task(p, MAY_WRITE, rc);
++ return rc;
++ }
+ /*
+ * If the secid isn't 0 we're dealing with some USB IO
+ * specific behavior. This is not clean. For one thing
+ * we can't take privilege into account.
+ */
+ skp = smack_from_secid(secid);
+- return smk_access(skp, tkp->smk_known, MAY_WRITE, &ad);
++ rc = smk_access(skp, tkp->smk_known, MAY_WRITE, &ad);
++ rc = smk_bu_note("USB signal", skp, tkp->smk_known, MAY_WRITE, rc);
++ return rc;
+ }
+
+ /**
+@@ -2005,6 +2196,7 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap)
+ sk_lbl = SMACK_UNLABELED_SOCKET;
+ skp = ssp->smk_out;
+ rc = smk_access(skp, hostsp, MAY_WRITE, &ad);
++ rc = smk_bu_note("IPv4 host check", skp, hostsp, MAY_WRITE, rc);
+ } else {
+ sk_lbl = SMACK_CIPSO_SOCKET;
+ rc = 0;
+@@ -2107,6 +2299,7 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address,
+ unsigned short port = 0;
+ char *object;
+ struct smk_audit_info ad;
++ int rc;
+ #ifdef CONFIG_AUDIT
+ struct lsm_network_audit net;
+ #endif
+@@ -2160,7 +2353,9 @@ auditout:
+ else
+ ad.a.u.net->v6info.daddr = address->sin6_addr;
+ #endif
+- return smk_access(skp, object, MAY_WRITE, &ad);
++ rc = smk_access(skp, object, MAY_WRITE, &ad);
++ rc = smk_bu_note("IPv6 port check", skp, object, MAY_WRITE, rc);
++ return rc;
+ }
+
+ /**
+@@ -2399,12 +2594,15 @@ static int smk_curacc_shm(struct shmid_kernel *shp, int access)
+ {
+ char *ssp = smack_of_shm(shp);
+ struct smk_audit_info ad;
++ int rc;
+
+ #ifdef CONFIG_AUDIT
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC);
+ ad.a.u.ipc_id = shp->shm_perm.id;
+ #endif
+- return smk_curacc(ssp, access, &ad);
++ rc = smk_curacc(ssp, access, &ad);
++ rc = smk_bu_current("shm", ssp, access, rc);
++ return rc;
+ }
+
+ /**
+@@ -2523,12 +2721,15 @@ static int smk_curacc_sem(struct sem_array *sma, int access)
+ {
+ char *ssp = smack_of_sem(sma);
+ struct smk_audit_info ad;
++ int rc;
+
+ #ifdef CONFIG_AUDIT
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC);
+ ad.a.u.ipc_id = sma->sem_perm.id;
+ #endif
+- return smk_curacc(ssp, access, &ad);
++ rc = smk_curacc(ssp, access, &ad);
++ rc = smk_bu_current("sem", ssp, access, rc);
++ return rc;
+ }
+
+ /**
+@@ -2653,12 +2854,15 @@ static int smk_curacc_msq(struct msg_queue *msq, int access)
+ {
+ char *msp = smack_of_msq(msq);
+ struct smk_audit_info ad;
++ int rc;
+
+ #ifdef CONFIG_AUDIT
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC);
+ ad.a.u.ipc_id = msq->q_perm.id;
+ #endif
+- return smk_curacc(msp, access, &ad);
++ rc = smk_curacc(msp, access, &ad);
++ rc = smk_bu_current("msq", msp, access, rc);
++ return rc;
+ }
+
+ /**
+@@ -2754,12 +2958,15 @@ static int smack_ipc_permission(struct kern_ipc_perm *ipp, short flag)
+ char *isp = ipp->security;
+ int may = smack_flags_to_may(flag);
+ struct smk_audit_info ad;
++ int rc;
+
+ #ifdef CONFIG_AUDIT
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC);
+ ad.a.u.ipc_id = ipp->id;
+ #endif
+- return smk_curacc(isp, may, &ad);
++ rc = smk_curacc(isp, may, &ad);
++ rc = smk_bu_current("svipc", isp, may, rc);
++ return rc;
+ }
+
+ /**
+@@ -3092,8 +3299,13 @@ static int smack_unix_stream_connect(struct sock *sock,
+ smk_ad_setfield_u_net_sk(&ad, other);
+ #endif
+ rc = smk_access(skp, okp->smk_known, MAY_WRITE, &ad);
+- if (rc == 0)
++ rc = smk_bu_note("UDS connect", skp, okp->smk_known,
++ MAY_WRITE, rc);
++ if (rc == 0) {
+ rc = smk_access(okp, okp->smk_known, MAY_WRITE, NULL);
++ rc = smk_bu_note("UDS connect", okp, okp->smk_known,
++ MAY_WRITE, rc);
++ }
+ }
+
+ /*
+@@ -3121,6 +3333,7 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other)
+ struct socket_smack *osp = other->sk->sk_security;
+ struct smack_known *skp;
+ struct smk_audit_info ad;
++ int rc;
+
+ #ifdef CONFIG_AUDIT
+ struct lsm_network_audit net;
+@@ -3133,7 +3346,10 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other)
+ return 0;
+
+ skp = ssp->smk_out;
+- return smk_access(skp, osp->smk_in->smk_known, MAY_WRITE, &ad);
++ rc = smk_access(skp, osp->smk_in->smk_known, MAY_WRITE, &ad);
++ rc = smk_bu_note("UDS send", skp, osp->smk_in->smk_known,
++ MAY_WRITE, rc);
++ return rc;
+ }
+
+ /**
+@@ -3348,6 +3564,8 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
+ * for networking.
+ */
+ rc = smk_access(skp, ssp->smk_in->smk_known, MAY_WRITE, &ad);
++ rc = smk_bu_note("IPv4 delivery", skp, ssp->smk_in->smk_known,
++ MAY_WRITE, rc);
+ if (rc != 0)
+ netlbl_skbuff_err(skb, rc, 0);
+ break;
+@@ -3528,6 +3746,8 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
+ * here. Read access is not required.
+ */
+ rc = smk_access(skp, ssp->smk_in->smk_known, MAY_WRITE, &ad);
++ rc = smk_bu_note("IPv4 connect", skp, ssp->smk_in->smk_known,
++ MAY_WRITE, rc);
+ if (rc != 0)
+ return rc;
+
+@@ -3632,6 +3852,7 @@ static int smack_key_permission(key_ref_t key_ref,
+ struct smk_audit_info ad;
+ struct smack_known *tkp = smk_of_task(cred->security);
+ int request = 0;
++ int rc;
+
+ keyp = key_ref_to_ptr(key_ref);
+ if (keyp == NULL)
+@@ -3656,7 +3877,9 @@ static int smack_key_permission(key_ref_t key_ref,
+ request = MAY_READ;
+ if (perm & (KEY_WRITE | KEY_LINK | KEY_SETATTR))
+ request = MAY_WRITE;
+- return smk_access(tkp, keyp->security, request, &ad);
++ rc = smk_access(tkp, keyp->security, request, &ad);
++ rc = smk_bu_note("key access", tkp, keyp->security, request, rc);
++ return rc;
+ }
+ #endif /* CONFIG_KEYS */
+
+diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
+index 585bea0..cf4e16b 100644
+--- a/security/smack/smackfs.c
++++ b/security/smack/smackfs.c
+@@ -304,6 +304,10 @@ static int smk_perm_from_str(const char *string)
+ case 'L':
+ perm |= MAY_LOCK;
+ break;
++ case 'b':
++ case 'B':
++ perm |= MAY_BRINGUP;
++ break;
+ default:
+ return perm;
+ }
+@@ -616,6 +620,8 @@ static void smk_rule_show(struct seq_file *s, struct smack_rule *srp, int max)
+ seq_putc(s, 't');
+ if (srp->smk_access & MAY_LOCK)
+ seq_putc(s, 'l');
++ if (srp->smk_access & MAY_BRINGUP)
++ seq_putc(s, 'b');
+
+ seq_putc(s, '\n');
+ }
+@@ -1880,7 +1886,10 @@ static ssize_t smk_user_access(struct file *file, const char __user *buf,
+ else if (res != -ENOENT)
+ return -EINVAL;
+
+- data[0] = res == 0 ? '1' : '0';
++ /*
++ * smk_access() can return a value > 0 in the "bringup" case.
++ */
++ data[0] = res >= 0 ? '1' : '0';
+ data[1] = '\0';
+
+ simple_transaction_set(file, 2);
+--
+2.1.4
+