Smack: Improve access check performance

Each Smack label that the kernel has seen is added to a
list of labels. The list of access rules for a given subject
label hangs off of the label list entry for the label.
This patch changes the structures that contain subject
labels to point at the label list entry rather that the
label itself. Doing so removes a label list lookup in
smk_access() that was accounting for the largest single
chunk of Smack overhead.

Targeted for git://git.gitorious.org/smack-next/kernel.git

Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
diff --git a/security/smack/smack.h b/security/smack/smack.h
index bb28e09..159f25b 100644
--- a/security/smack/smack.h
+++ b/security/smack/smack.h
@@ -29,82 +29,6 @@
 #define SMK_LONGLABEL	256
 
 /*
- * Maximum number of bytes for the levels in a CIPSO IP option.
- * Why 23? CIPSO is constrained to 30, so a 32 byte buffer is
- * bigger than can be used, and 24 is the next lower multiple
- * of 8, and there are too many issues if there isn't space set
- * aside for the terminating null byte.
- */
-#define SMK_CIPSOLEN	24
-
-struct superblock_smack {
-	char		*smk_root;
-	char		*smk_floor;
-	char		*smk_hat;
-	char		*smk_default;
-	int		smk_initialized;
-};
-
-struct socket_smack {
-	char		*smk_out;	/* outbound label */
-	char		*smk_in;	/* inbound label */
-	char		*smk_packet;	/* TCP peer label */
-};
-
-/*
- * Inode smack data
- */
-struct inode_smack {
-	char		*smk_inode;	/* label of the fso */
-	char		*smk_task;	/* label of the task */
-	char		*smk_mmap;	/* label of the mmap domain */
-	struct mutex	smk_lock;	/* initialization lock */
-	int		smk_flags;	/* smack inode flags */
-};
-
-struct task_smack {
-	char			*smk_task;	/* label for access control */
-	char			*smk_forked;	/* label when forked */
-	struct list_head	smk_rules;	/* per task access rules */
-	struct mutex		smk_rules_lock;	/* lock for the rules */
-};
-
-#define	SMK_INODE_INSTANT	0x01	/* inode is instantiated */
-#define	SMK_INODE_TRANSMUTE	0x02	/* directory is transmuting */
-#define	SMK_INODE_CHANGED	0x04	/* smack was transmuted */
-
-/*
- * A label access rule.
- */
-struct smack_rule {
-	struct list_head	list;
-	char			*smk_subject;
-	char			*smk_object;
-	int			smk_access;
-};
-
-/*
- * An entry in the table identifying hosts.
- */
-struct smk_netlbladdr {
-	struct list_head	list;
-	struct sockaddr_in	smk_host;	/* network address */
-	struct in_addr		smk_mask;	/* network mask */
-	char			*smk_label;	/* label */
-};
-
-/*
- * An entry in the table identifying ports.
- */
-struct smk_port_label {
-	struct list_head	list;
-	struct sock		*smk_sock;	/* socket initialized on */
-	unsigned short		smk_port;	/* the port number */
-	char			*smk_in;	/* incoming label */
-	char			*smk_out;	/* outgoing label */
-};
-
-/*
  * This is the repository for labels seen so that it is
  * not necessary to keep allocating tiny chuncks of memory
  * and so that they can be shared.
@@ -137,6 +61,82 @@
 };
 
 /*
+ * Maximum number of bytes for the levels in a CIPSO IP option.
+ * Why 23? CIPSO is constrained to 30, so a 32 byte buffer is
+ * bigger than can be used, and 24 is the next lower multiple
+ * of 8, and there are too many issues if there isn't space set
+ * aside for the terminating null byte.
+ */
+#define SMK_CIPSOLEN	24
+
+struct superblock_smack {
+	char		*smk_root;
+	char		*smk_floor;
+	char		*smk_hat;
+	char		*smk_default;
+	int		smk_initialized;
+};
+
+struct socket_smack {
+	struct smack_known	*smk_out;	/* outbound label */
+	char			*smk_in;	/* inbound label */
+	char			*smk_packet;	/* TCP peer label */
+};
+
+/*
+ * Inode smack data
+ */
+struct inode_smack {
+	char			*smk_inode;	/* label of the fso */
+	struct smack_known	*smk_task;	/* label of the task */
+	struct smack_known	*smk_mmap;	/* label of the mmap domain */
+	struct mutex		smk_lock;	/* initialization lock */
+	int			smk_flags;	/* smack inode flags */
+};
+
+struct task_smack {
+	struct smack_known	*smk_task;	/* label for access control */
+	struct smack_known	*smk_forked;	/* label when forked */
+	struct list_head	smk_rules;	/* per task access rules */
+	struct mutex		smk_rules_lock;	/* lock for the rules */
+};
+
+#define	SMK_INODE_INSTANT	0x01	/* inode is instantiated */
+#define	SMK_INODE_TRANSMUTE	0x02	/* directory is transmuting */
+#define	SMK_INODE_CHANGED	0x04	/* smack was transmuted */
+
+/*
+ * A label access rule.
+ */
+struct smack_rule {
+	struct list_head	list;
+	struct smack_known	*smk_subject;
+	char			*smk_object;
+	int			smk_access;
+};
+
+/*
+ * An entry in the table identifying hosts.
+ */
+struct smk_netlbladdr {
+	struct list_head	list;
+	struct sockaddr_in	smk_host;	/* network address */
+	struct in_addr		smk_mask;	/* network mask */
+	char			*smk_label;	/* label */
+};
+
+/*
+ * An entry in the table identifying ports.
+ */
+struct smk_port_label {
+	struct list_head	list;
+	struct sock		*smk_sock;	/* socket initialized on */
+	unsigned short		smk_port;	/* the port number */
+	char			*smk_in;	/* incoming label */
+	struct smack_known	*smk_out;	/* outgoing label */
+};
+
+/*
  * Mount options
  */
 #define SMK_FSDEFAULT	"smackfsdef="
@@ -214,9 +214,9 @@
  * These functions are in smack_access.c
  */
 int smk_access_entry(char *, char *, struct list_head *);
-int smk_access(char *, char *, int, struct smk_audit_info *);
+int smk_access(struct smack_known *, char *, int, struct smk_audit_info *);
 int smk_curacc(char *, u32, struct smk_audit_info *);
-char *smack_from_secid(const u32);
+struct smack_known *smack_from_secid(const u32);
 char *smk_parse_smack(const char *string, int len);
 int smk_netlbl_mls(int, char *, struct netlbl_lsm_secattr *, int);
 char *smk_import(const char *, int);
@@ -229,7 +229,7 @@
  */
 extern int smack_cipso_direct;
 extern int smack_cipso_mapped;
-extern char *smack_net_ambient;
+extern struct smack_known *smack_net_ambient;
 extern char *smack_onlycap;
 extern const char *smack_cipso_option;
 
