@@ -100,6 +100,22 @@ static inline bool lsm_export_any(struct lsm_export *l)
((l->flags & LSM_EXPORT_APPARMOR) && l->apparmor));
}
+static inline bool lsm_export_equal(struct lsm_export *l, struct lsm_export *m)
+{
+ if (l->flags != m->flags || l->flags == LSM_EXPORT_NONE)
+ return false;
+ if (l->flags & LSM_EXPORT_SELINUX &&
+ (l->selinux != m->selinux || l->selinux == 0))
+ return false;
+ if (l->flags & LSM_EXPORT_SMACK &&
+ (l->smack != m->smack || l->smack == 0))
+ return false;
+ if (l->flags & LSM_EXPORT_APPARMOR &&
+ (l->apparmor != m->apparmor || l->apparmor == 0))
+ return false;
+ return true;
+}
+
/**
* lsm_export_secid - pull the useful secid out of a lsm_export
* @data: the containing data structure
@@ -36,7 +36,7 @@ struct unix_skb_parms {
kgid_t gid;
struct scm_fp_list *fp; /* Passed files */
#ifdef CONFIG_SECURITY_NETWORK
- u32 secid; /* Security ID */
+ struct lsm_export le; /* LSM data */
#endif
u32 consumed;
} __randomize_layout;
@@ -143,20 +143,17 @@ static struct hlist_head *unix_sockets_unbound(void *addr)
#ifdef CONFIG_SECURITY_NETWORK
static void unix_get_secdata(struct scm_cookie *scm, struct sk_buff *skb)
{
- lsm_export_secid(&scm->le, &(UNIXCB(skb).secid));
+ UNIXCB(skb).le = scm->le;
}
static inline void unix_set_secdata(struct scm_cookie *scm, struct sk_buff *skb)
{
- lsm_export_to_all(&scm->le, UNIXCB(skb).secid);
+ scm->le = UNIXCB(skb).le;
}
static inline bool unix_secdata_eq(struct scm_cookie *scm, struct sk_buff *skb)
{
- u32 best_secid;
-
- lsm_export_secid(&scm->le, &best_secid);
- return (best_secid == UNIXCB(skb).secid);
+ return lsm_export_equal(&scm->le, &(UNIXCB(skb).le));
}
#else
static inline void unix_get_secdata(struct scm_cookie *scm, struct sk_buff *skb)
Store a lsm_export structure in the UDS control information instead of a single secid. Signed-off-by: Casey Schaufler <casey@schaufler-ca.com> --- include/linux/security.h | 16 ++++++++++++++++ include/net/af_unix.h | 2 +- net/unix/af_unix.c | 9 +++------ 3 files changed, 20 insertions(+), 7 deletions(-)