@@ -265,17 +265,17 @@
 }
 
 /*
- * Present a pointer to the smack label in an task blob.
+ * Present a pointer to the smack label entry in an task blob.
  */
-static inline char *smk_of_task(const struct task_smack *tsp)
+static inline struct smack_known *smk_of_task(const struct task_smack *tsp)
 {
 	return tsp->smk_task;
 }
 
 /*
- * Present a pointer to the forked smack label in an task blob.
+ * Present a pointer to the forked smack label entry in an task blob.
  */
-static inline char *smk_of_forked(const struct task_smack *tsp)
+static inline struct smack_known *smk_of_forked(const struct task_smack *tsp)
 {
 	return tsp->smk_forked;
 }
@@ -283,7 +283,7 @@
 /*
  * Present a pointer to the smack label in the current task blob.
  */
-static inline char *smk_of_current(void)
+static inline struct smack_known *smk_of_current(void)
 {
 	return smk_of_task(current_security());
 }
@@ -294,9 +294,11 @@
  */
 static inline int smack_privileged(int cap)
 {
+	struct smack_known *skp = smk_of_current();
+
 	if (!capable(cap))
 		return 0;
-	if (smack_onlycap == NULL || smack_onlycap == smk_of_current())
+	if (smack_onlycap == NULL || smack_onlycap == skp->smk_known)
 		return 1;
 	return 0;
 }
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c
index 2e397a8..53f2327 100644
--- a/security/smack/smack_access.c
+++ b/security/smack/smack_access.c
@@ -93,7 +93,7 @@
 
 	list_for_each_entry_rcu(srp, rule_list, list) {
 		if (srp->smk_object == object_label &&
-		    srp->smk_subject == subject_label) {
+		    srp->smk_subject->smk_known == subject_label) {
 			may = srp->smk_access;
 			break;
 		}
@@ -104,7 +104,7 @@
 
 /**
  * smk_access - determine if a subject has a specific access to an object
- * @subject_label: a pointer to the subject's Smack label
+ * @subject_known: a pointer to the subject's Smack label entry
  * @object_label: a pointer to the object's Smack label
  * @request: the access requested, in "MAY" format
  * @a : a pointer to the audit data
@@ -115,10 +115,9 @@
  *
  * Smack labels are shared on smack_list
  */
-int smk_access(char *subject_label, char *object_label, int request,
-	       struct smk_audit_info *a)
+int smk_access(struct smack_known *subject_known, char *object_label,
+		int request, struct smk_audit_info *a)
 {
-	struct smack_known *skp;
 	int may = MAY_NOT;
 	int rc = 0;
 
@@ -127,7 +126,7 @@
 	 *
 	 * A star subject can't access any object.
 	 */
-	if (subject_label == smack_known_star.smk_known) {
+	if (subject_known == &smack_known_star) {
 		rc = -EACCES;
 		goto out_audit;
 	}
@@ -137,7 +136,7 @@
 	 * An internet subject can access any object.
 	 */
 	if (object_label == smack_known_web.smk_known ||
-	    subject_label == smack_known_web.smk_known)
+	    subject_known == &smack_known_web)
 		goto out_audit;
 	/*
 	 * A star object can be accessed by any subject.
@@ -148,7 +147,7 @@
 	 * An object can be accessed in any way by a subject
 	 * with the same label.
 	 */
-	if (subject_label == object_label)
+	if (subject_known->smk_known == object_label)
 		goto out_audit;
 	/*
 	 * A hat subject can read any object.
@@ -157,7 +156,7 @@
 	if ((request & MAY_ANYREAD) == request) {
 		if (object_label == smack_known_floor.smk_known)
 			goto out_audit;
-		if (subject_label == smack_known_hat.smk_known)
+		if (subject_known == &smack_known_hat)
 			goto out_audit;
 	}
 	/*
@@ -167,9 +166,9 @@
 	 * good. A negative response from smk_access_entry()
 	 * indicates there is no entry for this pair.
 	 */
-	skp = smk_find_entry(subject_label);
 	rcu_read_lock();
-	may = smk_access_entry(subject_label, object_label, &skp->smk_rules);
+	may = smk_access_entry(subject_known->smk_known, object_label,
+				&subject_known->smk_rules);
 	rcu_read_unlock();
 
 	if (may > 0 && (request & may) == request)
@@ -179,7 +178,8 @@
 out_audit:
 #ifdef CONFIG_AUDIT
 	if (a)
-		smack_log(subject_label, object_label, request, rc, a);
+		smack_log(subject_known->smk_known, object_label, request,
+				rc, a);
 #endif
 	return rc;
 }
@@ -198,20 +198,21 @@
 int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a)
 {
 	struct task_smack *tsp = current_security();
-	char *sp = smk_of_task(tsp);
+	struct smack_known *skp = smk_of_task(tsp);
 	int may;
 	int rc;
 
 	/*
 	 * Check the global rule list
 	 */
-	rc = smk_access(sp, obj_label, mode, NULL);
+	rc = smk_access(skp, obj_label, mode, NULL);
 	if (rc == 0) {
 		/*
 		 * If there is an entry in the task's rule list
 		 * it can further restrict access.
 		 */
-		may = smk_access_entry(sp, obj_label, &tsp->smk_rules);
+		may = smk_access_entry(skp->smk_known, obj_label,
+					&tsp->smk_rules);
 		if (may < 0)
 			goto out_audit;
 		if ((mode & may) == mode)
@@ -228,7 +229,7 @@
 out_audit:
 #ifdef CONFIG_AUDIT
 	if (a)
-		smack_log(sp, obj_label, mode, rc, a);
+		smack_log(skp->smk_known, obj_label, mode, rc, a);
 #endif
 	return rc;
 }
@@ -513,10 +514,10 @@
  * smack_from_secid - find the Smack label associated with a secid
  * @secid: an integer that might be associated with a Smack label
  *
- * Returns a pointer to the appropriate Smack label if there is one,
+ * Returns a pointer to the appropriate Smack label entry if there is one,
  * otherwise a pointer to the invalid Smack label.
  */
-char *smack_from_secid(const u32 secid)
+struct smack_known *smack_from_secid(const u32 secid)
 {
 	struct smack_known *skp;
 
@@ -524,7 +525,7 @@
 	list_for_each_entry_rcu(skp, &smack_known_list, list) {
 		if (skp->smk_secid == secid) {
 			rcu_read_unlock();
-			return skp->smk_known;
+			return skp;
 		}
 	}
 
@@ -533,7 +534,7 @@
 	 * of a secid that is not on the list.
 	 */
 	rcu_read_unlock();
-	return smack_known_invalid.smk_known;
+	return &smack_known_invalid;
 }
 
 /**
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 609e89d..3669d9f 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -62,11 +62,12 @@
  * Returns a pointer to the master list entry for the Smack label
  * or NULL if there was no label to fetch.
  */
-static char *smk_fetch(const char *name, struct inode *ip, struct dentry *dp)
+static struct smack_known *smk_fetch(const char *name, struct inode *ip,
+					struct dentry *dp)
 {
 	int rc;
 	char *buffer;
-	char *result = NULL;
+	struct smack_known *skp = NULL;
 
 	if (ip->i_op->getxattr == NULL)
 		return NULL;
@@ -77,11 +78,11 @@
 
 	rc = ip->i_op->getxattr(dp, name, buffer, SMK_LONGLABEL);
 	if (rc > 0)
-		result = smk_import(buffer, rc);
+		skp = smk_import_entry(buffer, rc);
 
 	kfree(buffer);
 
-	return result;
+	return skp;
 }
 
 /**
@@ -111,7 +112,8 @@
  *
  * Returns the new blob or NULL if there's no memory available
  */
-static struct task_smack *new_task_smack(char *task, char *forked, gfp_t gfp)
+static struct task_smack *new_task_smack(struct smack_known *task,
+					struct smack_known *forked, gfp_t gfp)
 {
 	struct task_smack *tsp;
 
@@ -173,17 +175,17 @@
 {
 	int rc;
 	struct smk_audit_info ad;
-	char *tsp;
+	struct smack_known *skp;
 
 	rc = cap_ptrace_access_check(ctp, mode);
 	if (rc != 0)
 		return rc;
 
-	tsp = smk_of_task(task_security(ctp));
+	skp = smk_of_task(task_security(ctp));
 	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
 	smk_ad_setfield_u_tsk(&ad, ctp);
 
-	rc = smk_curacc(tsp, MAY_READWRITE, &ad);
+	rc = smk_curacc(skp->smk_known, MAY_READWRITE, &ad);
 	return rc;
 }
 
@@ -199,17 +201,17 @@
 {
 	int rc;
 	struct smk_audit_info ad;
-	char *tsp;
+	struct smack_known *skp;
 
 	rc = cap_ptrace_traceme(ptp);
 	if (rc != 0)
 		return rc;
 
-	tsp = smk_of_task(task_security(ptp));
+	skp = smk_of_task(task_security(ptp));
 	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
 	smk_ad_setfield_u_tsk(&ad, ptp);
 
-	rc = smk_curacc(tsp, MAY_READWRITE, &ad);
+	rc = smk_curacc(skp->smk_known, MAY_READWRITE, &ad);
 	return rc;
 }
 
@@ -224,12 +226,12 @@
 static int smack_syslog(int typefrom_file)
 {
 	int rc = 0;
-	char *sp = smk_of_current();
+	struct smack_known *skp = smk_of_current();
 
 	if (smack_privileged(CAP_MAC_OVERRIDE))
 		return 0;
 
-	 if (sp != smack_known_floor.smk_known)
+	 if (skp != &smack_known_floor)
 		rc = -EACCES;
 
 	return rc;
@@ -533,7 +535,9 @@
  */
 static int smack_inode_alloc_security(struct inode *inode)
 {
-	inode->i_security = new_inode_smack(smk_of_current());
+	struct smack_known *skp = smk_of_current();
+
+	inode->i_security = new_inode_smack(skp->smk_known);
 	if (inode->i_security == NULL)
 		return -ENOMEM;
 	return 0;
@@ -566,9 +570,8 @@
 				     const struct qstr *qstr, char **name,
 				     void **value, size_t *len)
 {
-	struct smack_known *skp;
 	struct inode_smack *issp = inode->i_security;
-	char *csp = smk_of_current();
+	struct smack_known *skp = smk_of_current();
 	char *isp = smk_of_inode(inode);
 	char *dsp = smk_of_inode(dir);
 	int may;
@@ -580,9 +583,8 @@
 	}
 
 	if (value) {
-		skp = smk_find_entry(csp);
 		rcu_read_lock();
-		may = smk_access_entry(csp, dsp, &skp->smk_rules);
+		may = smk_access_entry(skp->smk_known, dsp, &skp->smk_rules);
 		rcu_read_unlock();
 
 		/*
@@ -871,29 +873,31 @@
 static void smack_inode_post_setxattr(struct dentry *dentry, const char *name,
 				      const void *value, size_t size, int flags)
 {
-	char *nsp;
+	struct smack_known *skp;
 	struct inode_smack *isp = dentry->d_inode->i_security;
 
+	if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) {
+		isp->smk_flags |= SMK_INODE_TRANSMUTE;
+		return;
+	}
+
+	skp = smk_import_entry(value, size);
 	if (strcmp(name, XATTR_NAME_SMACK) == 0) {
-		nsp = smk_import(value, size);
-		if (nsp != NULL)
-			isp->smk_inode = nsp;
+		if (skp != NULL)
+			isp->smk_inode = skp->smk_known;
 		else
 			isp->smk_inode = smack_known_invalid.smk_known;
 	} else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0) {
-		nsp = smk_import(value, size);
-		if (nsp != NULL)
-			isp->smk_task = nsp;
+		if (skp != NULL)
+			isp->smk_task = skp;
 		else
-			isp->smk_task = smack_known_invalid.smk_known;
+			isp->smk_task = &smack_known_invalid;
 	} else if (strcmp(name, XATTR_NAME_SMACKMMAP) == 0) {
-		nsp = smk_import(value, size);
-		if (nsp != NULL)
-			isp->smk_mmap = nsp;
+		if (skp != NULL)
+			isp->smk_mmap = skp;
 		else
-			isp->smk_mmap = smack_known_invalid.smk_known;
-	} else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0)
-		isp->smk_flags |= SMK_INODE_TRANSMUTE;
+			isp->smk_mmap = &smack_known_invalid;
+	}
 
 	return;
 }
@@ -999,7 +1003,7 @@
 	if (strcmp(name, XATTR_SMACK_IPIN) == 0)
 		isp = ssp->smk_in;
 	else if (strcmp(name, XATTR_SMACK_IPOUT) == 0)
-		isp = ssp->smk_out;
+		isp = ssp->smk_out->smk_known;
 	else
 		return -EOPNOTSUPP;
 
@@ -1079,7 +1083,9 @@
  */
 static int smack_file_alloc_security(struct file *file)
 {
-	file->f_security = smk_of_current();
+	struct smack_known *skp = smk_of_current();
+
+	file->f_security = skp->smk_known;
 	return 0;
 }
 
@@ -1190,10 +1196,9 @@
 			   unsigned long flags)
 {
 	struct smack_known *skp;
+	struct smack_known *mkp;
 	struct smack_rule *srp;
 	struct task_smack *tsp;
-	char *sp;
-	char *msmack;
 	char *osmack;
 	struct inode_smack *isp;
 	int may;
@@ -1207,11 +1212,10 @@
 	isp = file_inode(file)->i_security;
 	if (isp->smk_mmap == NULL)
 		return 0;
-	msmack = isp->smk_mmap;
+	mkp = isp->smk_mmap;
 
 	tsp = current_security();
-	sp = smk_of_current();
-	skp = smk_find_entry(sp);
+	skp = smk_of_current();
 	rc = 0;
 
 	rcu_read_lock();
@@ -1225,13 +1229,13 @@
 		/*
 		 * Matching labels always allows access.
 		 */
-		if (msmack == osmack)
+		if (mkp->smk_known == osmack)
 			continue;
 		/*
 		 * If there is a matching local rule take
 		 * that into account as well.
 		 */
-		may = smk_access_entry(srp->smk_subject, osmack,
+		may = smk_access_entry(srp->smk_subject->smk_known, osmack,
 					&tsp->smk_rules);
 		if (may == -ENOENT)
 			may = srp->smk_access;
@@ -1249,8 +1253,8 @@
 		 * If there isn't one a SMACK64MMAP subject
 		 * can't have as much access as current.
 		 */
-		skp = smk_find_entry(msmack);
-		mmay = smk_access_entry(msmack, osmack, &skp->smk_rules);
+		mmay = smk_access_entry(mkp->smk_known, osmack,
+						&mkp->smk_rules);
 		if (mmay == -ENOENT) {
 			rc = -EACCES;
 			break;
@@ -1259,7 +1263,8 @@
 		 * If there is a local entry it modifies the
 		 * potential access, too.
 		 */
-		tmay = smk_access_entry(msmack, osmack, &tsp->smk_rules);
+		tmay = smk_access_entry(mkp->smk_known, osmack,
+						&tsp->smk_rules);
 		if (tmay != -ENOENT)
 			mmay &= tmay;
 
@@ -1288,7 +1293,9 @@
  */
 static int smack_file_set_fowner(struct file *file)
 {
-	file->f_security = smk_of_current();
+	struct smack_known *skp = smk_of_current();
+
+	file->f_security = skp->smk_known;
 	return 0;
 }
 
@@ -1306,9 +1313,10 @@
 static int smack_file_send_sigiotask(struct task_struct *tsk,
 				     struct fown_struct *fown, int signum)
 {
+	struct smack_known *skp;
+	struct smack_known *tkp = smk_of_task(tsk->cred->security);
 	struct file *file;
 	int rc;
-	char *tsp = smk_of_task(tsk->cred->security);
 	struct smk_audit_info ad;
 
 	/*
@@ -1317,13 +1325,14 @@
 	file = container_of(fown, struct file, f_owner);
 
 	/* we don't log here as rc can be overriden */
-	rc = smk_access(file->f_security, tsp, MAY_WRITE, NULL);
+	skp = smk_find_entry(file->f_security);
+	rc = smk_access(skp, tkp->smk_known, MAY_WRITE, NULL);
 	if (rc != 0 && has_capability(tsk, CAP_MAC_OVERRIDE))
 		rc = 0;
 
 	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
 	smk_ad_setfield_u_tsk(&ad, tsk);
-	smack_log(file->f_security, tsp, MAY_WRITE, rc, &ad);
+	smack_log(file->f_security, tkp->smk_known, MAY_WRITE, rc, &ad);
 	return rc;
 }
 
@@ -1478,12 +1487,12 @@
 static int smack_kernel_act_as(struct cred *new, u32 secid)
 {
 	struct task_smack *new_tsp = new->security;
-	char *smack = smack_from_secid(secid);
+	struct smack_known *skp = smack_from_secid(secid);
 
-	if (smack == NULL)
+	if (skp == NULL)
 		return -EINVAL;
 
-	new_tsp->smk_task = smack;
+	new_tsp->smk_task = skp;
 	return 0;
 }
 
@@ -1501,8 +1510,8 @@
 	struct inode_smack *isp = inode->i_security;
 	struct task_smack *tsp = new->security;
 
-	tsp->smk_forked = isp->smk_inode;
-	tsp->smk_task = isp->smk_inode;
+	tsp->smk_forked = smk_find_entry(isp->smk_inode);
+	tsp->smk_task = tsp->smk_forked;
 	return 0;
 }
 
@@ -1518,10 +1527,11 @@
 				const char *caller)
 {
 	struct smk_audit_info ad;
+	struct smack_known *skp = smk_of_task(task_security(p));
 
 	smk_ad_init(&ad, caller, LSM_AUDIT_DATA_TASK);
 	smk_ad_setfield_u_tsk(&ad, p);
-	return smk_curacc(smk_of_task(task_security(p)), access, &ad);
+	return smk_curacc(skp->smk_known, access, &ad);
 }
 
 /**
@@ -1567,7 +1577,9 @@
  */
 static void smack_task_getsecid(struct task_struct *p, u32 *secid)
 {
-	*secid = smack_to_secid(smk_of_task(task_security(p)));
+	struct smack_known *skp = smk_of_task(task_security(p));
+
+	*secid = skp->smk_secid;
 }
 
 /**
@@ -1671,6 +1683,8 @@
 			   int sig, u32 secid)
 {
 	struct smk_audit_info ad;
+	struct smack_known *skp;
+	struct smack_known *tkp = smk_of_task(task_security(p));
 
 	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
 	smk_ad_setfield_u_tsk(&ad, p);
@@ -1679,15 +1693,14 @@
 	 * can write the receiver.
 	 */
 	if (secid == 0)
-		return smk_curacc(smk_of_task(task_security(p)), MAY_WRITE,
-				  &ad);
+		return smk_curacc(tkp->smk_known, MAY_WRITE, &ad);
 	/*
 	 * 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.
 	 */
-	return smk_access(smack_from_secid(secid),
-			  smk_of_task(task_security(p)), MAY_WRITE, &ad);
+	skp = smack_from_secid(secid);
+	return smk_access(skp, tkp->smk_known, MAY_WRITE, &ad);
 }
 
 /**
@@ -1719,7 +1732,9 @@
 static void smack_task_to_inode(struct task_struct *p, struct inode *inode)
 {
 	struct inode_smack *isp = inode->i_security;
-	isp->smk_inode = smk_of_task(task_security(p));
+	struct smack_known *skp = smk_of_task(task_security(p));
+
+	isp->smk_inode = skp->smk_known;
 }
 
 /*
@@ -1738,15 +1753,15 @@
  */
 static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags)
 {
-	char *csp = smk_of_current();
+	struct smack_known *skp = smk_of_current();
 	struct socket_smack *ssp;
 
 	ssp = kzalloc(sizeof(struct socket_smack), gfp_flags);
 	if (ssp == NULL)
 		return -ENOMEM;
 
-	ssp->smk_in = csp;
-	ssp->smk_out = csp;
+	ssp->smk_in = skp->smk_known;
+	ssp->smk_out = skp;
 	ssp->smk_packet = NULL;
 
 	sk->sk_security = ssp;
@@ -1833,7 +1848,7 @@
 	    labeled == SMACK_UNLABELED_SOCKET)
 		netlbl_sock_delattr(sk);
 	else {
-		skp = smk_find_entry(ssp->smk_out);
+		skp = ssp->smk_out;
 		rc = netlbl_sock_setattr(sk, sk->sk_family, &skp->smk_netlabel);
 	}
 
@@ -1856,6 +1871,7 @@
  */
 static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap)
 {
+	struct smack_known *skp;
 	int rc;
 	int sk_lbl;
 	char *hostsp;
@@ -1874,7 +1890,8 @@
 		ad.a.u.net->v4info.daddr = sap->sin_addr.s_addr;
 #endif
 		sk_lbl = SMACK_UNLABELED_SOCKET;
-		rc = smk_access(ssp->smk_out, hostsp, MAY_WRITE, &ad);
+		skp = ssp->smk_out;
+		rc = smk_access(skp, hostsp, MAY_WRITE, &ad);
 	} else {
 		sk_lbl = SMACK_CIPSO_SOCKET;
 		rc = 0;
@@ -1974,8 +1991,8 @@
 	struct sockaddr_in6 *addr6;
 	struct smk_port_label *spp;
 	struct socket_smack *ssp = sk->sk_security;
+	struct smack_known *skp;
 	unsigned short port = 0;
-	char *subject;
 	char *object;
 	struct smk_audit_info ad;
 #ifdef CONFIG_AUDIT
@@ -1983,11 +2000,11 @@
 #endif
 
 	if (act == SMK_RECEIVING) {
-		subject = smack_net_ambient;
+		skp = smack_net_ambient;
 		object = ssp->smk_in;
 	} else {
-		subject = ssp->smk_out;
-		object = smack_net_ambient;
+		skp = ssp->smk_out;
+		object = smack_net_ambient->smk_known;
 	}
 
 	/*
@@ -2008,7 +2025,7 @@
 	 * It's local so the send check has to have passed.
 	 */
 	if (act == SMK_RECEIVING) {
-		subject = smack_known_web.smk_known;
+		skp = &smack_known_web;
 		goto auditout;
 	}
 
@@ -2017,7 +2034,7 @@
 			continue;
 		object = spp->smk_in;
 		if (act == SMK_CONNECTING)
-			ssp->smk_packet = spp->smk_out;
+			ssp->smk_packet = spp->smk_out->smk_known;
 		break;
 	}
 
@@ -2032,7 +2049,7 @@
 	else
 		ad.a.u.net->v6info.daddr = addr6->sin6_addr;
 #endif
-	return smk_access(subject, object, MAY_WRITE, &ad);
+	return smk_access(skp, object, MAY_WRITE, &ad);
 }
 
 /**
@@ -2050,7 +2067,7 @@
 static int smack_inode_setsecurity(struct inode *inode, const char *name,
 				   const void *value, size_t size, int flags)
 {
-	char *sp;
+	struct smack_known *skp;
 	struct inode_smack *nsp = inode->i_security;
 	struct socket_smack *ssp;
 	struct socket *sock;
@@ -2059,12 +2076,12 @@
 	if (value == NULL || size > SMK_LONGLABEL || size == 0)
 		return -EACCES;
 
-	sp = smk_import(value, size);
-	if (sp == NULL)
+	skp = smk_import_entry(value, size);
+	if (skp == NULL)
 		return -EINVAL;
 
 	if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) {
-		nsp->smk_inode = sp;
+		nsp->smk_inode = skp->smk_known;
 		nsp->smk_flags |= SMK_INODE_INSTANT;
 		return 0;
 	}
@@ -2081,9 +2098,9 @@
 	ssp = sock->sk->sk_security;
 
 	if (strcmp(name, XATTR_SMACK_IPIN) == 0)
-		ssp->smk_in = sp;
+		ssp->smk_in = skp->smk_known;
 	else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) {
-		ssp->smk_out = sp;
+		ssp->smk_out = skp;
 		if (sock->sk->sk_family == PF_INET) {
 			rc = smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET);
 			if (rc != 0)
@@ -2203,7 +2220,9 @@
  */
 static int smack_msg_msg_alloc_security(struct msg_msg *msg)
 {
-	msg->security = smk_of_current();
+	struct smack_known *skp = smk_of_current();
+
+	msg->security = skp->smk_known;
 	return 0;
 }
 
@@ -2238,8 +2257,9 @@
 static int smack_shm_alloc_security(struct shmid_kernel *shp)
 {
 	struct kern_ipc_perm *isp = &shp->shm_perm;
+	struct smack_known *skp = smk_of_current();
 
-	isp->security = smk_of_current();
+	isp->security = skp->smk_known;
 	return 0;
 }
 
@@ -2361,8 +2381,9 @@
 static int smack_sem_alloc_security(struct sem_array *sma)
 {
 	struct kern_ipc_perm *isp = &sma->sem_perm;
+	struct smack_known *skp = smk_of_current();
 
-	isp->security = smk_of_current();
+	isp->security = skp->smk_known;
 	return 0;
 }
 
@@ -2479,8 +2500,9 @@
 static int smack_msg_queue_alloc_security(struct msg_queue *msq)
 {
 	struct kern_ipc_perm *kisp = &msq->q_perm;
+	struct smack_known *skp = smk_of_current();
 
-	kisp->security = smk_of_current();
+	kisp->security = skp->smk_known;
 	return 0;
 }
 
@@ -2652,8 +2674,8 @@
 	struct super_block *sbp;
 	struct superblock_smack *sbsp;
 	struct inode_smack *isp;
-	char *csp = smk_of_current();
-	char *fetched;
+	struct smack_known *skp;
+	struct smack_known *ckp = smk_of_current();
 	char *final;
 	char trattr[TRANS_TRUE_SIZE];
 	int transflag = 0;
@@ -2720,7 +2742,7 @@
 		 * Programs that change smack have to treat the
 		 * pty with respect.
 		 */
-		final = csp;
+		final = ckp->smk_known;
 		break;
 	case SOCKFS_MAGIC:
 		/*
@@ -2775,9 +2797,9 @@
 		 * Get the dentry for xattr.
 		 */
 		dp = dget(opt_dentry);
-		fetched = smk_fetch(XATTR_NAME_SMACK, inode, dp);
-		if (fetched != NULL)
-			final = fetched;
+		skp = smk_fetch(XATTR_NAME_SMACK, inode, dp);
+		if (skp != NULL)
+			final = skp->smk_known;
 
 		/*
 		 * Transmuting directory
@@ -2817,7 +2839,7 @@
 	}
 
 	if (final == NULL)
-		isp->smk_inode = csp;
+		isp->smk_inode = ckp->smk_known;
 	else
 		isp->smk_inode = final;
 
@@ -2840,13 +2862,14 @@
  */
 static int smack_getprocattr(struct task_struct *p, char *name, char **value)
 {
+	struct smack_known *skp = smk_of_task(task_security(p));
 	char *cp;
 	int slen;
 
 	if (strcmp(name, "current") != 0)
 		return -EINVAL;
 
-	cp = kstrdup(smk_of_task(task_security(p)), GFP_KERNEL);
+	cp = kstrdup(skp->smk_known, GFP_KERNEL);
 	if (cp == NULL)
 		return -ENOMEM;
 
@@ -2872,7 +2895,7 @@
 {
 	struct task_smack *tsp;
 	struct cred *new;
-	char *newsmack;
+	struct smack_known *skp;
 
 	/*
 	 * Changing another process' Smack value is too dangerous
@@ -2890,14 +2913,14 @@
 	if (strcmp(name, "current") != 0)
 		return -EINVAL;
 
-	newsmack = smk_import(value, size);
-	if (newsmack == NULL)
+	skp = smk_import_entry(value, size);
+	if (skp == NULL)
 		return -EINVAL;
 
 	/*
 	 * No process is ever allowed the web ("@") label.
 	 */
-	if (newsmack == smack_known_web.smk_known)
+	if (skp == &smack_known_web)
 		return -EPERM;
 
 	new = prepare_creds();
@@ -2905,7 +2928,7 @@
 		return -ENOMEM;
 
 	tsp = new->security;
-	tsp->smk_task = newsmack;
+	tsp->smk_task = skp;
 
 	commit_creds(new);
 	return size;
@@ -2923,6 +2946,7 @@
 static int smack_unix_stream_connect(struct sock *sock,
 				     struct sock *other, struct sock *newsk)
 {
+	struct smack_known *skp;
 	struct socket_smack *ssp = sock->sk_security;
 	struct socket_smack *osp = other->sk_security;
 	struct socket_smack *nsp = newsk->sk_security;
@@ -2936,15 +2960,17 @@
 	smk_ad_setfield_u_net_sk(&ad, other);
 #endif
 
-	if (!smack_privileged(CAP_MAC_OVERRIDE))
-		rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad);
+	if (!smack_privileged(CAP_MAC_OVERRIDE)) {
+		skp = ssp->smk_out;
+		rc = smk_access(skp, osp->smk_in, MAY_WRITE, &ad);
+	}
 
 	/*
 	 * Cross reference the peer labels for SO_PEERSEC.
 	 */
 	if (rc == 0) {
-		nsp->smk_packet = ssp->smk_out;
-		ssp->smk_packet = osp->smk_out;
+		nsp->smk_packet = ssp->smk_out->smk_known;
+		ssp->smk_packet = osp->smk_out->smk_known;
 	}
 
 	return rc;
@@ -2962,8 +2988,8 @@
 {
 	struct socket_smack *ssp = sock->sk->sk_security;
 	struct socket_smack *osp = other->sk->sk_security;
+	struct smack_known *skp;
 	struct smk_audit_info ad;
-	int rc = 0;
 
 #ifdef CONFIG_AUDIT
 	struct lsm_network_audit net;
@@ -2972,10 +2998,11 @@
 	smk_ad_setfield_u_net_sk(&ad, other->sk);
 #endif
 
-	if (!smack_privileged(CAP_MAC_OVERRIDE))
-		rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad);
+	if (smack_privileged(CAP_MAC_OVERRIDE))
+		return 0;
 
-	return rc;
+	skp = ssp->smk_out;
+	return smk_access(skp, osp->smk_in, MAY_WRITE, &ad);
 }
 
 /**
@@ -3017,13 +3044,12 @@
  * @sap: netlabel secattr
  * @ssp: socket security information
  *
- * Returns a pointer to a Smack label found on the label list.
+ * Returns a pointer to a Smack label entry found on the label list.
  */
-static char *smack_from_secattr(struct netlbl_lsm_secattr *sap,
-				struct socket_smack *ssp)
+static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap,
+						struct socket_smack *ssp)
 {
-	struct smack_known *kp;
-	char *sp;
+	struct smack_known *skp;
 	int found = 0;
 
 	if ((sap->flags & NETLBL_SECATTR_MLS_LVL) != 0) {
@@ -3038,11 +3064,11 @@
 		 * ambient value.
 		 */
 		rcu_read_lock();
-		list_for_each_entry(kp, &smack_known_list, list) {
-			if (sap->attr.mls.lvl != kp->smk_netlabel.attr.mls.lvl)
+		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,
-				kp->smk_netlabel.attr.mls.cat,
+				skp->smk_netlabel.attr.mls.cat,
 				SMK_CIPSOLEN) != 0)
 				continue;
 			found = 1;
@@ -3051,17 +3077,17 @@
 		rcu_read_unlock();
 
 		if (found)
-			return kp->smk_known;
+			return skp;
 
 		if (ssp != NULL && ssp->smk_in == smack_known_star.smk_known)
-			return smack_known_web.smk_known;
-		return smack_known_star.smk_known;
+			return &smack_known_web;
+		return &smack_known_star;
 	}
 	if ((sap->flags & NETLBL_SECATTR_SECID) != 0) {
 		/*
 		 * Looks like a fallback, which gives us a secid.
 		 */
-		sp = smack_from_secid(sap->attr.secid);
+		skp = smack_from_secid(sap->attr.secid);
 		/*
 		 * This has got to be a bug because it is
 		 * impossible to specify a fallback without
@@ -3069,8 +3095,8 @@
 		 * it has a secid, and the only way to get a
 		 * secid is from a fallback.
 		 */
-		BUG_ON(sp == NULL);
-		return sp;
+		BUG_ON(skp == NULL);
+		return skp;
 	}
 	/*
 	 * Without guidance regarding the smack value
@@ -3139,8 +3165,8 @@
 {
 	struct netlbl_lsm_secattr secattr;
 	struct socket_smack *ssp = sk->sk_security;
+	struct smack_known *skp;
 	struct sockaddr sadd;
-	char *csp;
 	int rc = 0;
 	struct smk_audit_info ad;
 #ifdef CONFIG_AUDIT
@@ -3155,9 +3181,9 @@
 
 		rc = netlbl_skbuff_getattr(skb, sk->sk_family, &secattr);
 		if (rc == 0)
-			csp = smack_from_secattr(&secattr, ssp);
+			skp = smack_from_secattr(&secattr, ssp);
 		else
-			csp = smack_net_ambient;
+			skp = smack_net_ambient;
 
 		netlbl_secattr_destroy(&secattr);
 
@@ -3173,7 +3199,7 @@
 		 * This is the simplist possible security model
 		 * for networking.
 		 */
-		rc = smk_access(csp, ssp->smk_in, MAY_WRITE, &ad);
+		rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad);
 		if (rc != 0)
 			netlbl_skbuff_err(skb, rc, 0);
 		break;
@@ -3238,7 +3264,7 @@
 {
 	struct netlbl_lsm_secattr secattr;
 	struct socket_smack *ssp = NULL;
-	char *sp;
+	struct smack_known *skp;
 	int family = PF_UNSPEC;
 	u32 s = 0;	/* 0 is the invalid secid */
 	int rc;
@@ -3254,7 +3280,7 @@
 
 	if (family == PF_UNIX) {
 		ssp = sock->sk->sk_security;
-		s = smack_to_secid(ssp->smk_out);
+		s = ssp->smk_out->smk_secid;
 	} else if (family == PF_INET || family == PF_INET6) {
 		/*
 		 * Translate what netlabel gave us.
@@ -3264,8 +3290,8 @@
 		netlbl_secattr_init(&secattr);
 		rc = netlbl_skbuff_getattr(skb, family, &secattr);
 		if (rc == 0) {
-			sp = smack_from_secattr(&secattr, ssp);
-			s = smack_to_secid(sp);
+			skp = smack_from_secattr(&secattr, ssp);
+			s = skp->smk_secid;
 		}
 		netlbl_secattr_destroy(&secattr);
 	}
@@ -3286,13 +3312,15 @@
 static void smack_sock_graft(struct sock *sk, struct socket *parent)
 {
 	struct socket_smack *ssp;
+	struct smack_known *skp = smk_of_current();
 
 	if (sk == NULL ||
 	    (sk->sk_family != PF_INET && sk->sk_family != PF_INET6))
 		return;
 
 	ssp = sk->sk_security;
-	ssp->smk_in = ssp->smk_out = smk_of_current();
+	ssp->smk_in = skp->smk_known;
+	ssp->smk_out = skp;
 	/* cssp->smk_packet is already set in smack_inet_csk_clone() */
 }
 
@@ -3314,7 +3342,6 @@
 	struct netlbl_lsm_secattr secattr;
 	struct sockaddr_in addr;
 	struct iphdr *hdr;
-	char *sp;
 	char *hsp;
 	int rc;
 	struct smk_audit_info ad;
@@ -3337,9 +3364,9 @@
 	netlbl_secattr_init(&secattr);
 	rc = netlbl_skbuff_getattr(skb, family, &secattr);
 	if (rc == 0)
-		sp = smack_from_secattr(&secattr, ssp);
+		skp = smack_from_secattr(&secattr, ssp);
 	else
-		sp = smack_known_huh.smk_known;
+		skp = &smack_known_huh;
 	netlbl_secattr_destroy(&secattr);
 
 #ifdef CONFIG_AUDIT
@@ -3352,7 +3379,7 @@
 	 * Receiving a packet requires that the other end be able to write
 	 * here. Read access is not required.
 	 */
-	rc = smk_access(sp, ssp->smk_in, MAY_WRITE, &ad);
+	rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad);
 	if (rc != 0)
 		return rc;
 
@@ -3360,7 +3387,7 @@
 	 * Save the peer's label in the request_sock so we can later setup
 	 * smk_packet in the child socket so that SO_PEERCRED can report it.
 	 */
-	req->peer_secid = smack_to_secid(sp);
+	req->peer_secid = skp->smk_secid;
 
 	/*
 	 * We need to decide if we want to label the incoming connection here
@@ -3373,10 +3400,9 @@
 	hsp = smack_host_label(&addr);
 	rcu_read_unlock();
 
-	if (hsp == NULL) {
-		skp = smk_find_entry(sp);
+	if (hsp == NULL)
 		rc = netlbl_req_setattr(req, &skp->smk_netlabel);
-	} else
+	else
 		netlbl_req_delattr(req);
 
 	return rc;
@@ -3393,10 +3419,12 @@
 				 const struct request_sock *req)
 {
 	struct socket_smack *ssp = sk->sk_security;
+	struct smack_known *skp;
 
-	if (req->peer_secid != 0)
-		ssp->smk_packet = smack_from_secid(req->peer_secid);
-	else
+	if (req->peer_secid != 0) {
+		skp = smack_from_secid(req->peer_secid);
+		ssp->smk_packet = skp->smk_known;
+	} else
 		ssp->smk_packet = NULL;
 }
 
@@ -3422,7 +3450,9 @@
 static int smack_key_alloc(struct key *key, const struct cred *cred,
 			   unsigned long flags)
 {
-	key->security = smk_of_task(cred->security);
+	struct smack_known *skp = smk_of_task(cred->security);
+
+	key->security = skp->smk_known;
 	return 0;
 }
 
@@ -3451,7 +3481,7 @@
 {
 	struct key *keyp;
 	struct smk_audit_info ad;
-	char *tsp = smk_of_task(cred->security);
+	struct smack_known *tkp = smk_of_task(cred->security);
 
 	keyp = key_ref_to_ptr(key_ref);
 	if (keyp == NULL)
@@ -3465,15 +3495,14 @@
 	/*
 	 * This should not occur
 	 */
-	if (tsp == NULL)
+	if (tkp == NULL)
 		return -EACCES;
 #ifdef CONFIG_AUDIT
 	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_KEY);
 	ad.a.u.key_struct.key = keyp->serial;
 	ad.a.u.key_struct.key_desc = keyp->description;
 #endif
-	return smk_access(tsp, keyp->security,
-				 MAY_READWRITE, &ad);
+	return smk_access(tkp, keyp->security, MAY_READWRITE, &ad);
 }
 #endif /* CONFIG_KEYS */
 
@@ -3555,7 +3584,7 @@
 static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule,
 				  struct audit_context *actx)
 {
-	char *smack;
+	struct smack_known *skp;
 	char *rule = vrule;
 
 	if (!rule) {
@@ -3567,7 +3596,7 @@
 	if (field != AUDIT_SUBJ_USER && field != AUDIT_OBJ_USER)
 		return 0;
 
-	smack = smack_from_secid(secid);
+	skp = smack_from_secid(secid);
 
 	/*
 	 * No need to do string comparisons. If a match occurs,
@@ -3575,9 +3604,9 @@
 	 * label.
 	 */
 	if (op == Audit_equal)
-		return (rule == smack);
+		return (rule == skp->smk_known);
 	if (op == Audit_not_equal)
-		return (rule != smack);
+		return (rule != skp->smk_known);
 
 	return 0;
 }
@@ -3605,11 +3634,11 @@
  */
 static int smack_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
 {
-	char *sp = smack_from_secid(secid);
+	struct smack_known *skp = smack_from_secid(secid);
 
 	if (secdata)
-		*secdata = sp;
-	*seclen = strlen(sp);
+		*secdata = skp->smk_known;
+	*seclen = strlen(skp->smk_known);
 	return 0;
 }
 
@@ -3845,8 +3874,8 @@
 	if (!security_module_enable(&smack_ops))
 		return 0;
 
-	tsp = new_task_smack(smack_known_floor.smk_known,
-				smack_known_floor.smk_known, GFP_KERNEL);
+	tsp = new_task_smack(&smack_known_floor, &smack_known_floor,
+				GFP_KERNEL);
 	if (tsp == NULL)
 		return -ENOMEM;
 
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index 53a08b8..3c79cba 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -66,7 +66,7 @@
  * If it isn't somehow marked, use this.
  * It can be reset via smackfs/ambient
  */
-char *smack_net_ambient;
+struct smack_known *smack_net_ambient;
 
 /*
  * This is the level in a CIPSO header that indicates a
@@ -112,7 +112,7 @@
 LIST_HEAD(smack_rule_list);
 
 struct smack_parsed_rule {
-	char			*smk_subject;
+	struct smack_known	*smk_subject;
 	char			*smk_object;
 	int			smk_access1;
 	int			smk_access2;
@@ -163,9 +163,11 @@
  */
 static void smk_netlabel_audit_set(struct netlbl_audit *nap)
 {
+	struct smack_known *skp = smk_of_current();
+
 	nap->loginuid = audit_get_loginuid(current);
 	nap->sessionid = audit_get_sessionid(current);
-	nap->secid = smack_to_secid(smk_of_current());
+	nap->secid = skp->smk_secid;
 }
 
 /*
@@ -306,7 +308,7 @@
 	struct smack_known *skp;
 
 	if (import) {
-		rule->smk_subject = smk_import(subject, len);
+		rule->smk_subject = smk_import_entry(subject, len);
 		if (rule->smk_subject == NULL)
 			return -1;
 
@@ -321,7 +323,7 @@
 		kfree(cp);
 		if (skp == NULL)
 			return -1;
-		rule->smk_subject = skp->smk_known;
+		rule->smk_subject = skp;
 
 		cp = smk_parse_smack(object, len);
 		if (cp == NULL)
@@ -445,7 +447,6 @@
 					struct list_head *rule_list,
 					struct mutex *rule_lock, int format)
 {
-	struct smack_known *skp;
 	struct smack_parsed_rule *rule;
 	char *data;
 	int datalen;
@@ -505,12 +506,10 @@
 			goto out_free_rule;
 	}
 
-
 	if (rule_list == NULL) {
 		load = 1;
-		skp = smk_find_entry(rule->smk_subject);
-		rule_list = &skp->smk_rules;
-		rule_lock = &skp->smk_rules_lock;
+		rule_list = &rule->smk_subject->smk_rules;
+		rule_lock = &rule->smk_subject->smk_rules_lock;
 	}
 
 	rc = smk_set_access(rule, rule_list, rule_lock, load);
@@ -579,13 +578,14 @@
 	 * because you should expect to be able to write
 	 * anything you read back.
 	 */
-	if (strlen(srp->smk_subject) >= max || strlen(srp->smk_object) >= max)
+	if (strlen(srp->smk_subject->smk_known) >= max ||
+	    strlen(srp->smk_object) >= max)
 		return;
 
 	if (srp->smk_access == 0)
 		return;
 
-	seq_printf(s, "%s %s", srp->smk_subject, srp->smk_object);
+	seq_printf(s, "%s %s", srp->smk_subject->smk_known, srp->smk_object);
 
 	seq_putc(s, ' ');
 
@@ -738,9 +738,9 @@
 			       __func__, __LINE__, rc);
 	}
 	if (smack_net_ambient == NULL)
-		smack_net_ambient = smack_known_floor.smk_known;
+		smack_net_ambient = &smack_known_floor;
 
-	rc = netlbl_cfg_unlbl_map_add(smack_net_ambient, PF_INET,
+	rc = netlbl_cfg_unlbl_map_add(smack_net_ambient->smk_known, PF_INET,
 				      NULL, NULL, &nai);
 	if (rc != 0)
 		printk(KERN_WARNING "%s:%d add rc = %d\n",
@@ -1535,11 +1535,12 @@
 	 */
 	mutex_lock(&smack_ambient_lock);
 
-	asize = strlen(smack_net_ambient) + 1;
+	asize = strlen(smack_net_ambient->smk_known) + 1;
 
 	if (cn >= asize)
 		rc = simple_read_from_buffer(buf, cn, ppos,
-					     smack_net_ambient, asize);
+					     smack_net_ambient->smk_known,
+					     asize);
 	else
 		rc = -EINVAL;
 
@@ -1560,8 +1561,8 @@
 static ssize_t smk_write_ambient(struct file *file, const char __user *buf,
 				 size_t count, loff_t *ppos)
 {
+	struct smack_known *skp;
 	char *oldambient;
-	char *smack = NULL;
 	char *data;
 	int rc = count;
 
@@ -1577,16 +1578,16 @@
 		goto out;
 	}
 
-	smack = smk_import(data, count);
-	if (smack == NULL) {
+	skp = smk_import_entry(data, count);
+	if (skp == NULL) {
 		rc = -EINVAL;
 		goto out;
 	}
 
 	mutex_lock(&smack_ambient_lock);
 
-	oldambient = smack_net_ambient;
-	smack_net_ambient = smack;
+	oldambient = smack_net_ambient->smk_known;
+	smack_net_ambient = skp;
 	smk_unlbl_ambient(oldambient);
 
 	mutex_unlock(&smack_ambient_lock);
@@ -1645,7 +1646,7 @@
 				 size_t count, loff_t *ppos)
 {
 	char *data;
-	char *sp = smk_of_task(current->cred->security);
+	struct smack_known *skp = smk_of_task(current->cred->security);
 	int rc = count;
 
 	if (!smack_privileged(CAP_MAC_ADMIN))
@@ -1656,7 +1657,7 @@
 	 * explicitly for clarity. The smk_access() implementation
 	 * would use smk_access(smack_onlycap, MAY_WRITE)
 	 */
-	if (smack_onlycap != NULL && smack_onlycap != sp)
+	if (smack_onlycap != NULL && smack_onlycap != skp->smk_known)
 		return -EPERM;
 
 	data = kzalloc(count, GFP_KERNEL);
@@ -1866,8 +1867,8 @@
 	if (res)
 		return -EINVAL;
 
-	res = smk_access(rule.smk_subject, rule.smk_object, rule.smk_access1,
-			  NULL);
+	res = smk_access(rule.smk_subject, rule.smk_object,
+				rule.smk_access1, NULL);
 	data[0] = res == 0 ? '1' : '0';
 	data[1] = '\0';