* [PATCH 54/58] LSM: Remove unused macro
From: Casey Schaufler @ 2019-06-02 16:50 UTC (permalink / raw)
To: casey.schaufler, jmorris, linux-security-module, selinux
Cc: casey, keescook, john.johansen, penguin-kernel, paul, sds
In-Reply-To: <20190602165101.25079-1-casey@schaufler-ca.com>
The call_one_void_hook macro is unused since the change
to how releasing a secctx was made. Remove it.
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
---
security/security.c | 10 ----------
1 file changed, 10 deletions(-)
diff --git a/security/security.c b/security/security.c
index 363647cf1ae8..ae43735575d6 100644
--- a/security/security.c
+++ b/security/security.c
@@ -698,16 +698,6 @@ int lsm_superblock_alloc(struct super_block *sb)
P->hook.FUNC(__VA_ARGS__); \
} while (0)
-#define call_one_void_hook(FUNC, ...) \
- do { \
- struct security_hook_list *P; \
- \
- hlist_for_each_entry(P, &security_hook_heads.FUNC, list) { \
- P->hook.FUNC(__VA_ARGS__); \
- break; \
- } \
- } while (0)
-
#define call_int_hook(FUNC, IRC, ...) ({ \
int RC = IRC; \
do { \
--
2.19.1
^ permalink raw reply related
* [PATCH 55/58] LSM: Special handling for secctx lsm hooks
From: Casey Schaufler @ 2019-06-02 16:50 UTC (permalink / raw)
To: casey.schaufler, jmorris, linux-security-module, selinux
Cc: casey, keescook, john.johansen, penguin-kernel, paul, sds
In-Reply-To: <20190602165101.25079-1-casey@schaufler-ca.com>
Create a special set of LSM hooks for the translation
to human readable security data.
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
---
include/linux/lsm_hooks.h | 10 ++++++++++
security/security.c | 32 ++++++++++++++++++++++++--------
2 files changed, 34 insertions(+), 8 deletions(-)
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 088985d10a69..d90d953c8ef4 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -2032,6 +2032,16 @@ struct security_hook_list {
char *lsm;
} __randomize_layout;
+/*
+ * The set of hooks that may be selected for a specific module.
+ */
+struct lsm_one_hooks {
+ char *lsm;
+ union security_list_options secid_to_secctx;
+ union security_list_options secctx_to_secid;
+ union security_list_options socket_getpeersec_stream;
+};
+
/*
* Security blob size or offset data.
*/
diff --git a/security/security.c b/security/security.c
index ae43735575d6..b05265ec24f0 100644
--- a/security/security.c
+++ b/security/security.c
@@ -420,6 +420,9 @@ static int lsm_append(char *new, char **result)
return 0;
}
+/* Base list of once-only hooks */
+struct lsm_one_hooks lsm_base_one;
+
/**
* security_add_hooks - Add a modules hooks to the hook lists.
* @hooks: the hooks to add
@@ -436,6 +439,25 @@ void __init security_add_hooks(struct security_hook_list *hooks, int count,
for (i = 0; i < count; i++) {
hooks[i].lsm = lsm;
hlist_add_tail_rcu(&hooks[i].list, hooks[i].head);
+
+ /*
+ * Check for the special hooks that are restricted to
+ * a single module to create the base set. Use the hooks
+ * from that module for the set, which may not be complete.
+ */
+ if (lsm_base_one.lsm && strcmp(lsm_base_one.lsm, hooks[i].lsm))
+ continue;
+ if (hooks[i].head == &security_hook_heads.secid_to_secctx)
+ lsm_base_one.secid_to_secctx = hooks[i].hook;
+ else if (hooks[i].head == &security_hook_heads.secctx_to_secid)
+ lsm_base_one.secctx_to_secid = hooks[i].hook;
+ else if (hooks[i].head ==
+ &security_hook_heads.socket_getpeersec_stream)
+ lsm_base_one.socket_getpeersec_stream = hooks[i].hook;
+ else
+ continue;
+ if (lsm_base_one.lsm == NULL)
+ lsm_base_one.lsm = kstrdup(hooks[i].lsm, GFP_KERNEL);
}
if (lsm_append(lsm, &lsm_names) < 0)
panic("%s - Cannot get early memory.\n", __func__);
@@ -714,14 +736,8 @@ int lsm_superblock_alloc(struct super_block *sb)
#define call_one_int_hook(FUNC, IRC, ...) ({ \
int RC = IRC; \
- do { \
- struct security_hook_list *P; \
- \
- hlist_for_each_entry(P, &security_hook_heads.FUNC, list) { \
- RC = P->hook.FUNC(__VA_ARGS__); \
- break; \
- } \
- } while (0); \
+ if (lsm_base_one.FUNC.FUNC) \
+ RC = lsm_base_one.FUNC.FUNC(__VA_ARGS__); \
RC; \
})
--
2.19.1
^ permalink raw reply related
* [PATCH 52/58] LSM: Use lsm_context in security_inode_setsecctx
From: Casey Schaufler @ 2019-06-02 16:50 UTC (permalink / raw)
To: casey.schaufler, jmorris, linux-security-module, selinux
Cc: casey, keescook, john.johansen, penguin-kernel, paul, sds
In-Reply-To: <20190602165101.25079-1-casey@schaufler-ca.com>
From: Casey Schaufler <cschaufler@schaufler-ca.com>
Convert security_inode_setsecctx to use the lsm_context structure
instead of a context/secid pair. There is some scaffolding involved
that will be removed when the related data is updated.
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
---
fs/nfsd/nfs4proc.c | 8 ++++++--
fs/nfsd/vfs.c | 7 ++++++-
include/linux/security.h | 5 +++--
security/security.c | 8 ++------
4 files changed, 17 insertions(+), 11 deletions(-)
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 0cfd257ffdaf..5b4ea2a317ed 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -54,12 +54,16 @@
static inline void
nfsd4_security_inode_setsecctx(struct svc_fh *resfh, struct xdr_netobj *label, u32 *bmval)
{
+ struct lsm_context lc;
struct inode *inode = d_inode(resfh->fh_dentry);
int status;
inode_lock(inode);
- status = security_inode_setsecctx(resfh->fh_dentry,
- label->data, label->len);
+
+ lsm_context_init(&lc);
+ lc.context = label->data;
+ lc.len = label->len;
+ status = security_inode_setsecctx(resfh->fh_dentry, &lc);
inode_unlock(inode);
if (status)
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 7dc98e14655d..2d6dd4bb7247 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -531,6 +531,7 @@ __be32 nfsd4_set_nfs4_label(struct svc_rqst *rqstp, struct svc_fh *fhp,
__be32 error;
int host_error;
struct dentry *dentry;
+ struct lsm_context lc;
error = fh_verify(rqstp, fhp, 0 /* S_IFREG */, NFSD_MAY_SATTR);
if (error)
@@ -539,7 +540,11 @@ __be32 nfsd4_set_nfs4_label(struct svc_rqst *rqstp, struct svc_fh *fhp,
dentry = fhp->fh_dentry;
inode_lock(d_inode(dentry));
- host_error = security_inode_setsecctx(dentry, label->data, label->len);
+
+ lsm_context_init(&lc);
+ lc.context = label->data;
+ lc.len = label->len;
+ host_error = security_inode_setsecctx(dentry, &lc);
inode_unlock(d_inode(dentry));
return nfserrno(host_error);
}
diff --git a/include/linux/security.h b/include/linux/security.h
index 94c714310ab7..0be6eadd0110 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -439,7 +439,7 @@ void security_release_secctx(struct lsm_context *cp);
void security_inode_invalidate_secctx(struct inode *inode);
int security_inode_notifysecctx(struct inode *inode, struct lsm_context *cp);
-int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen);
+int security_inode_setsecctx(struct dentry *dentry, struct lsm_context *cp);
int security_inode_getsecctx(struct inode *inode, struct lsm_context *cp);
#else /* CONFIG_SECURITY */
@@ -1237,7 +1237,8 @@ static inline int security_inode_notifysecctx(struct inode *inode,
{
return -EOPNOTSUPP;
}
-static inline int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
+static inline int security_inode_setsecctx(struct dentry *dentry,
+ struct lsm_context *cp)
{
return -EOPNOTSUPP;
}
diff --git a/security/security.c b/security/security.c
index 9d09c774a1e9..363647cf1ae8 100644
--- a/security/security.c
+++ b/security/security.c
@@ -2006,13 +2006,9 @@ int security_inode_notifysecctx(struct inode *inode, struct lsm_context *cp)
}
EXPORT_SYMBOL(security_inode_notifysecctx);
-int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
+int security_inode_setsecctx(struct dentry *dentry, struct lsm_context *cp)
{
- struct lsm_context lc;
-
- lc.context = ctx;
- lc.len = ctxlen;
- return call_int_hook(inode_setsecctx, 0, dentry, &lc);
+ return call_int_hook(inode_setsecctx, 0, dentry, cp);
}
EXPORT_SYMBOL(security_inode_setsecctx);
--
2.19.1
^ permalink raw reply related
* [PATCH 49/58] fs: remove lsm_context scaffolding
From: Casey Schaufler @ 2019-06-02 16:50 UTC (permalink / raw)
To: casey.schaufler, jmorris, linux-security-module, selinux
Cc: casey, keescook, john.johansen, penguin-kernel, paul, sds
In-Reply-To: <20190602165101.25079-1-casey@schaufler-ca.com>
The conversion from secctx/seclen pairs to the lsm_context
structure used scaffolding in kernfs and nfs. Replace the
secctx/seclen pairs in the filesystem local datastructures
with a lsm_context.
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
---
fs/kernfs/dir.c | 9 +++------
fs/kernfs/inode.c | 13 +++++--------
fs/kernfs/kernfs-internal.h | 3 +--
fs/nfs/inode.c | 15 ++++++---------
fs/nfs/internal.h | 8 ++++----
fs/nfs/nfs4proc.c | 27 +++++++++++----------------
fs/nfs/nfs4xdr.c | 16 +++++++++-------
include/linux/nfs4.h | 8 ++++----
8 files changed, 43 insertions(+), 56 deletions(-)
diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c
index 11672c075a8b..48506e856573 100644
--- a/fs/kernfs/dir.c
+++ b/fs/kernfs/dir.c
@@ -532,12 +532,9 @@ void kernfs_put(struct kernfs_node *kn)
kfree_const(kn->name);
if (kn->iattr) {
- if (kn->iattr->ia_secdata) {
- struct lsm_context lc; /* Scaffolding -Casey */
- lc.context = kn->iattr->ia_secdata;
- lc.len = kn->iattr->ia_secdata_len;
- security_release_secctx(&lc);
- }
+ if (kn->iattr->ia_context.context)
+ security_release_secctx(
+ &kn->iattr->ia_context);
simple_xattrs_free(&kn->iattr->xattrs);
kmem_cache_free(kernfs_iattrs_cache, kn->iattr);
}
diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c
index 45781f0da80f..4c7da446d210 100644
--- a/fs/kernfs/inode.c
+++ b/fs/kernfs/inode.c
@@ -141,11 +141,11 @@ static int kernfs_node_setsecdata(struct kernfs_iattrs *attrs, void **secdata,
void *old_secdata;
size_t old_secdata_len;
- old_secdata = attrs->ia_secdata;
- old_secdata_len = attrs->ia_secdata_len;
+ old_secdata = attrs->ia_context.context;
+ old_secdata_len = attrs->ia_context.len;
- attrs->ia_secdata = *secdata;
- attrs->ia_secdata_len = *secdata_len;
+ attrs->ia_context.context = *secdata;
+ attrs->ia_context.len = *secdata_len;
*secdata = old_secdata;
*secdata_len = old_secdata_len;
@@ -184,7 +184,6 @@ static inline void set_inode_attr(struct inode *inode, struct iattr *iattr)
static void kernfs_refresh_inode(struct kernfs_node *kn, struct inode *inode)
{
struct kernfs_iattrs *attrs = kn->iattr;
- struct lsm_context lc; /* Scaffolding -Casey */
inode->i_mode = kn->mode;
if (attrs) {
@@ -193,9 +192,7 @@ static void kernfs_refresh_inode(struct kernfs_node *kn, struct inode *inode)
* persistent copy in kernfs_node.
*/
set_inode_attr(inode, &attrs->ia_iattr);
- lc.context = attrs->ia_secdata;
- lc.len = attrs->ia_secdata_len;
- security_inode_notifysecctx(inode, &lc);
+ security_inode_notifysecctx(inode, &attrs->ia_context);
}
if (kernfs_type(kn) == KERNFS_DIR)
diff --git a/fs/kernfs/kernfs-internal.h b/fs/kernfs/kernfs-internal.h
index 0b7d197a904c..2a870795bb3e 100644
--- a/fs/kernfs/kernfs-internal.h
+++ b/fs/kernfs/kernfs-internal.h
@@ -21,8 +21,7 @@
struct kernfs_iattrs {
struct iattr ia_iattr;
- void *ia_secdata;
- u32 ia_secdata_len;
+ struct lsm_context ia_context;
struct simple_xattrs xattrs;
};
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 8d0be9767b14..a9a3ec40a90c 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -340,22 +340,19 @@ static void nfs_clear_label_invalid(struct inode *inode)
void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr,
struct nfs4_label *label)
{
- struct lsm_context lc; /* Scaffolding -Casey */
int error;
if (label == NULL)
return;
if ((fattr->valid & NFS_ATTR_FATTR_V4_SECURITY_LABEL) && inode->i_security) {
- lc.context = label->label;
- lc.len = label->len;
- error = security_inode_notifysecctx(inode, &lc);
+ error = security_inode_notifysecctx(inode, &label->context);
if (error)
printk(KERN_ERR "%s() %s %d "
"security_inode_notifysecctx() %d\n",
__func__,
- (char *)label->label,
- label->len, error);
+ label->context.context,
+ label->context.len, error);
nfs_clear_label_invalid(inode);
}
}
@@ -375,12 +372,12 @@ struct nfs4_label *nfs4_label_alloc(struct nfs_server *server, gfp_t flags)
if (label == NULL)
return ERR_PTR(-ENOMEM);
- label->label = kzalloc(NFS4_MAXLABELLEN, flags);
- if (label->label == NULL) {
+ label->context.context = kzalloc(NFS4_MAXLABELLEN, flags);
+ if (label->context.context == NULL) {
kfree(label);
return ERR_PTR(-ENOMEM);
}
- label->len = NFS4_MAXLABELLEN;
+ label->context.len = NFS4_MAXLABELLEN;
return label;
}
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index c7cf23ae6597..63de73024b5f 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -307,20 +307,20 @@ nfs4_label_copy(struct nfs4_label *dst, struct nfs4_label *src)
if (!dst || !src)
return NULL;
- if (src->len > NFS4_MAXLABELLEN)
+ if (src->context.len > NFS4_MAXLABELLEN)
return NULL;
dst->lfs = src->lfs;
dst->pi = src->pi;
- dst->len = src->len;
- memcpy(dst->label, src->label, src->len);
+ dst->context.len = src->context.len;
+ memcpy(dst->context.context, src->context.context, src->context.len);
return dst;
}
static inline void nfs4_label_free(struct nfs4_label *label)
{
if (label) {
- kfree(label->label);
+ kfree(label->context.context);
kfree(label);
}
return;
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 8dee01eda643..b2480d0341f1 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -113,7 +113,6 @@ static inline struct nfs4_label *
nfs4_label_init_security(struct inode *dir, struct dentry *dentry,
struct iattr *sattr, struct nfs4_label *label)
{
- struct lsm_context lc; /* Scaffolding -Casey */
int err;
if (label == NULL)
@@ -123,9 +122,7 @@ nfs4_label_init_security(struct inode *dir, struct dentry *dentry,
return NULL;
err = security_dentry_init_security(dentry, sattr->ia_mode,
- &dentry->d_name, &lc);
- label->label = lc.context;
- label->len = lc.len;
+ &dentry->d_name, &label->context);
if (err == 0)
return label;
@@ -134,13 +131,8 @@ nfs4_label_init_security(struct inode *dir, struct dentry *dentry,
static inline void
nfs4_label_release_security(struct nfs4_label *label)
{
- struct lsm_context lc; /* Scaffolding -Casey */
-
- if (label) {
- lc.context = label->label;
- lc.len = label->len;
- security_release_secctx(&lc);
- }
+ if (label)
+ security_release_secctx(&label->context);
}
static inline u32 *nfs4_bitmask(struct nfs_server *server, struct nfs4_label *label)
{
@@ -3556,7 +3548,9 @@ nfs4_atomic_open(struct inode *dir, struct nfs_open_context *ctx,
int open_flags, struct iattr *attr, int *opened)
{
struct nfs4_state *state;
- struct nfs4_label l = {0, 0, 0, NULL}, *label = NULL;
+ struct nfs4_label *label = NULL;
+ struct nfs4_label l = {0, 0,
+ .context = { .context = NULL, .len = 0, }, };
label = nfs4_label_init_security(dir, ctx->dentry, attr, &l);
@@ -5595,7 +5589,8 @@ static int _nfs4_get_security_label(struct inode *inode, void *buf,
{
struct nfs_server *server = NFS_SERVER(inode);
struct nfs_fattr fattr;
- struct nfs4_label label = {0, 0, buflen, buf};
+ struct nfs4_label label = {0, 0,
+ .context = { .context = buf, .len = buflen, }, };
u32 bitmask[3] = { 0, 0, FATTR4_WORD2_SECURITY_LABEL };
struct nfs4_getattr_arg arg = {
@@ -5621,7 +5616,7 @@ static int _nfs4_get_security_label(struct inode *inode, void *buf,
return ret;
if (!(fattr.valid & NFS_ATTR_FATTR_V4_SECURITY_LABEL))
return -ENOENT;
- if (buflen < label.len)
+ if (buflen < label.context.len)
return -ERANGE;
return 0;
}
@@ -5713,8 +5708,8 @@ nfs4_set_security_label(struct inode *inode, const void *buf, size_t buflen)
ilabel.pi = 0;
ilabel.lfs = 0;
- ilabel.label = (char *)buf;
- ilabel.len = buflen;
+ ilabel.context.context = (char *)buf;
+ ilabel.context.len = buflen;
olabel = nfs4_label_alloc(NFS_SERVER(inode), GFP_KERNEL);
if (IS_ERR(olabel)) {
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index cfcabc33e24d..85a527ccd6d7 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -1141,7 +1141,7 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap,
}
if (label && (attrmask[2] & FATTR4_WORD2_SECURITY_LABEL)) {
- len += 4 + 4 + 4 + (XDR_QUADLEN(label->len) << 2);
+ len += 4 + 4 + 4 + (XDR_QUADLEN(label->context.len) << 2);
bmval[2] |= FATTR4_WORD2_SECURITY_LABEL;
}
@@ -1175,8 +1175,9 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap,
if (bmval[2] & FATTR4_WORD2_SECURITY_LABEL) {
*p++ = cpu_to_be32(label->lfs);
*p++ = cpu_to_be32(label->pi);
- *p++ = cpu_to_be32(label->len);
- p = xdr_encode_opaque_fixed(p, label->label, label->len);
+ *p++ = cpu_to_be32(label->context.len);
+ p = xdr_encode_opaque_fixed(p, label->context.context,
+ label->context.len);
}
if (bmval[2] & FATTR4_WORD2_MODE_UMASK) {
*p++ = cpu_to_be32(iap->ia_mode & S_IALLUGO);
@@ -4163,8 +4164,8 @@ static int decode_attr_security_label(struct xdr_stream *xdr, uint32_t *bitmap,
return -EIO;
if (len < NFS4_MAXLABELLEN) {
if (label) {
- memcpy(label->label, p, len);
- label->len = len;
+ memcpy(label->context.context, p, len);
+ label->context.len = len;
label->pi = pi;
label->lfs = lfs;
status = NFS_ATTR_FATTR_V4_SECURITY_LABEL;
@@ -4174,9 +4175,10 @@ static int decode_attr_security_label(struct xdr_stream *xdr, uint32_t *bitmap,
printk(KERN_WARNING "%s: label too long (%u)!\n",
__func__, len);
}
- if (label && label->label)
+ if (label && label->context.context)
dprintk("%s: label=%s, len=%d, PI=%d, LFS=%d\n", __func__,
- (char *)label->label, label->len, label->pi, label->lfs);
+ (char *)label->context.context, label->context.len,
+ label->pi, label->lfs);
return status;
}
diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
index 22494d170619..1189aad71592 100644
--- a/include/linux/nfs4.h
+++ b/include/linux/nfs4.h
@@ -15,6 +15,7 @@
#include <linux/list.h>
#include <linux/uidgid.h>
+#include <linux/security.h>
#include <uapi/linux/nfs4.h>
enum nfs4_acl_whotype {
@@ -43,10 +44,9 @@ struct nfs4_acl {
#define NFS4_MAXLABELLEN 2048
struct nfs4_label {
- uint32_t lfs;
- uint32_t pi;
- u32 len;
- char *label;
+ uint32_t lfs;
+ uint32_t pi;
+ struct lsm_context context;
};
typedef struct { char data[NFS4_VERIFIER_SIZE]; } nfs4_verifier;
--
2.19.1
^ permalink raw reply related
* [PATCH 48/58] LSM: Use lsm_context in security_secid_to_secctx
From: Casey Schaufler @ 2019-06-02 16:50 UTC (permalink / raw)
To: casey.schaufler, jmorris, linux-security-module, selinux
Cc: casey, keescook, john.johansen, penguin-kernel, paul, sds
In-Reply-To: <20190602165101.25079-1-casey@schaufler-ca.com>
Convert security_secid_to_secctx to use the lsm_context structure
instead of a context/secid pair. There is some scaffolding involved
that will be removed when the related data is updated.
Add a flag for lsm_export to indicate that the caller of
security_secid_to_secctx() is only interested in the length
of the context.
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
---
drivers/android/binder.c | 2 +-
include/linux/security.h | 13 +++++++------
include/net/scm.h | 2 +-
kernel/audit.c | 5 ++---
kernel/auditsc.c | 10 +++++-----
net/ipv4/ip_sockglue.c | 2 +-
net/netfilter/nf_conntrack_netlink.c | 11 ++++++-----
net/netfilter/nf_conntrack_standalone.c | 2 +-
net/netfilter/nfnetlink_queue.c | 2 +-
net/netlabel/netlabel_unlabeled.c | 12 ++++--------
net/netlabel/netlabel_user.c | 3 +--
security/apparmor/secid.c | 3 +--
security/security.c | 13 ++-----------
security/selinux/hooks.c | 3 +++
security/smack/smack_lsm.c | 2 +-
15 files changed, 37 insertions(+), 48 deletions(-)
diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index c2cfef13257c..58033c003cc2 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -3121,7 +3121,7 @@ static void binder_transaction(struct binder_proc *proc,
struct lsm_export le;
security_task_getsecid(proc->tsk, &le);
- ret = security_secid_to_secctx(&le, &lc.context, &lc.len);
+ ret = security_secid_to_secctx(&le, &lc);
if (ret) {
return_error = BR_FAILED_REPLY;
return_error_param = ret;
diff --git a/include/linux/security.h b/include/linux/security.h
index 57ce9b824eef..9a9de2bafa55 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -83,10 +83,11 @@ struct lsm_export {
u32 apparmor;
u32 flags;
};
-#define LSM_EXPORT_NONE 0x00
-#define LSM_EXPORT_SELINUX 0x01
-#define LSM_EXPORT_SMACK 0x02
-#define LSM_EXPORT_APPARMOR 0x04
+#define LSM_EXPORT_NONE 0x00000000
+#define LSM_EXPORT_SELINUX 0x00000001
+#define LSM_EXPORT_SMACK 0x00000002
+#define LSM_EXPORT_APPARMOR 0x00000004
+#define LSM_EXPORT_LENGTH 0x80000000 /* Only the length required */
static inline void lsm_export_init(struct lsm_export *l)
{
@@ -431,7 +432,7 @@ int security_setprocattr(const char *lsm, const char *name, void *value,
size_t size);
int security_netlink_send(struct sock *sk, struct sk_buff *skb);
int security_ismaclabel(const char *name);
-int security_secid_to_secctx(struct lsm_export *l, char **secdata, u32 *seclen);
+int security_secid_to_secctx(struct lsm_export *l, struct lsm_context *cp);
int security_secctx_to_secid(struct lsm_context *cp, struct lsm_export *l);
void security_release_secctx(struct lsm_context *cp);
@@ -1211,7 +1212,7 @@ static inline int security_ismaclabel(const char *name)
}
static inline int security_secid_to_secctx(struct lsm_export *l,
- char **secdata, u32 *seclen)
+ struct lsm_seccontext *cp)
{
return -EOPNOTSUPP;
}
diff --git a/include/net/scm.h b/include/net/scm.h
index 7e242ebdd258..b25ca3b6a514 100644
--- a/include/net/scm.h
+++ b/include/net/scm.h
@@ -96,7 +96,7 @@ static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct sc
int err;
if (test_bit(SOCK_PASSSEC, &sock->flags)) {
- err = security_secid_to_secctx(&scm->le, &lc.context, &lc.len);
+ err = security_secid_to_secctx(&scm->le, &lc);
if (!err) {
put_cmsg(msg, SOL_SOCKET, SCM_SECURITY,
diff --git a/kernel/audit.c b/kernel/audit.c
index 269c76fefe40..203e5b14bea4 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -1428,8 +1428,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
}
case AUDIT_SIGNAL_INFO:
if (lsm_export_any(&audit_sig_lsm)) {
- err = security_secid_to_secctx(&audit_sig_lsm,
- &lc.context, &lc.len);
+ err = security_secid_to_secctx(&audit_sig_lsm, &lc);
if (err)
return err;
}
@@ -2076,7 +2075,7 @@ int audit_log_task_context(struct audit_buffer *ab)
if (!lsm_export_any(&le))
return 0;
- error = security_secid_to_secctx(&le, &lc.context, &lc.len);
+ error = security_secid_to_secctx(&le, &lc);
if (error) {
if (error != -EINVAL)
goto error_path;
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 4dab81c7aca0..ceefd17467f9 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -938,7 +938,7 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid,
unsigned int sessionid,
struct lsm_export *l, char *comm)
{
- struct lsm_context lc = { .context = NULL, };
+ struct lsm_context lc;
struct audit_buffer *ab;
int rc = 0;
@@ -950,7 +950,7 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid,
from_kuid(&init_user_ns, auid),
from_kuid(&init_user_ns, uid), sessionid);
if (lsm_export_any(l)) {
- if (security_secid_to_secctx(l, &lc.context, &lc.len)) {
+ if (security_secid_to_secctx(l, &lc)) {
audit_log_format(ab, " obj=(none)");
rc = 1;
} else {
@@ -1190,8 +1190,8 @@ static void show_special(struct audit_context *context, int *call_panic)
from_kgid(&init_user_ns, context->ipc.gid),
context->ipc.mode);
if (lsm_export_any(l)) {
- struct lsm_context lc = { .context = NULL, };
- if (security_secid_to_secctx(l, &lc.context, &lc.len)) {
+ struct lsm_context lc;
+ if (security_secid_to_secctx(l, &lc)) {
audit_log_format(ab, " osid=(unknown)");
*call_panic = 1;
} else {
@@ -1342,7 +1342,7 @@ static void audit_log_name(struct audit_context *context, struct audit_names *n,
if (lsm_export_any(&n->olsm)) {
struct lsm_context lc;
- if (security_secid_to_secctx(&n->olsm, &lc.context, &lc.len)) {
+ if (security_secid_to_secctx(&n->olsm, &lc)) {
audit_log_format(ab, " osid=(unknown)");
if (call_panic)
*call_panic = 2;
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 18a7fab8b2d3..56035b53952d 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -138,7 +138,7 @@ static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb)
if (err)
return;
- err = security_secid_to_secctx(&le, &lc.context, &lc.len);
+ err = security_secid_to_secctx(&le, &lc);
if (err)
return;
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 49bce1b085ce..ea83909af6db 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -337,7 +337,7 @@ static int ctnetlink_dump_secctx(struct sk_buff *skb, const struct nf_conn *ct)
le.selinux = ct->secmark;
le.smack = ct->secmark;
- ret = security_secid_to_secctx(&le, &lc.context, &lc.len);
+ ret = security_secid_to_secctx(&le, &lc);
if (ret)
return 0;
@@ -620,20 +620,21 @@ static inline size_t ctnetlink_acct_size(const struct nf_conn *ct)
static inline int ctnetlink_secctx_size(const struct nf_conn *ct)
{
#ifdef CONFIG_NF_CONNTRACK_SECMARK
- int len, ret;
+ int ret;
struct lsm_export le;
+ struct lsm_context lc;
lsm_export_init(&le);
- le.flags = LSM_EXPORT_SELINUX | LSM_EXPORT_SMACK;
+ le.flags = LSM_EXPORT_SELINUX | LSM_EXPORT_SMACK | LSM_EXPORT_LENGTH;
le.selinux = ct->secmark;
le.smack = ct->secmark;
- ret = security_secid_to_secctx(&le, NULL, &len);
+ ret = security_secid_to_secctx(&le, &lc);
if (ret)
return 0;
return nla_total_size(0) /* CTA_SECCTX */
- + nla_total_size(sizeof(char) * len); /* CTA_SECCTX_NAME */
+ + nla_total_size(sizeof(char) * lc.len); /* CTA_SECCTX_NAME */
#else
return 0;
#endif
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
index 97d16a51504b..797abf443a34 100644
--- a/net/netfilter/nf_conntrack_standalone.c
+++ b/net/netfilter/nf_conntrack_standalone.c
@@ -182,7 +182,7 @@ static void ct_show_secctx(struct seq_file *s, const struct nf_conn *ct)
le.selinux = ct->secmark;
le.smack = ct->secmark;
- ret = security_secid_to_secctx(&le, &lc.context, &lc.len);
+ ret = security_secid_to_secctx(&le, &lc);
if (ret)
return;
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index b70871693368..4a3d4b52caef 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -322,7 +322,7 @@ static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, char **secdata)
le.flags = LSM_EXPORT_SELINUX | LSM_EXPORT_SMACK;
le.selinux = skb->secmark;
le.smack = skb->secmark;
- security_secid_to_secctx(&le, &lc.context, &lc.len);
+ security_secid_to_secctx(&le, &lc);
*secdata = lc.context;
}
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c
index 4c4a8f6df261..336d315ee8eb 100644
--- a/net/netlabel/netlabel_unlabeled.c
+++ b/net/netlabel/netlabel_unlabeled.c
@@ -450,7 +450,7 @@ int netlbl_unlhsh_add(struct net *net,
rcu_read_unlock();
if (audit_buf != NULL) {
struct lsm_context lc;
- if (security_secid_to_secctx(l, &lc.context, &lc.len) == 0) {
+ if (security_secid_to_secctx(l, &lc) == 0) {
audit_log_format(audit_buf, " sec_obj=%s", lc.context);
security_release_secctx(&lc);
}
@@ -504,8 +504,7 @@ static int netlbl_unlhsh_remove_addr4(struct net *net,
if (dev != NULL)
dev_put(dev);
if (entry != NULL &&
- security_secid_to_secctx(&entry->le,
- &lc.context, &lc.len) == 0) {
+ security_secid_to_secctx(&entry->le, &lc) == 0) {
audit_log_format(audit_buf, " sec_obj=%s", lc.context);
security_release_secctx(&lc);
}
@@ -544,8 +543,6 @@ static int netlbl_unlhsh_remove_addr6(struct net *net,
struct netlbl_unlhsh_addr6 *entry;
struct audit_buffer *audit_buf;
struct net_device *dev;
- char *secctx;
- u32 secctx_len;
spin_lock(&netlbl_unlhsh_lock);
list_entry = netlbl_af6list_remove(addr, mask, &iface->addr6_list);
@@ -566,8 +563,7 @@ static int netlbl_unlhsh_remove_addr6(struct net *net,
if (dev != NULL)
dev_put(dev);
if (entry != NULL &&
- security_secid_to_secctx(&entry->le,
- &lc.context, &lc.len) == 0) {
+ security_secid_to_secctx(&entry->le, &lc) == 0) {
audit_log_format(audit_buf, " sec_obj=%s", lc.context);
security_release_secctx(&lc);
}
@@ -1137,7 +1133,7 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd,
lep = (struct lsm_export *)&addr6->le;
}
- ret_val = security_secid_to_secctx(lep, &lc.context, &lc.len);
+ ret_val = security_secid_to_secctx(lep, &lc);
if (ret_val != 0)
goto list_cb_failure;
ret_val = nla_put(cb_arg->skb,
diff --git a/net/netlabel/netlabel_user.c b/net/netlabel/netlabel_user.c
index 0418f0935199..11ea98525c4e 100644
--- a/net/netlabel/netlabel_user.c
+++ b/net/netlabel/netlabel_user.c
@@ -112,8 +112,7 @@ struct audit_buffer *netlbl_audit_start_common(int type,
audit_info->sessionid);
if (lsm_export_any(&audit_info->le) &&
- security_secid_to_secctx(&audit_info->le, &lc.context,
- &lc.len) == 0) {
+ security_secid_to_secctx(&audit_info->le, &lc) == 0) {
audit_log_format(audit_buf, " subj=%s", lc.context);
security_release_secctx(&lc);
}
diff --git a/security/apparmor/secid.c b/security/apparmor/secid.c
index 46c8b9a67ac7..9dc17903a936 100644
--- a/security/apparmor/secid.c
+++ b/security/apparmor/secid.c
@@ -92,8 +92,7 @@ int apparmor_secid_to_secctx(struct lsm_export *l, struct lsm_context *cp)
if (!label)
return -EINVAL;
- /* scaffolding check - Casey */
- if (cp)
+ if (!(l->flags & LSM_EXPORT_LENGTH))
len = aa_label_asxprint(&cp->context, root_ns, label,
FLAG_SHOW_MODE | FLAG_VIEW_SUBNS |
FLAG_HIDDEN_UNCONFINED | FLAG_ABS_ROOT,
diff --git a/security/security.c b/security/security.c
index 3da7302d20ec..6588172b3ec8 100644
--- a/security/security.c
+++ b/security/security.c
@@ -1972,18 +1972,9 @@ int security_ismaclabel(const char *name)
}
EXPORT_SYMBOL(security_ismaclabel);
-int security_secid_to_secctx(struct lsm_export *l, char **secdata, u32 *seclen)
+int security_secid_to_secctx(struct lsm_export *l, struct lsm_context *cp)
{
- struct lsm_context lc = { .context = NULL, .len = 0, };
- int rc;
-
- rc = call_one_int_hook(secid_to_secctx, -EOPNOTSUPP, l, &lc);
- if (secdata)
- *secdata = lc.context;
- else
- security_release_secctx(&lc);
- *seclen = lc.len;
- return rc;
+ return call_one_int_hook(secid_to_secctx, -EOPNOTSUPP, l, cp);
}
EXPORT_SYMBOL(security_secid_to_secctx);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 332296f69f76..7bf73493d10d 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -6306,6 +6306,9 @@ static int selinux_secid_to_secctx(struct lsm_export *l, struct lsm_context *cp)
u32 secid;
selinux_import_secid(l, &secid);
+ if (l->flags & LSM_EXPORT_LENGTH)
+ return security_sid_to_context(&selinux_state, secid,
+ NULL, &cp->len);
return security_sid_to_context(&selinux_state, secid,
&cp->context, &cp->len);
}
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index cf27905ccaa5..1b5b3e421bff 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -4442,7 +4442,7 @@ static int smack_secid_to_secctx(struct lsm_export *l, struct lsm_context *cp)
smack_import_secid(l, &secid);
skp = smack_from_secid(secid);
- cp->context = skp->smk_known;
+ cp->context = (l->flags & LSM_EXPORT_LENGTH) ? NULL : skp->smk_known;
cp->len = strlen(skp->smk_known);
return 0;
}
--
2.19.1
^ permalink raw reply related
* [PATCH 50/58] LSM: Add the release function to the lsm_context
From: Casey Schaufler @ 2019-06-02 16:50 UTC (permalink / raw)
To: casey.schaufler, jmorris, linux-security-module, selinux
Cc: casey, keescook, john.johansen, penguin-kernel, paul, sds
In-Reply-To: <20190602165101.25079-1-casey@schaufler-ca.com>
In order to ensure that the release function for a
lsm_context matches the LSM that allocated it an element
is added to the lsm_context structure to contain a
pointer to it. This function is called in security_release_secctx
instead of relying on a value in a hook list.
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
---
include/linux/lsm_hooks.h | 6 ------
include/linux/security.h | 1 +
security/apparmor/lsm.c | 1 -
security/apparmor/secid.c | 11 ++++++-----
security/security.c | 5 ++++-
security/selinux/hooks.c | 14 ++++++++------
security/smack/smack_lsm.c | 16 ++++++++--------
7 files changed, 27 insertions(+), 27 deletions(-)
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 3a779a0f9e15..d1235a3cd8e9 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -1326,10 +1326,6 @@
* @cp contains the security context.
* @l contains the pointer to the generated security data.
*
- * @release_secctx:
- * Release the security context.
- * @secdata contains the security context.
- *
* Security hooks for Audit
*
* @audit_rule_init:
@@ -1662,7 +1658,6 @@ union security_list_options {
int (*secid_to_secctx)(struct lsm_export *l, struct lsm_context *cp);
int (*secctx_to_secid)(const struct lsm_context *cp,
struct lsm_export *l);
- void (*release_secctx)(struct lsm_context *cp);
void (*inode_invalidate_secctx)(struct inode *inode);
int (*inode_notifysecctx)(struct inode *inode, struct lsm_context *cp);
@@ -1939,7 +1934,6 @@ struct security_hook_heads {
struct hlist_head ismaclabel;
struct hlist_head secid_to_secctx;
struct hlist_head secctx_to_secid;
- struct hlist_head release_secctx;
struct hlist_head inode_invalidate_secctx;
struct hlist_head inode_notifysecctx;
struct hlist_head inode_setsecctx;
diff --git a/include/linux/security.h b/include/linux/security.h
index 9a9de2bafa55..94c714310ab7 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -121,6 +121,7 @@ static inline bool lsm_export_equal(struct lsm_export *l, struct lsm_export *m)
struct lsm_context {
char *context;
u32 len;
+ void (*release)(struct lsm_context *cp); /* frees .context */
};
static inline void lsm_context_init(struct lsm_context *cp)
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index 76c409737370..771b0ae24a5f 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -1225,7 +1225,6 @@ static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = {
LSM_HOOK_INIT(secid_to_secctx, apparmor_secid_to_secctx),
LSM_HOOK_INIT(secctx_to_secid, apparmor_secctx_to_secid),
- LSM_HOOK_INIT(release_secctx, apparmor_release_secctx),
};
/*
diff --git a/security/apparmor/secid.c b/security/apparmor/secid.c
index 9dc17903a936..30fd4ad80948 100644
--- a/security/apparmor/secid.c
+++ b/security/apparmor/secid.c
@@ -81,6 +81,11 @@ static inline void aa_export_secid(struct lsm_export *l, u32 secid)
l->apparmor = secid;
}
+void apparmor_release_secctx(struct lsm_context *cp)
+{
+ kfree(cp->context);
+}
+
int apparmor_secid_to_secctx(struct lsm_export *l, struct lsm_context *cp)
{
/* TODO: cache secctx and ref count so we don't have to recreate */
@@ -105,6 +110,7 @@ int apparmor_secid_to_secctx(struct lsm_export *l, struct lsm_context *cp)
return -ENOMEM;
cp->len = len;
+ cp->release = apparmor_release_secctx;
return 0;
}
@@ -122,11 +128,6 @@ int apparmor_secctx_to_secid(const struct lsm_context *cp, struct lsm_export *l)
return 0;
}
-void apparmor_release_secctx(struct lsm_context *cp)
-{
- kfree(cp->context);
-}
-
/**
* aa_alloc_secid - allocate a new secid for a profile
* @label: the label to allocate a secid for
diff --git a/security/security.c b/security/security.c
index 6588172b3ec8..c8ce190dcdda 100644
--- a/security/security.c
+++ b/security/security.c
@@ -1987,7 +1987,10 @@ EXPORT_SYMBOL(security_secctx_to_secid);
void security_release_secctx(struct lsm_context *cp)
{
- call_one_void_hook(release_secctx, cp);
+ if (WARN_ON(cp->release == NULL))
+ return;
+ cp->release(cp);
+ lsm_context_init(cp);
}
EXPORT_SYMBOL(security_release_secctx);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 7bf73493d10d..0e347a26c3d8 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2812,6 +2812,11 @@ static void selinux_inode_free_security(struct inode *inode)
inode_free_security(inode);
}
+static void selinux_release_secctx(struct lsm_context *cp)
+{
+ kfree(cp->context);
+}
+
static int selinux_dentry_init_security(struct dentry *dentry, int mode,
const struct qstr *name,
struct lsm_context *cp)
@@ -2826,6 +2831,7 @@ static int selinux_dentry_init_security(struct dentry *dentry, int mode,
if (rc)
return rc;
+ cp->release = selinux_release_secctx;
return security_sid_to_context(&selinux_state, newsid, &cp->context,
&cp->len);
}
@@ -6306,6 +6312,7 @@ static int selinux_secid_to_secctx(struct lsm_export *l, struct lsm_context *cp)
u32 secid;
selinux_import_secid(l, &secid);
+ cp->release = selinux_release_secctx;
if (l->flags & LSM_EXPORT_LENGTH)
return security_sid_to_context(&selinux_state, secid,
NULL, &cp->len);
@@ -6325,11 +6332,6 @@ static int selinux_secctx_to_secid(const struct lsm_context *cp,
return rc;
}
-static void selinux_release_secctx(struct lsm_context *cp)
-{
- kfree(cp->context);
-}
-
static void selinux_inode_invalidate_secctx(struct inode *inode)
{
struct inode_security_struct *isec = selinux_inode(inode);
@@ -6367,6 +6369,7 @@ static int selinux_inode_getsecctx(struct inode *inode, struct lsm_context *cp)
if (len < 0)
return len;
cp->len = len;
+ cp->release = selinux_release_secctx;
return 0;
}
#ifdef CONFIG_KEYS
@@ -6781,7 +6784,6 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = {
LSM_HOOK_INIT(ismaclabel, selinux_ismaclabel),
LSM_HOOK_INIT(secid_to_secctx, selinux_secid_to_secctx),
LSM_HOOK_INIT(secctx_to_secid, selinux_secctx_to_secid),
- LSM_HOOK_INIT(release_secctx, selinux_release_secctx),
LSM_HOOK_INIT(inode_invalidate_secctx, selinux_inode_invalidate_secctx),
LSM_HOOK_INIT(inode_notifysecctx, selinux_inode_notifysecctx),
LSM_HOOK_INIT(inode_setsecctx, selinux_inode_setsecctx),
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 1b5b3e421bff..e00346799cdf 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -4425,6 +4425,12 @@ static int smack_ismaclabel(const char *name)
return (strcmp(name, XATTR_SMACK_SUFFIX) == 0);
}
+/*
+ * The smack_release_secctx hook does nothing
+ */
+static void smack_release_secctx(struct lsm_context *cp)
+{
+}
/**
* smack_secid_to_secctx - return the smack label for a secid
@@ -4444,6 +4450,7 @@ static int smack_secid_to_secctx(struct lsm_export *l, struct lsm_context *cp)
cp->context = (l->flags & LSM_EXPORT_LENGTH) ? NULL : skp->smk_known;
cp->len = strlen(skp->smk_known);
+ cp->release = smack_release_secctx;
return 0;
}
@@ -4467,13 +4474,6 @@ static int smack_secctx_to_secid(const struct lsm_context *cp,
return 0;
}
-/*
- * The smack_release_secctx hook does nothing
- */
-static void smack_release_secctx(struct lsm_context *cp)
-{
-}
-
static int smack_inode_notifysecctx(struct inode *inode, struct lsm_context *cp)
{
return smack_inode_setsecurity(inode, XATTR_SMACK_SUFFIX, cp->context,
@@ -4491,6 +4491,7 @@ static int smack_inode_getsecctx(struct inode *inode, struct lsm_context *cp)
cp->context = skp->smk_known;
cp->len = strlen(skp->smk_known);
+ cp->release = smack_release_secctx;
return 0;
}
@@ -4713,7 +4714,6 @@ static struct security_hook_list smack_hooks[] __lsm_ro_after_init = {
LSM_HOOK_INIT(ismaclabel, smack_ismaclabel),
LSM_HOOK_INIT(secid_to_secctx, smack_secid_to_secctx),
LSM_HOOK_INIT(secctx_to_secid, smack_secctx_to_secid),
- LSM_HOOK_INIT(release_secctx, smack_release_secctx),
LSM_HOOK_INIT(inode_notifysecctx, smack_inode_notifysecctx),
LSM_HOOK_INIT(inode_setsecctx, smack_inode_setsecctx),
LSM_HOOK_INIT(inode_getsecctx, smack_inode_getsecctx),
--
2.19.1
^ permalink raw reply related
* [PATCH 51/58] LSM: Use lsm_context in inode_setsecctx hooks
From: Casey Schaufler @ 2019-06-02 16:50 UTC (permalink / raw)
To: casey.schaufler, jmorris, linux-security-module, selinux
Cc: casey, keescook, john.johansen, penguin-kernel, paul, sds
In-Reply-To: <20190602165101.25079-1-casey@schaufler-ca.com>
Convert SELinux and Smack to use the lsm_context structure
instead of a context/secid pair. There is some scaffolding involved
that will be removed when the related data is updated.
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
---
include/linux/lsm_hooks.h | 5 ++---
security/security.c | 6 +++++-
security/selinux/hooks.c | 6 ++++--
security/smack/smack_lsm.c | 5 +++--
4 files changed, 14 insertions(+), 8 deletions(-)
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index d1235a3cd8e9..088985d10a69 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -1383,8 +1383,7 @@
* operation.
* Must be called with inode->i_mutex locked.
* @dentry contains the inode we wish to set the security context of.
- * @ctx contains the string which we wish to set in the inode.
- * @ctxlen contains the length of @ctx.
+ * @cp contains the string which we wish to set in the inode.
*
* @inode_getsecctx:
* On success, returns 0 and fills out @cp with the security
@@ -1661,7 +1660,7 @@ union security_list_options {
void (*inode_invalidate_secctx)(struct inode *inode);
int (*inode_notifysecctx)(struct inode *inode, struct lsm_context *cp);
- int (*inode_setsecctx)(struct dentry *dentry, void *ctx, u32 ctxlen);
+ int (*inode_setsecctx)(struct dentry *dentry, struct lsm_context *cp);
int (*inode_getsecctx)(struct inode *inode, struct lsm_context *cp);
#ifdef CONFIG_SECURITY_NETWORK
diff --git a/security/security.c b/security/security.c
index c8ce190dcdda..9d09c774a1e9 100644
--- a/security/security.c
+++ b/security/security.c
@@ -2008,7 +2008,11 @@ EXPORT_SYMBOL(security_inode_notifysecctx);
int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
{
- return call_int_hook(inode_setsecctx, 0, dentry, ctx, ctxlen);
+ struct lsm_context lc;
+
+ lc.context = ctx;
+ lc.len = ctxlen;
+ return call_int_hook(inode_setsecctx, 0, dentry, &lc);
}
EXPORT_SYMBOL(security_inode_setsecctx);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 0e347a26c3d8..af0d98f4dd37 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -6356,9 +6356,11 @@ static int selinux_inode_notifysecctx(struct inode *inode,
/*
* called with inode->i_mutex locked
*/
-static int selinux_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
+static int selinux_inode_setsecctx(struct dentry *dentry,
+ struct lsm_context *cp)
{
- return __vfs_setxattr_noperm(dentry, XATTR_NAME_SELINUX, ctx, ctxlen, 0);
+ return __vfs_setxattr_noperm(dentry, XATTR_NAME_SELINUX, cp->context,
+ cp->len, 0);
}
static int selinux_inode_getsecctx(struct inode *inode, struct lsm_context *cp)
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index e00346799cdf..4570e8cac1b3 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -4480,9 +4480,10 @@ static int smack_inode_notifysecctx(struct inode *inode, struct lsm_context *cp)
cp->len, 0);
}
-static int smack_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
+static int smack_inode_setsecctx(struct dentry *dentry, struct lsm_context *cp)
{
- return __vfs_setxattr_noperm(dentry, XATTR_NAME_SMACK, ctx, ctxlen, 0);
+ return __vfs_setxattr_noperm(dentry, XATTR_NAME_SMACK, cp->context,
+ cp->len, 0);
}
static int smack_inode_getsecctx(struct inode *inode, struct lsm_context *cp)
--
2.19.1
^ permalink raw reply related
* [PATCH 47/58] LSM: Use lsm_context in security_release_secctx
From: Casey Schaufler @ 2019-06-02 16:50 UTC (permalink / raw)
To: casey.schaufler, jmorris, linux-security-module, selinux
Cc: casey, keescook, john.johansen, penguin-kernel, paul, sds
In-Reply-To: <20190602165101.25079-1-casey@schaufler-ca.com>
Convert security_release_secctx to use the lsm_context structure
instead of a context/secid pair. There is some scaffolding involved
that will be removed when the related data is updated.
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
---
drivers/android/binder.c | 21 +++++++--------
fs/kernfs/dir.c | 9 ++++---
fs/kernfs/inode.c | 2 +-
fs/nfs/nfs4proc.c | 9 +++++--
fs/nfsd/nfs4xdr.c | 2 +-
include/linux/security.h | 4 +--
include/net/scm.h | 10 +++----
kernel/audit.c | 27 +++++++++----------
kernel/auditsc.c | 27 +++++++++----------
net/ipv4/ip_sockglue.c | 9 +++----
net/netfilter/nf_conntrack_netlink.c | 10 +++----
net/netfilter/nf_conntrack_standalone.c | 9 +++----
net/netfilter/nfnetlink_queue.c | 28 ++++++++++---------
net/netlabel/netlabel_unlabeled.c | 36 ++++++++++++-------------
net/netlabel/netlabel_user.c | 11 ++++----
security/security.c | 10 +++----
16 files changed, 109 insertions(+), 115 deletions(-)
diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index 0eeb5b75da5b..c2cfef13257c 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -2874,8 +2874,7 @@ static void binder_transaction(struct binder_proc *proc,
binder_size_t last_fixup_min_off = 0;
struct binder_context *context = proc->context;
int t_debug_id = atomic_inc_return(&binder_last_id);
- char *secctx = NULL;
- u32 secctx_sz = 0;
+ struct lsm_context lc = { .len = 0, .context = NULL, };
e = binder_transaction_log_add(&binder_transaction_log);
e->debug_id = t_debug_id;
@@ -3122,14 +3121,14 @@ static void binder_transaction(struct binder_proc *proc,
struct lsm_export le;
security_task_getsecid(proc->tsk, &le);
- ret = security_secid_to_secctx(&le, &secctx, &secctx_sz);
+ ret = security_secid_to_secctx(&le, &lc.context, &lc.len);
if (ret) {
return_error = BR_FAILED_REPLY;
return_error_param = ret;
return_error_line = __LINE__;
goto err_get_secctx_failed;
}
- extra_buffers_size += ALIGN(secctx_sz, sizeof(u64));
+ extra_buffers_size += ALIGN(lc.len, sizeof(u64));
}
trace_binder_transaction(reply, t, target_node);
@@ -3148,18 +3147,18 @@ static void binder_transaction(struct binder_proc *proc,
t->buffer = NULL;
goto err_binder_alloc_buf_failed;
}
- if (secctx) {
+ if (lc.context) {
size_t buf_offset = ALIGN(tr->data_size, sizeof(void *)) +
ALIGN(tr->offsets_size, sizeof(void *)) +
ALIGN(extra_buffers_size, sizeof(void *)) -
- ALIGN(secctx_sz, sizeof(u64));
+ ALIGN(lc.len, sizeof(u64));
t->security_ctx = (uintptr_t)t->buffer->user_data + buf_offset;
binder_alloc_copy_to_buffer(&target_proc->alloc,
t->buffer, buf_offset,
- secctx, secctx_sz);
- security_release_secctx(secctx, secctx_sz);
- secctx = NULL;
+ lc.context, lc.len);
+ security_release_secctx(&lc);
+ lc.context = NULL;
}
t->buffer->debug_id = t->debug_id;
t->buffer->transaction = t;
@@ -3479,8 +3478,8 @@ static void binder_transaction(struct binder_proc *proc,
t->buffer->transaction = NULL;
binder_alloc_free_buf(&target_proc->alloc, t->buffer);
err_binder_alloc_buf_failed:
- if (secctx)
- security_release_secctx(secctx, secctx_sz);
+ if (lc.context)
+ security_release_secctx(&lc);
err_get_secctx_failed:
kfree(tcomplete);
binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE);
diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c
index b84d635567d3..11672c075a8b 100644
--- a/fs/kernfs/dir.c
+++ b/fs/kernfs/dir.c
@@ -532,9 +532,12 @@ void kernfs_put(struct kernfs_node *kn)
kfree_const(kn->name);
if (kn->iattr) {
- if (kn->iattr->ia_secdata)
- security_release_secctx(kn->iattr->ia_secdata,
- kn->iattr->ia_secdata_len);
+ if (kn->iattr->ia_secdata) {
+ struct lsm_context lc; /* Scaffolding -Casey */
+ lc.context = kn->iattr->ia_secdata;
+ lc.len = kn->iattr->ia_secdata_len;
+ security_release_secctx(&lc);
+ }
simple_xattrs_free(&kn->iattr->xattrs);
kmem_cache_free(kernfs_iattrs_cache, kn->iattr);
}
diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c
index 41c5afc698fc..45781f0da80f 100644
--- a/fs/kernfs/inode.c
+++ b/fs/kernfs/inode.c
@@ -370,7 +370,7 @@ static int kernfs_security_xattr_set(const struct xattr_handler *handler,
mutex_unlock(&kernfs_mutex);
if (lc.context)
- security_release_secctx(lc.context, lc.len);
+ security_release_secctx(&lc);
return error;
}
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index de000649f9f3..8dee01eda643 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -134,8 +134,13 @@ nfs4_label_init_security(struct inode *dir, struct dentry *dentry,
static inline void
nfs4_label_release_security(struct nfs4_label *label)
{
- if (label)
- security_release_secctx(label->label, label->len);
+ struct lsm_context lc; /* Scaffolding -Casey */
+
+ if (label) {
+ lc.context = label->label;
+ lc.len = label->len;
+ security_release_secctx(&lc);
+ }
}
static inline u32 *nfs4_bitmask(struct nfs_server *server, struct nfs4_label *label)
{
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 1bf34730d054..3d1251bd588f 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -2918,7 +2918,7 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp,
out:
#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
if (lc.context)
- security_release_secctx(lc.context, lc.len);
+ security_release_secctx(&lc);
#endif /* CONFIG_NFSD_V4_SECURITY_LABEL */
kfree(acl);
if (tempfh) {
diff --git a/include/linux/security.h b/include/linux/security.h
index 3f757b2d8275..57ce9b824eef 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -433,7 +433,7 @@ int security_netlink_send(struct sock *sk, struct sk_buff *skb);
int security_ismaclabel(const char *name);
int security_secid_to_secctx(struct lsm_export *l, char **secdata, u32 *seclen);
int security_secctx_to_secid(struct lsm_context *cp, struct lsm_export *l);
-void security_release_secctx(char *secdata, u32 seclen);
+void security_release_secctx(struct lsm_context *cp);
void security_inode_invalidate_secctx(struct inode *inode);
int security_inode_notifysecctx(struct inode *inode, struct lsm_context *cp);
@@ -1222,7 +1222,7 @@ static inline int security_secctx_to_secid(struct lsm_context *cp,
return -EOPNOTSUPP;
}
-static inline void security_release_secctx(char *secdata, u32 seclen)
+static inline void security_release_secctx(struct lsm_context *cp);
{
}
diff --git a/include/net/scm.h b/include/net/scm.h
index b5d1c24318e3..7e242ebdd258 100644
--- a/include/net/scm.h
+++ b/include/net/scm.h
@@ -92,16 +92,16 @@ static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
#ifdef CONFIG_SECURITY_NETWORK
static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm)
{
- char *secdata;
- u32 seclen;
+ struct lsm_context lc;
int err;
if (test_bit(SOCK_PASSSEC, &sock->flags)) {
- err = security_secid_to_secctx(&scm->le, &secdata, &seclen);
+ err = security_secid_to_secctx(&scm->le, &lc.context, &lc.len);
if (!err) {
- put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, seclen, secdata);
- security_release_secctx(secdata, seclen);
+ put_cmsg(msg, SOL_SOCKET, SCM_SECURITY,
+ lc.len, lc.context);
+ security_release_secctx(&lc);
}
}
}
diff --git a/kernel/audit.c b/kernel/audit.c
index d83d1f05c95d..269c76fefe40 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -1191,8 +1191,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
struct audit_buffer *ab;
u16 msg_type = nlh->nlmsg_type;
struct audit_sig_info *sig_data;
- char *ctx = NULL;
- u32 len;
+ struct lsm_context lc = { .context = NULL, .len = 0, };
err = audit_netlink_ok(skb, msg_type);
if (err)
@@ -1428,27 +1427,26 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
break;
}
case AUDIT_SIGNAL_INFO:
- len = 0;
if (lsm_export_any(&audit_sig_lsm)) {
- err = security_secid_to_secctx(&audit_sig_lsm, &ctx,
- &len);
+ err = security_secid_to_secctx(&audit_sig_lsm,
+ &lc.context, &lc.len);
if (err)
return err;
}
- sig_data = kmalloc(sizeof(*sig_data) + len, GFP_KERNEL);
+ sig_data = kmalloc(sizeof(*sig_data) + lc.len, GFP_KERNEL);
if (!sig_data) {
if (lsm_export_any(&audit_sig_lsm))
- security_release_secctx(ctx, len);
+ security_release_secctx(&lc);
return -ENOMEM;
}
sig_data->uid = from_kuid(&init_user_ns, audit_sig_uid);
sig_data->pid = audit_sig_pid;
if (lsm_export_any(&audit_sig_lsm)) {
- memcpy(sig_data->ctx, ctx, len);
- security_release_secctx(ctx, len);
+ memcpy(sig_data->ctx, lc.context, lc.len);
+ security_release_secctx(&lc);
}
audit_send_reply(skb, seq, AUDIT_SIGNAL_INFO, 0, 0,
- sig_data, sizeof(*sig_data) + len);
+ sig_data, sizeof(*sig_data) + lc.len);
kfree(sig_data);
break;
case AUDIT_TTY_GET: {
@@ -2070,24 +2068,23 @@ void audit_log_key(struct audit_buffer *ab, char *key)
int audit_log_task_context(struct audit_buffer *ab)
{
- char *ctx = NULL;
- unsigned len;
int error;
struct lsm_export le;
+ struct lsm_context lc = { .context = NULL, };
security_task_getsecid(current, &le);
if (!lsm_export_any(&le))
return 0;
- error = security_secid_to_secctx(&le, &ctx, &len);
+ error = security_secid_to_secctx(&le, &lc.context, &lc.len);
if (error) {
if (error != -EINVAL)
goto error_path;
return 0;
}
- audit_log_format(ab, " subj=%s", ctx);
- security_release_secctx(ctx, len);
+ audit_log_format(ab, " subj=%s", lc.context);
+ security_release_secctx(&lc);
return 0;
error_path:
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index d64775f4bb1b..4dab81c7aca0 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -938,9 +938,8 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid,
unsigned int sessionid,
struct lsm_export *l, char *comm)
{
+ struct lsm_context lc = { .context = NULL, };
struct audit_buffer *ab;
- char *ctx = NULL;
- u32 len;
int rc = 0;
ab = audit_log_start(context, GFP_KERNEL, AUDIT_OBJ_PID);
@@ -951,12 +950,12 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid,
from_kuid(&init_user_ns, auid),
from_kuid(&init_user_ns, uid), sessionid);
if (lsm_export_any(l)) {
- if (security_secid_to_secctx(l, &ctx, &len)) {
+ if (security_secid_to_secctx(l, &lc.context, &lc.len)) {
audit_log_format(ab, " obj=(none)");
rc = 1;
} else {
- audit_log_format(ab, " obj=%s", ctx);
- security_release_secctx(ctx, len);
+ audit_log_format(ab, " obj=%s", lc.context);
+ security_release_secctx(&lc);
}
}
audit_log_format(ab, " ocomm=");
@@ -1191,14 +1190,13 @@ static void show_special(struct audit_context *context, int *call_panic)
from_kgid(&init_user_ns, context->ipc.gid),
context->ipc.mode);
if (lsm_export_any(l)) {
- char *ctx = NULL;
- u32 len;
- if (security_secid_to_secctx(l, &ctx, &len)) {
+ struct lsm_context lc = { .context = NULL, };
+ if (security_secid_to_secctx(l, &lc.context, &lc.len)) {
audit_log_format(ab, " osid=(unknown)");
*call_panic = 1;
} else {
- audit_log_format(ab, " obj=%s", ctx);
- security_release_secctx(ctx, len);
+ audit_log_format(ab, " obj=%s", lc.context);
+ security_release_secctx(&lc);
}
}
if (context->ipc.has_perm) {
@@ -1342,16 +1340,15 @@ static void audit_log_name(struct audit_context *context, struct audit_names *n,
MAJOR(n->rdev),
MINOR(n->rdev));
if (lsm_export_any(&n->olsm)) {
- char *ctx = NULL;
- u32 len;
+ struct lsm_context lc;
- if (security_secid_to_secctx(&n->olsm, &ctx, &len)) {
+ if (security_secid_to_secctx(&n->olsm, &lc.context, &lc.len)) {
audit_log_format(ab, " osid=(unknown)");
if (call_panic)
*call_panic = 2;
} else {
- audit_log_format(ab, " obj=%s", ctx);
- security_release_secctx(ctx, len);
+ audit_log_format(ab, " obj=%s", lc.context);
+ security_release_secctx(&lc);
}
}
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index a4f37ba6dbe2..18a7fab8b2d3 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -131,20 +131,19 @@ static void ip_cmsg_recv_checksum(struct msghdr *msg, struct sk_buff *skb,
static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb)
{
struct lsm_export le;
- char *secdata;
- u32 seclen;
+ struct lsm_context lc;
int err;
err = security_socket_getpeersec_dgram(NULL, skb, &le);
if (err)
return;
- err = security_secid_to_secctx(&le, &secdata, &seclen);
+ err = security_secid_to_secctx(&le, &lc.context, &lc.len);
if (err)
return;
- put_cmsg(msg, SOL_IP, SCM_SECURITY, seclen, secdata);
- security_release_secctx(secdata, seclen);
+ put_cmsg(msg, SOL_IP, SCM_SECURITY, lc.len, lc.context);
+ security_release_secctx(&lc);
}
static void ip_cmsg_recv_dstaddr(struct msghdr *msg, struct sk_buff *skb)
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index d10cc1924e46..49bce1b085ce 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -328,16 +328,16 @@ static int ctnetlink_dump_mark(struct sk_buff *skb, const struct nf_conn *ct)
static int ctnetlink_dump_secctx(struct sk_buff *skb, const struct nf_conn *ct)
{
struct nlattr *nest_secctx;
- int len, ret;
- char *secctx;
+ int ret;
struct lsm_export le;
+ struct lsm_context lc;
lsm_export_init(&le);
le.flags = LSM_EXPORT_SELINUX | LSM_EXPORT_SMACK;
le.selinux = ct->secmark;
le.smack = ct->secmark;
- ret = security_secid_to_secctx(&le, &secctx, &len);
+ ret = security_secid_to_secctx(&le, &lc.context, &lc.len);
if (ret)
return 0;
@@ -346,13 +346,13 @@ static int ctnetlink_dump_secctx(struct sk_buff *skb, const struct nf_conn *ct)
if (!nest_secctx)
goto nla_put_failure;
- if (nla_put_string(skb, CTA_SECCTX_NAME, secctx))
+ if (nla_put_string(skb, CTA_SECCTX_NAME, lc.context))
goto nla_put_failure;
nla_nest_end(skb, nest_secctx);
ret = 0;
nla_put_failure:
- security_release_secctx(secctx, len);
+ security_release_secctx(&lc);
return ret;
}
#else
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
index d353f3efc5a5..97d16a51504b 100644
--- a/net/netfilter/nf_conntrack_standalone.c
+++ b/net/netfilter/nf_conntrack_standalone.c
@@ -173,9 +173,8 @@ static void ct_seq_stop(struct seq_file *s, void *v)
static void ct_show_secctx(struct seq_file *s, const struct nf_conn *ct)
{
int ret;
- u32 len;
- char *secctx;
struct lsm_export le;
+ struct lsm_context lc;
/* Whichever LSM may be using the secmark */
lsm_export_init(&le);
@@ -183,13 +182,13 @@ static void ct_show_secctx(struct seq_file *s, const struct nf_conn *ct)
le.selinux = ct->secmark;
le.smack = ct->secmark;
- ret = security_secid_to_secctx(&le, &secctx, &len);
+ ret = security_secid_to_secctx(&le, &lc.context, &lc.len);
if (ret)
return;
- seq_printf(s, "secctx=%s ", secctx);
+ seq_printf(s, "secctx=%s ", lc.context);
- security_release_secctx(secctx, len);
+ security_release_secctx(&lc);
}
#else
static inline void ct_show_secctx(struct seq_file *s, const struct nf_conn *ct)
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index a0670137477b..b70871693368 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -307,9 +307,9 @@ static int nfqnl_put_sk_uidgid(struct sk_buff *skb, struct sock *sk)
static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, char **secdata)
{
- u32 seclen = 0;
#if IS_ENABLED(CONFIG_NETWORK_SECMARK)
struct lsm_export le;
+ struct lsm_context lc = { .context = NULL, .len = 0, };
if (!skb || !sk_fullsock(skb->sk))
return 0;
@@ -322,12 +322,15 @@ static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, char **secdata)
le.flags = LSM_EXPORT_SELINUX | LSM_EXPORT_SMACK;
le.selinux = skb->secmark;
le.smack = skb->secmark;
- security_secid_to_secctx(&le, secdata, &seclen);
+ security_secid_to_secctx(&le, &lc.context, &lc.len);
+ *secdata = lc.context;
}
read_unlock_bh(&skb->sk->sk_callback_lock);
+ return lc.len;
+#else
+ return 0;
#endif
- return seclen;
}
static u32 nfqnl_get_bridge_size(struct nf_queue_entry *entry)
@@ -403,8 +406,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
enum ip_conntrack_info uninitialized_var(ctinfo);
struct nfnl_ct_hook *nfnl_ct;
bool csum_verify;
- char *secdata = NULL;
- u32 seclen = 0;
+ struct lsm_context lc = { .context = NULL, };
size = nlmsg_total_size(sizeof(struct nfgenmsg))
+ nla_total_size(sizeof(struct nfqnl_msg_packet_hdr))
@@ -470,9 +472,9 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
}
if ((queue->flags & NFQA_CFG_F_SECCTX) && entskb->sk) {
- seclen = nfqnl_get_sk_secctx(entskb, &secdata);
- if (seclen)
- size += nla_total_size(seclen);
+ lc.len = nfqnl_get_sk_secctx(entskb, &lc.context);
+ if (lc.len)
+ size += nla_total_size(lc.len);
}
skb = alloc_skb(size, GFP_ATOMIC);
@@ -605,7 +607,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
nfqnl_put_sk_uidgid(skb, entskb->sk) < 0)
goto nla_put_failure;
- if (seclen && nla_put(skb, NFQA_SECCTX, seclen, secdata))
+ if (lc.len && nla_put(skb, NFQA_SECCTX, lc.len, lc.context))
goto nla_put_failure;
if (ct && nfnl_ct->build(skb, ct, ctinfo, NFQA_CT, NFQA_CT_INFO) < 0)
@@ -633,8 +635,8 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
}
nlh->nlmsg_len = skb->len;
- if (seclen)
- security_release_secctx(secdata, seclen);
+ if (lc.context)
+ security_release_secctx(&lc);
return skb;
nla_put_failure:
@@ -642,8 +644,8 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
kfree_skb(skb);
net_err_ratelimited("nf_queue: error creating packet message\n");
nlmsg_failure:
- if (seclen)
- security_release_secctx(secdata, seclen);
+ if (lc.context)
+ security_release_secctx(&lc);
return NULL;
}
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c
index 707ea5a364b0..4c4a8f6df261 100644
--- a/net/netlabel/netlabel_unlabeled.c
+++ b/net/netlabel/netlabel_unlabeled.c
@@ -387,8 +387,6 @@ int netlbl_unlhsh_add(struct net *net,
struct net_device *dev;
struct netlbl_unlhsh_iface *iface;
struct audit_buffer *audit_buf = NULL;
- char *secctx = NULL;
- u32 secctx_len;
if (addr_len != sizeof(struct in_addr) &&
addr_len != sizeof(struct in6_addr))
@@ -451,9 +449,10 @@ int netlbl_unlhsh_add(struct net *net,
unlhsh_add_return:
rcu_read_unlock();
if (audit_buf != NULL) {
- if (security_secid_to_secctx(l, &secctx, &secctx_len) == 0) {
- audit_log_format(audit_buf, " sec_obj=%s", secctx);
- security_release_secctx(secctx, secctx_len);
+ struct lsm_context lc;
+ if (security_secid_to_secctx(l, &lc.context, &lc.len) == 0) {
+ audit_log_format(audit_buf, " sec_obj=%s", lc.context);
+ security_release_secctx(&lc);
}
audit_log_format(audit_buf, " res=%u", ret_val == 0 ? 1 : 0);
audit_log_end(audit_buf);
@@ -484,8 +483,6 @@ static int netlbl_unlhsh_remove_addr4(struct net *net,
struct netlbl_unlhsh_addr4 *entry;
struct audit_buffer *audit_buf;
struct net_device *dev;
- char *secctx;
- u32 secctx_len;
spin_lock(&netlbl_unlhsh_lock);
list_entry = netlbl_af4list_remove(addr->s_addr, mask->s_addr,
@@ -499,6 +496,7 @@ static int netlbl_unlhsh_remove_addr4(struct net *net,
audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_STCDEL,
audit_info);
if (audit_buf != NULL) {
+ struct lsm_context lc;
dev = dev_get_by_index(net, iface->ifindex);
netlbl_af4list_audit_addr(audit_buf, 1,
(dev != NULL ? dev->name : NULL),
@@ -507,9 +505,9 @@ static int netlbl_unlhsh_remove_addr4(struct net *net,
dev_put(dev);
if (entry != NULL &&
security_secid_to_secctx(&entry->le,
- &secctx, &secctx_len) == 0) {
- audit_log_format(audit_buf, " sec_obj=%s", secctx);
- security_release_secctx(secctx, secctx_len);
+ &lc.context, &lc.len) == 0) {
+ audit_log_format(audit_buf, " sec_obj=%s", lc.context);
+ security_release_secctx(&lc);
}
audit_log_format(audit_buf, " res=%u", entry != NULL ? 1 : 0);
audit_log_end(audit_buf);
@@ -560,6 +558,7 @@ static int netlbl_unlhsh_remove_addr6(struct net *net,
audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_STCDEL,
audit_info);
if (audit_buf != NULL) {
+ struct lsm_context lc;
dev = dev_get_by_index(net, iface->ifindex);
netlbl_af6list_audit_addr(audit_buf, 1,
(dev != NULL ? dev->name : NULL),
@@ -568,9 +567,9 @@ static int netlbl_unlhsh_remove_addr6(struct net *net,
dev_put(dev);
if (entry != NULL &&
security_secid_to_secctx(&entry->le,
- &secctx, &secctx_len) == 0) {
- audit_log_format(audit_buf, " sec_obj=%s", secctx);
- security_release_secctx(secctx, secctx_len);
+ &lc.context, &lc.len) == 0) {
+ audit_log_format(audit_buf, " sec_obj=%s", lc.context);
+ security_release_secctx(&lc);
}
audit_log_format(audit_buf, " res=%u", entry != NULL ? 1 : 0);
audit_log_end(audit_buf);
@@ -1082,9 +1081,8 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd,
struct netlbl_unlhsh_walk_arg *cb_arg = arg;
struct net_device *dev;
void *data;
- char *secctx;
- u32 secctx_len;
struct lsm_export *lep;
+ struct lsm_context lc;
data = genlmsg_put(cb_arg->skb, NETLINK_CB(cb_arg->nl_cb->skb).portid,
cb_arg->seq, &netlbl_unlabel_gnl_family,
@@ -1139,14 +1137,14 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd,
lep = (struct lsm_export *)&addr6->le;
}
- ret_val = security_secid_to_secctx(lep, &secctx, &secctx_len);
+ ret_val = security_secid_to_secctx(lep, &lc.context, &lc.len);
if (ret_val != 0)
goto list_cb_failure;
ret_val = nla_put(cb_arg->skb,
NLBL_UNLABEL_A_SECCTX,
- secctx_len,
- secctx);
- security_release_secctx(secctx, secctx_len);
+ lc.len,
+ lc.context);
+ security_release_secctx(&lc);
if (ret_val != 0)
goto list_cb_failure;
diff --git a/net/netlabel/netlabel_user.c b/net/netlabel/netlabel_user.c
index 2cc96305c841..0418f0935199 100644
--- a/net/netlabel/netlabel_user.c
+++ b/net/netlabel/netlabel_user.c
@@ -98,8 +98,7 @@ struct audit_buffer *netlbl_audit_start_common(int type,
struct netlbl_audit *audit_info)
{
struct audit_buffer *audit_buf;
- char *secctx;
- u32 secctx_len;
+ struct lsm_context lc;
if (audit_enabled == AUDIT_OFF)
return NULL;
@@ -113,10 +112,10 @@ struct audit_buffer *netlbl_audit_start_common(int type,
audit_info->sessionid);
if (lsm_export_any(&audit_info->le) &&
- security_secid_to_secctx(&audit_info->le, &secctx,
- &secctx_len) == 0) {
- audit_log_format(audit_buf, " subj=%s", secctx);
- security_release_secctx(secctx, secctx_len);
+ security_secid_to_secctx(&audit_info->le, &lc.context,
+ &lc.len) == 0) {
+ audit_log_format(audit_buf, " subj=%s", lc.context);
+ security_release_secctx(&lc);
}
return audit_buf;
diff --git a/security/security.c b/security/security.c
index 029d2f4fe48c..3da7302d20ec 100644
--- a/security/security.c
+++ b/security/security.c
@@ -1981,7 +1981,7 @@ int security_secid_to_secctx(struct lsm_export *l, char **secdata, u32 *seclen)
if (secdata)
*secdata = lc.context;
else
- security_release_secctx(lc.context, lc.len);
+ security_release_secctx(&lc);
*seclen = lc.len;
return rc;
}
@@ -1994,13 +1994,9 @@ int security_secctx_to_secid(struct lsm_context *cp, struct lsm_export *l)
}
EXPORT_SYMBOL(security_secctx_to_secid);
-void security_release_secctx(char *secdata, u32 seclen)
+void security_release_secctx(struct lsm_context *cp)
{
- struct lsm_context lc;
-
- lc.context = secdata;
- lc.len = seclen;
- call_one_void_hook(release_secctx, &lc);
+ call_one_void_hook(release_secctx, cp);
}
EXPORT_SYMBOL(security_release_secctx);
--
2.19.1
^ permalink raw reply related
* [PATCH 46/58] LSM: Use lsm_context in release_secctx hooks
From: Casey Schaufler @ 2019-06-02 16:50 UTC (permalink / raw)
To: casey.schaufler, jmorris, linux-security-module, selinux
Cc: casey, keescook, john.johansen, penguin-kernel, paul, sds
In-Reply-To: <20190602165101.25079-1-casey@schaufler-ca.com>
Convert SELinux, Smack and AppAror to use the lsm_context structure
instead of a context/secid pair. There is some scaffolding involved
that will be removed when the related data is updated.
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
---
include/linux/lsm_hooks.h | 3 +--
security/apparmor/include/secid.h | 2 +-
security/apparmor/secid.c | 4 ++--
security/security.c | 6 +++++-
security/selinux/hooks.c | 4 ++--
security/smack/smack_lsm.c | 4 ++--
6 files changed, 13 insertions(+), 10 deletions(-)
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index d4ace7af4950..3a779a0f9e15 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -1329,7 +1329,6 @@
* @release_secctx:
* Release the security context.
* @secdata contains the security context.
- * @seclen contains the length of the security context.
*
* Security hooks for Audit
*
@@ -1663,7 +1662,7 @@ union security_list_options {
int (*secid_to_secctx)(struct lsm_export *l, struct lsm_context *cp);
int (*secctx_to_secid)(const struct lsm_context *cp,
struct lsm_export *l);
- void (*release_secctx)(char *secdata, u32 seclen);
+ void (*release_secctx)(struct lsm_context *cp);
void (*inode_invalidate_secctx)(struct inode *inode);
int (*inode_notifysecctx)(struct inode *inode, struct lsm_context *cp);
diff --git a/security/apparmor/include/secid.h b/security/apparmor/include/secid.h
index acfcf99bff0e..a780e56d4f5b 100644
--- a/security/apparmor/include/secid.h
+++ b/security/apparmor/include/secid.h
@@ -29,7 +29,7 @@ struct aa_label *aa_secid_to_label(struct lsm_export *l);
int apparmor_secid_to_secctx(struct lsm_export *l, struct lsm_context *cp);
int apparmor_secctx_to_secid(const struct lsm_context *cp,
struct lsm_export *l);
-void apparmor_release_secctx(char *secdata, u32 seclen);
+void apparmor_release_secctx(struct lsm_context *cp);
int aa_alloc_secid(struct aa_label *label, gfp_t gfp);
diff --git a/security/apparmor/secid.c b/security/apparmor/secid.c
index 35df38592b6e..46c8b9a67ac7 100644
--- a/security/apparmor/secid.c
+++ b/security/apparmor/secid.c
@@ -123,9 +123,9 @@ int apparmor_secctx_to_secid(const struct lsm_context *cp, struct lsm_export *l)
return 0;
}
-void apparmor_release_secctx(char *secdata, u32 seclen)
+void apparmor_release_secctx(struct lsm_context *cp)
{
- kfree(secdata);
+ kfree(cp->context);
}
/**
diff --git a/security/security.c b/security/security.c
index 44a4402073d7..029d2f4fe48c 100644
--- a/security/security.c
+++ b/security/security.c
@@ -1996,7 +1996,11 @@ EXPORT_SYMBOL(security_secctx_to_secid);
void security_release_secctx(char *secdata, u32 seclen)
{
- call_one_void_hook(release_secctx, secdata, seclen);
+ struct lsm_context lc;
+
+ lc.context = secdata;
+ lc.len = seclen;
+ call_one_void_hook(release_secctx, &lc);
}
EXPORT_SYMBOL(security_release_secctx);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index fe09905d013c..332296f69f76 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -6322,9 +6322,9 @@ static int selinux_secctx_to_secid(const struct lsm_context *cp,
return rc;
}
-static void selinux_release_secctx(char *secdata, u32 seclen)
+static void selinux_release_secctx(struct lsm_context *cp)
{
- kfree(secdata);
+ kfree(cp->context);
}
static void selinux_inode_invalidate_secctx(struct inode *inode)
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 3d24503029e5..cf27905ccaa5 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -4468,9 +4468,9 @@ static int smack_secctx_to_secid(const struct lsm_context *cp,
}
/*
- * There smack_release_secctx hook does nothing
+ * The smack_release_secctx hook does nothing
*/
-static void smack_release_secctx(char *secdata, u32 seclen)
+static void smack_release_secctx(struct lsm_context *cp)
{
}
--
2.19.1
^ permalink raw reply related
* [PATCH 44/58] LSM: Use lsm_context in security_inode_getsecctx
From: Casey Schaufler @ 2019-06-02 16:50 UTC (permalink / raw)
To: casey.schaufler, jmorris, linux-security-module, selinux
Cc: casey, keescook, john.johansen, penguin-kernel, paul, sds
In-Reply-To: <20190602165101.25079-1-casey@schaufler-ca.com>
From: Casey Schaufler <cschaufler@schaufler-ca.com>
Convert security_inode_getsecctx to use the lsm_context structure
instead of a context/secid pair. There is some scaffolding involved
that will be removed when the related data is updated.
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
---
fs/kernfs/inode.c | 11 +++++------
fs/nfsd/nfs4xdr.c | 14 ++++++--------
include/linux/security.h | 5 +++--
security/security.c | 11 ++---------
4 files changed, 16 insertions(+), 25 deletions(-)
diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c
index 460e611b1938..41c5afc698fc 100644
--- a/fs/kernfs/inode.c
+++ b/fs/kernfs/inode.c
@@ -351,8 +351,7 @@ static int kernfs_security_xattr_set(const struct xattr_handler *handler,
{
struct kernfs_node *kn = inode->i_private;
struct kernfs_iattrs *attrs;
- void *secdata;
- u32 secdata_len = 0;
+ struct lsm_context lc = { .context = NULL, .len = 0, };
int error;
attrs = kernfs_iattrs(kn);
@@ -362,16 +361,16 @@ static int kernfs_security_xattr_set(const struct xattr_handler *handler,
error = security_inode_setsecurity(inode, suffix, value, size, flags);
if (error)
return error;
- error = security_inode_getsecctx(inode, &secdata, &secdata_len);
+ error = security_inode_getsecctx(inode, &lc);
if (error)
return error;
mutex_lock(&kernfs_mutex);
- error = kernfs_node_setsecdata(attrs, &secdata, &secdata_len);
+ error = kernfs_node_setsecdata(attrs, (void **)&lc.context, &lc.len);
mutex_unlock(&kernfs_mutex);
- if (secdata)
- security_release_secctx(secdata, secdata_len);
+ if (lc.context)
+ security_release_secctx(lc.context, lc.len);
return error;
}
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 3de42a729093..1bf34730d054 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -2420,8 +2420,7 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp,
__be32 status;
int err;
struct nfs4_acl *acl = NULL;
- void *context = NULL;
- int contextlen;
+ struct lsm_context lc = { .context = NULL, .len = 0, };
bool contextsupport = false;
struct nfsd4_compoundres *resp = rqstp->rq_resp;
u32 minorversion = resp->cstate.minorversion;
@@ -2477,8 +2476,7 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp,
if ((bmval2 & FATTR4_WORD2_SECURITY_LABEL) ||
bmval0 & FATTR4_WORD0_SUPPORTED_ATTRS) {
if (exp->ex_flags & NFSEXP_SECURITY_LABEL)
- err = security_inode_getsecctx(d_inode(dentry),
- &context, &contextlen);
+ err = security_inode_getsecctx(d_inode(dentry), &lc);
else
err = -EOPNOTSUPP;
contextsupport = (err == 0);
@@ -2907,8 +2905,8 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp,
}
if (bmval2 & FATTR4_WORD2_SECURITY_LABEL) {
- status = nfsd4_encode_security_label(xdr, rqstp, context,
- contextlen);
+ status = nfsd4_encode_security_label(xdr, rqstp, lc.context,
+ lc.len);
if (status)
goto out;
}
@@ -2919,8 +2917,8 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp,
out:
#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
- if (context)
- security_release_secctx(context, contextlen);
+ if (lc.context)
+ security_release_secctx(lc.context, lc.len);
#endif /* CONFIG_NFSD_V4_SECURITY_LABEL */
kfree(acl);
if (tempfh) {
diff --git a/include/linux/security.h b/include/linux/security.h
index 6b2fcca08a43..90d1ff7a2fe6 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -439,7 +439,7 @@ void security_release_secctx(char *secdata, u32 seclen);
void security_inode_invalidate_secctx(struct inode *inode);
int security_inode_notifysecctx(struct inode *inode, struct lsm_context *cp);
int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen);
-int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen);
+int security_inode_getsecctx(struct inode *inode, struct lsm_context *cp);
#else /* CONFIG_SECURITY */
static inline int call_lsm_notifier(enum lsm_event event, void *data)
@@ -1241,7 +1241,8 @@ static inline int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32
{
return -EOPNOTSUPP;
}
-static inline int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
+static inline int security_inode_getsecctx(struct inode *inode,
+ struct lsm_context *cp);
{
return -EOPNOTSUPP;
}
diff --git a/security/security.c b/security/security.c
index 74f211d58e5f..4f999cfcf949 100644
--- a/security/security.c
+++ b/security/security.c
@@ -2023,16 +2023,9 @@ int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
}
EXPORT_SYMBOL(security_inode_setsecctx);
-int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
+int security_inode_getsecctx(struct inode *inode, struct lsm_context *cp)
{
- struct lsm_context lc = { .context = NULL, .len = 0, };
- int rc;
-
- rc = call_int_hook(inode_getsecctx, -EOPNOTSUPP, inode, &lc);
-
- *ctx = (void *)lc.context;
- *ctxlen = lc.len;
- return rc;
+ return call_int_hook(inode_getsecctx, -EOPNOTSUPP, inode, cp);
}
EXPORT_SYMBOL(security_inode_getsecctx);
--
2.19.1
^ permalink raw reply related
* [PATCH 45/58] LSM: Use lsm_context in security_secctx_to_secid
From: Casey Schaufler @ 2019-06-02 16:50 UTC (permalink / raw)
To: casey.schaufler, jmorris, linux-security-module, selinux
Cc: casey, keescook, john.johansen, penguin-kernel, paul, sds
In-Reply-To: <20190602165101.25079-1-casey@schaufler-ca.com>
Convert security_secctx_to_secid to use the lsm_context structure
instead of a context/secid pair. There is some scaffolding involved
that will be removed when the related data is updated.
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
---
include/linux/security.h | 6 ++----
kernel/cred.c | 5 ++++-
net/netfilter/nft_meta.c | 5 ++++-
net/netfilter/xt_SECMARK.c | 5 ++++-
net/netlabel/netlabel_unlabeled.c | 16 ++++++++--------
security/security.c | 9 ++-------
6 files changed, 24 insertions(+), 22 deletions(-)
diff --git a/include/linux/security.h b/include/linux/security.h
index 90d1ff7a2fe6..3f757b2d8275 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -432,8 +432,7 @@ int security_setprocattr(const char *lsm, const char *name, void *value,
int security_netlink_send(struct sock *sk, struct sk_buff *skb);
int security_ismaclabel(const char *name);
int security_secid_to_secctx(struct lsm_export *l, char **secdata, u32 *seclen);
-int security_secctx_to_secid(const char *secdata, u32 seclen,
- struct lsm_export *l);
+int security_secctx_to_secid(struct lsm_context *cp, struct lsm_export *l);
void security_release_secctx(char *secdata, u32 seclen);
void security_inode_invalidate_secctx(struct inode *inode);
@@ -1217,8 +1216,7 @@ static inline int security_secid_to_secctx(struct lsm_export *l,
return -EOPNOTSUPP;
}
-static inline int security_secctx_to_secid(const char *secdata,
- u32 seclen,
+static inline int security_secctx_to_secid(struct lsm_context *cp,
struct lsm_export *l)
{
return -EOPNOTSUPP;
diff --git a/kernel/cred.c b/kernel/cred.c
index 7792538b1ca6..ebae67fdd4d0 100644
--- a/kernel/cred.c
+++ b/kernel/cred.c
@@ -724,10 +724,13 @@ EXPORT_SYMBOL(set_security_override);
*/
int set_security_override_from_ctx(struct cred *new, const char *secctx)
{
+ struct lsm_context lc;
struct lsm_export le;
int ret;
- ret = security_secctx_to_secid(secctx, strlen(secctx), &le);
+ lc.context = secctx;
+ lc.len = strlen(secctx);
+ ret = security_secctx_to_secid(&lc, &le);
if (ret < 0)
return ret;
diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
index a1d3dab5bc25..f25b26318d72 100644
--- a/net/netfilter/nft_meta.c
+++ b/net/netfilter/nft_meta.c
@@ -577,11 +577,14 @@ static const struct nla_policy nft_secmark_policy[NFTA_SECMARK_MAX + 1] = {
static int nft_secmark_compute_secid(struct nft_secmark *priv)
{
struct lsm_export le;
+ struct lsm_context lc;
u32 tmp_secid = 0;
int err;
lsm_export_init(&le);
- err = security_secctx_to_secid(priv->ctx, strlen(priv->ctx), &le);
+ lc.context = priv->ctx;
+ lc.len = strlen(priv->ctx);
+ err = security_secctx_to_secid(&lc, &le);
if (err)
return err;
diff --git a/net/netfilter/xt_SECMARK.c b/net/netfilter/xt_SECMARK.c
index 9a2a97c200a2..a06e50535194 100644
--- a/net/netfilter/xt_SECMARK.c
+++ b/net/netfilter/xt_SECMARK.c
@@ -50,13 +50,16 @@ secmark_tg(struct sk_buff *skb, const struct xt_action_param *par)
static int checkentry_lsm(struct xt_secmark_target_info *info)
{
struct lsm_export le;
+ struct lsm_context lc;
int err;
info->secctx[SECMARK_SECCTX_MAX - 1] = '\0';
info->secid = 0;
lsm_export_init(&le);
- err = security_secctx_to_secid(info->secctx, strlen(info->secctx), &le);
+ lc.context = info->secctx;
+ lc.len = strlen(info->secctx);
+ err = security_secctx_to_secid(&lc, &le);
if (err) {
if (err == -EINVAL)
pr_info_ratelimited("invalid security context \'%s\'\n",
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c
index f79ab91bf25e..707ea5a364b0 100644
--- a/net/netlabel/netlabel_unlabeled.c
+++ b/net/netlabel/netlabel_unlabeled.c
@@ -894,6 +894,7 @@ static int netlbl_unlabel_staticadd(struct sk_buff *skb,
void *mask;
u32 addr_len;
struct lsm_export le;
+ struct lsm_context lc;
struct netlbl_audit audit_info;
/* Don't allow users to add both IPv4 and IPv6 addresses for a
@@ -914,10 +915,9 @@ static int netlbl_unlabel_staticadd(struct sk_buff *skb,
if (ret_val != 0)
return ret_val;
dev_name = nla_data(info->attrs[NLBL_UNLABEL_A_IFACE]);
- ret_val = security_secctx_to_secid(
- nla_data(info->attrs[NLBL_UNLABEL_A_SECCTX]),
- nla_len(info->attrs[NLBL_UNLABEL_A_SECCTX]),
- &le);
+ lc.context = nla_data(info->attrs[NLBL_UNLABEL_A_SECCTX]);
+ lc.len = nla_len(info->attrs[NLBL_UNLABEL_A_SECCTX]);
+ ret_val = security_secctx_to_secid(&lc, &le);
if (ret_val != 0)
return ret_val;
@@ -945,6 +945,7 @@ static int netlbl_unlabel_staticadddef(struct sk_buff *skb,
void *mask;
u32 addr_len;
struct lsm_export le;
+ struct lsm_context lc;
struct netlbl_audit audit_info;
/* Don't allow users to add both IPv4 and IPv6 addresses for a
@@ -963,10 +964,9 @@ static int netlbl_unlabel_staticadddef(struct sk_buff *skb,
ret_val = netlbl_unlabel_addrinfo_get(info, &addr, &mask, &addr_len);
if (ret_val != 0)
return ret_val;
- ret_val = security_secctx_to_secid(
- nla_data(info->attrs[NLBL_UNLABEL_A_SECCTX]),
- nla_len(info->attrs[NLBL_UNLABEL_A_SECCTX]),
- &le);
+ lc.context = nla_data(info->attrs[NLBL_UNLABEL_A_SECCTX]);
+ lc.len = nla_len(info->attrs[NLBL_UNLABEL_A_SECCTX]);
+ ret_val = security_secctx_to_secid(&lc, &le);
if (ret_val != 0)
return ret_val;
diff --git a/security/security.c b/security/security.c
index 4f999cfcf949..44a4402073d7 100644
--- a/security/security.c
+++ b/security/security.c
@@ -1987,15 +1987,10 @@ int security_secid_to_secctx(struct lsm_export *l, char **secdata, u32 *seclen)
}
EXPORT_SYMBOL(security_secid_to_secctx);
-int security_secctx_to_secid(const char *secdata, u32 seclen,
- struct lsm_export *l)
+int security_secctx_to_secid(struct lsm_context *cp, struct lsm_export *l)
{
- struct lsm_context lc;
-
- lc.context = (char *)secdata;
- lc.len = seclen;
lsm_export_init(l);
- return call_one_int_hook(secctx_to_secid, 0, &lc, l);
+ return call_one_int_hook(secctx_to_secid, 0, cp, l);
}
EXPORT_SYMBOL(security_secctx_to_secid);
--
2.19.1
^ permalink raw reply related
* [PATCH 40/58] LSM: Use lsm_context in inode_notifysecctx hooks
From: Casey Schaufler @ 2019-06-02 16:50 UTC (permalink / raw)
To: casey.schaufler, jmorris, linux-security-module, selinux
Cc: casey, keescook, john.johansen, penguin-kernel, paul, sds
In-Reply-To: <20190602165101.25079-1-casey@schaufler-ca.com>
Convert SELinux and Smack to use the lsm_context structure
instead of a context/secid pair. There is some scaffolding involved
that will be removed when the related data is updated.
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
---
include/linux/lsm_hooks.h | 5 ++---
security/security.c | 6 +++++-
security/selinux/hooks.c | 5 +++--
security/smack/smack_lsm.c | 5 +++--
4 files changed, 13 insertions(+), 8 deletions(-)
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 20e59e0b775f..eda0a1bcdf07 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -1377,8 +1377,7 @@
* file's attributes to the client.
* Must be called with inode->i_mutex locked.
* @inode we wish to set the security context of.
- * @ctx contains the string which we wish to set in the inode.
- * @ctxlen contains the length of @ctx.
+ * @cp contains the string which we wish to set in the inode.
*
* @inode_setsecctx:
* Change the security context of an inode. Updates the
@@ -1668,7 +1667,7 @@ union security_list_options {
void (*release_secctx)(char *secdata, u32 seclen);
void (*inode_invalidate_secctx)(struct inode *inode);
- int (*inode_notifysecctx)(struct inode *inode, void *ctx, u32 ctxlen);
+ int (*inode_notifysecctx)(struct inode *inode, struct lsm_context *cp);
int (*inode_setsecctx)(struct dentry *dentry, void *ctx, u32 ctxlen);
int (*inode_getsecctx)(struct inode *inode, struct lsm_context *cp);
diff --git a/security/security.c b/security/security.c
index 0c23ffdd92c9..4f443dd481bd 100644
--- a/security/security.c
+++ b/security/security.c
@@ -2013,7 +2013,11 @@ EXPORT_SYMBOL(security_inode_invalidate_secctx);
int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen)
{
- return call_int_hook(inode_notifysecctx, 0, inode, ctx, ctxlen);
+ struct lsm_context lc;
+
+ lc.context = ctx;
+ lc.len = ctxlen;
+ return call_int_hook(inode_notifysecctx, 0, inode, &lc);
}
EXPORT_SYMBOL(security_inode_notifysecctx);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index e881f42d3ff8..633d62b97e90 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -6339,10 +6339,11 @@ static void selinux_inode_invalidate_secctx(struct inode *inode)
/*
* called with inode->i_mutex locked
*/
-static int selinux_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen)
+static int selinux_inode_notifysecctx(struct inode *inode,
+ struct lsm_context *cp)
{
int rc = selinux_inode_setsecurity(inode, XATTR_SELINUX_SUFFIX,
- ctx, ctxlen, 0);
+ cp->context, cp->len, 0);
/* Do not return error when suppressing label (SBLABEL_MNT not set). */
return rc == -EOPNOTSUPP ? 0 : rc;
}
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 46eead699e1d..3d24503029e5 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -4474,9 +4474,10 @@ static void smack_release_secctx(char *secdata, u32 seclen)
{
}
-static int smack_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen)
+static int smack_inode_notifysecctx(struct inode *inode, struct lsm_context *cp)
{
- return smack_inode_setsecurity(inode, XATTR_SMACK_SUFFIX, ctx, ctxlen, 0);
+ return smack_inode_setsecurity(inode, XATTR_SMACK_SUFFIX, cp->context,
+ cp->len, 0);
}
static int smack_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
--
2.19.1
^ permalink raw reply related
* [PATCH 43/58] LSM: Use lsm_context in security_inode_notifysecctx
From: Casey Schaufler @ 2019-06-02 16:50 UTC (permalink / raw)
To: casey.schaufler, jmorris, linux-security-module, selinux
Cc: casey, keescook, john.johansen, penguin-kernel, paul, sds
In-Reply-To: <20190602165101.25079-1-casey@schaufler-ca.com>
Convert security_inode_notifysecctx to use the lsm_context structure
instead of a context/secid pair. There is some scaffolding involved
that will be removed when the related data is updated.
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
---
fs/kernfs/inode.c | 6 ++++--
fs/nfs/inode.c | 6 ++++--
include/linux/security.h | 5 +++--
security/security.c | 8 ++------
4 files changed, 13 insertions(+), 12 deletions(-)
diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c
index 0c1fd945ce42..460e611b1938 100644
--- a/fs/kernfs/inode.c
+++ b/fs/kernfs/inode.c
@@ -184,6 +184,7 @@ static inline void set_inode_attr(struct inode *inode, struct iattr *iattr)
static void kernfs_refresh_inode(struct kernfs_node *kn, struct inode *inode)
{
struct kernfs_iattrs *attrs = kn->iattr;
+ struct lsm_context lc; /* Scaffolding -Casey */
inode->i_mode = kn->mode;
if (attrs) {
@@ -192,8 +193,9 @@ static void kernfs_refresh_inode(struct kernfs_node *kn, struct inode *inode)
* persistent copy in kernfs_node.
*/
set_inode_attr(inode, &attrs->ia_iattr);
- security_inode_notifysecctx(inode, attrs->ia_secdata,
- attrs->ia_secdata_len);
+ lc.context = attrs->ia_secdata;
+ lc.len = attrs->ia_secdata_len;
+ security_inode_notifysecctx(inode, &lc);
}
if (kernfs_type(kn) == KERNFS_DIR)
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 414a90d48493..8d0be9767b14 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -340,14 +340,16 @@ static void nfs_clear_label_invalid(struct inode *inode)
void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr,
struct nfs4_label *label)
{
+ struct lsm_context lc; /* Scaffolding -Casey */
int error;
if (label == NULL)
return;
if ((fattr->valid & NFS_ATTR_FATTR_V4_SECURITY_LABEL) && inode->i_security) {
- error = security_inode_notifysecctx(inode, label->label,
- label->len);
+ lc.context = label->label;
+ lc.len = label->len;
+ error = security_inode_notifysecctx(inode, &lc);
if (error)
printk(KERN_ERR "%s() %s %d "
"security_inode_notifysecctx() %d\n",
diff --git a/include/linux/security.h b/include/linux/security.h
index 6c3a74a44a59..6b2fcca08a43 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -437,7 +437,7 @@ int security_secctx_to_secid(const char *secdata, u32 seclen,
void security_release_secctx(char *secdata, u32 seclen);
void security_inode_invalidate_secctx(struct inode *inode);
-int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen);
+int security_inode_notifysecctx(struct inode *inode, struct lsm_context *cp);
int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen);
int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen);
#else /* CONFIG_SECURITY */
@@ -1232,7 +1232,8 @@ static inline void security_inode_invalidate_secctx(struct inode *inode)
{
}
-static inline int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen)
+static inline int security_inode_notifysecctx(struct inode *inode,
+ struct lsm_context *cp);
{
return -EOPNOTSUPP;
}
diff --git a/security/security.c b/security/security.c
index 628287180ce7..74f211d58e5f 100644
--- a/security/security.c
+++ b/security/security.c
@@ -2011,13 +2011,9 @@ void security_inode_invalidate_secctx(struct inode *inode)
}
EXPORT_SYMBOL(security_inode_invalidate_secctx);
-int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen)
+int security_inode_notifysecctx(struct inode *inode, struct lsm_context *cp)
{
- struct lsm_context lc;
-
- lc.context = ctx;
- lc.len = ctxlen;
- return call_int_hook(inode_notifysecctx, 0, inode, &lc);
+ return call_int_hook(inode_notifysecctx, 0, inode, cp);
}
EXPORT_SYMBOL(security_inode_notifysecctx);
--
2.19.1
^ permalink raw reply related
* [PATCH 42/58] LSM: Use lsm_context in security_dentry_init_security
From: Casey Schaufler @ 2019-06-02 16:50 UTC (permalink / raw)
To: casey.schaufler, jmorris, linux-security-module, selinux
Cc: casey, keescook, john.johansen, penguin-kernel, paul, sds
In-Reply-To: <20190602165101.25079-1-casey@schaufler-ca.com>
From: Casey Schaufler <cschaufler@schaufler-ca.com>
Convert security_dentry_init_security to use the lsm_context structure
instead of a context/secid pair. There is some scaffolding involved
that will be removed when the related data is updated.
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
---
fs/nfs/nfs4proc.c | 5 ++++-
include/linux/security.h | 7 +++----
security/security.c | 14 ++++----------
3 files changed, 11 insertions(+), 15 deletions(-)
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 4dbb0ee23432..de000649f9f3 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -113,6 +113,7 @@ static inline struct nfs4_label *
nfs4_label_init_security(struct inode *dir, struct dentry *dentry,
struct iattr *sattr, struct nfs4_label *label)
{
+ struct lsm_context lc; /* Scaffolding -Casey */
int err;
if (label == NULL)
@@ -122,7 +123,9 @@ nfs4_label_init_security(struct inode *dir, struct dentry *dentry,
return NULL;
err = security_dentry_init_security(dentry, sattr->ia_mode,
- &dentry->d_name, (void **)&label->label, &label->len);
+ &dentry->d_name, &lc);
+ label->label = lc.context;
+ label->len = lc.len;
if (err == 0)
return label;
diff --git a/include/linux/security.h b/include/linux/security.h
index e12b169deed6..6c3a74a44a59 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -302,8 +302,8 @@ int security_sb_clone_mnt_opts(const struct super_block *oldsb,
int security_add_mnt_opt(const char *option, const char *val,
int len, void **mnt_opts);
int security_dentry_init_security(struct dentry *dentry, int mode,
- const struct qstr *name, void **ctx,
- u32 *ctxlen);
+ const struct qstr *name,
+ struct lsm_context *cp);
int security_dentry_create_files_as(struct dentry *dentry, int mode,
struct qstr *name,
const struct cred *old,
@@ -674,8 +674,7 @@ static inline void security_inode_free(struct inode *inode)
static inline int security_dentry_init_security(struct dentry *dentry,
int mode,
const struct qstr *name,
- void **ctx,
- u32 *ctxlen)
+ struct lsm_context *cp)
{
return -EOPNOTSUPP;
}
diff --git a/security/security.c b/security/security.c
index c04b334370a5..628287180ce7 100644
--- a/security/security.c
+++ b/security/security.c
@@ -1014,17 +1014,11 @@ void security_inode_free(struct inode *inode)
}
int security_dentry_init_security(struct dentry *dentry, int mode,
- const struct qstr *name, void **ctx,
- u32 *ctxlen)
+ const struct qstr *name,
+ struct lsm_context *cp)
{
- struct lsm_context lc = { .context = NULL, .len = 0, };
- int rc;
-
- rc = call_int_hook(dentry_init_security, -EOPNOTSUPP, dentry, mode,
- name, &lc);
- *ctx = (void *)lc.context;
- *ctxlen = lc.len;
- return rc;
+ return call_int_hook(dentry_init_security, -EOPNOTSUPP, dentry, mode,
+ name, cp);
}
EXPORT_SYMBOL(security_dentry_init_security);
--
2.19.1
^ permalink raw reply related
* [PATCH 41/58] LSM: Use lsm_context in dentry_init_security hooks
From: Casey Schaufler @ 2019-06-02 16:50 UTC (permalink / raw)
To: casey.schaufler, jmorris, linux-security-module, selinux
Cc: casey, keescook, john.johansen, penguin-kernel, paul, sds
In-Reply-To: <20190602165101.25079-1-casey@schaufler-ca.com>
From: Casey Schaufler <cschaufler@schaufler-ca.com>
Convert SELinux to use the lsm_context structure
instead of a context/secid pair. There is some scaffolding involved
that will be removed when the related data is updated.
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
---
include/linux/lsm_hooks.h | 7 +++----
security/security.c | 10 ++++++++--
security/selinux/hooks.c | 8 ++++----
3 files changed, 15 insertions(+), 10 deletions(-)
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index eda0a1bcdf07..d4ace7af4950 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -165,8 +165,7 @@
* @dentry dentry to use in calculating the context.
* @mode mode used to determine resource type.
* @name name of the last path component used to create file
- * @ctx pointer to place the pointer to the resulting context in.
- * @ctxlen point to place the length of the resulting context.
+ * @cp pointer to place the pointer to the resulting context in.
* @dentry_create_files_as:
* Compute a context for a dentry as the inode is not yet available
* and set that context in passed in creds so that new files are
@@ -1492,8 +1491,8 @@ union security_list_options {
int (*sb_add_mnt_opt)(const char *option, const char *val, int len,
void **mnt_opts);
int (*dentry_init_security)(struct dentry *dentry, int mode,
- const struct qstr *name, void **ctx,
- u32 *ctxlen);
+ const struct qstr *name,
+ struct lsm_context *cp);
int (*dentry_create_files_as)(struct dentry *dentry, int mode,
struct qstr *name,
const struct cred *old,
diff --git a/security/security.c b/security/security.c
index 4f443dd481bd..c04b334370a5 100644
--- a/security/security.c
+++ b/security/security.c
@@ -1017,8 +1017,14 @@ int security_dentry_init_security(struct dentry *dentry, int mode,
const struct qstr *name, void **ctx,
u32 *ctxlen)
{
- return call_int_hook(dentry_init_security, -EOPNOTSUPP, dentry, mode,
- name, ctx, ctxlen);
+ struct lsm_context lc = { .context = NULL, .len = 0, };
+ int rc;
+
+ rc = call_int_hook(dentry_init_security, -EOPNOTSUPP, dentry, mode,
+ name, &lc);
+ *ctx = (void *)lc.context;
+ *ctxlen = lc.len;
+ return rc;
}
EXPORT_SYMBOL(security_dentry_init_security);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 633d62b97e90..fe09905d013c 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2813,8 +2813,8 @@ static void selinux_inode_free_security(struct inode *inode)
}
static int selinux_dentry_init_security(struct dentry *dentry, int mode,
- const struct qstr *name, void **ctx,
- u32 *ctxlen)
+ const struct qstr *name,
+ struct lsm_context *cp)
{
u32 newsid;
int rc;
@@ -2826,8 +2826,8 @@ static int selinux_dentry_init_security(struct dentry *dentry, int mode,
if (rc)
return rc;
- return security_sid_to_context(&selinux_state, newsid, (char **)ctx,
- ctxlen);
+ return security_sid_to_context(&selinux_state, newsid, &cp->context,
+ &cp->len);
}
static int selinux_dentry_create_files_as(struct dentry *dentry, int mode,
--
2.19.1
^ permalink raw reply related
* [PATCH 39/58] LSM: Use lsm_context in inode_getsecctx hooks
From: Casey Schaufler @ 2019-06-02 16:50 UTC (permalink / raw)
To: casey.schaufler, jmorris, linux-security-module, selinux
Cc: casey, keescook, john.johansen, penguin-kernel, paul, sds
In-Reply-To: <20190602165101.25079-1-casey@schaufler-ca.com>
Convert SELinux and Smack to use the lsm_context structure
instead of a context/secid pair. There is some scaffolding involved
that will be removed when the related data is updated.
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
---
include/linux/lsm_hooks.h | 7 +++----
security/security.c | 11 +++++++++--
security/selinux/hooks.c | 6 +++---
security/smack/smack_lsm.c | 6 +++---
4 files changed, 18 insertions(+), 12 deletions(-)
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index c983d573a005..20e59e0b775f 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -1394,11 +1394,10 @@
* @ctxlen contains the length of @ctx.
*
* @inode_getsecctx:
- * On success, returns 0 and fills out @ctx and @ctxlen with the security
+ * On success, returns 0 and fills out @cp with the security
* context for the given @inode.
* @inode we wish to get the security context of.
- * @ctx is a pointer in which to place the allocated security context.
- * @ctxlen points to the place to put the length of @ctx.
+ * @cp is a pointer in which to place the allocated security context.
*
* Security hooks for using the eBPF maps and programs functionalities through
* eBPF syscalls.
@@ -1671,7 +1670,7 @@ union security_list_options {
void (*inode_invalidate_secctx)(struct inode *inode);
int (*inode_notifysecctx)(struct inode *inode, void *ctx, u32 ctxlen);
int (*inode_setsecctx)(struct dentry *dentry, void *ctx, u32 ctxlen);
- int (*inode_getsecctx)(struct inode *inode, void **ctx, u32 *ctxlen);
+ int (*inode_getsecctx)(struct inode *inode, struct lsm_context *cp);
#ifdef CONFIG_SECURITY_NETWORK
int (*unix_stream_connect)(struct sock *sock, struct sock *other,
diff --git a/security/security.c b/security/security.c
index 84f27428b62d..0c23ffdd92c9 100644
--- a/security/security.c
+++ b/security/security.c
@@ -1992,7 +1992,7 @@ int security_secctx_to_secid(const char *secdata, u32 seclen,
{
struct lsm_context lc;
- lc.context = secdata;
+ lc.context = (char *)secdata;
lc.len = seclen;
lsm_export_init(l);
return call_one_int_hook(secctx_to_secid, 0, &lc, l);
@@ -2025,7 +2025,14 @@ EXPORT_SYMBOL(security_inode_setsecctx);
int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
{
- return call_int_hook(inode_getsecctx, -EOPNOTSUPP, inode, ctx, ctxlen);
+ struct lsm_context lc = { .context = NULL, .len = 0, };
+ int rc;
+
+ rc = call_int_hook(inode_getsecctx, -EOPNOTSUPP, inode, &lc);
+
+ *ctx = (void *)lc.context;
+ *ctxlen = lc.len;
+ return rc;
}
EXPORT_SYMBOL(security_inode_getsecctx);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index a2257ccaee5c..e881f42d3ff8 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -6355,14 +6355,14 @@ static int selinux_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
return __vfs_setxattr_noperm(dentry, XATTR_NAME_SELINUX, ctx, ctxlen, 0);
}
-static int selinux_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
+static int selinux_inode_getsecctx(struct inode *inode, struct lsm_context *cp)
{
int len = 0;
len = selinux_inode_getsecurity(inode, XATTR_SELINUX_SUFFIX,
- ctx, true);
+ (void **)&cp->context, true);
if (len < 0)
return len;
- *ctxlen = len;
+ cp->len = len;
return 0;
}
#ifdef CONFIG_KEYS
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 78c01ef707eb..46eead699e1d 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -4484,12 +4484,12 @@ static int smack_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
return __vfs_setxattr_noperm(dentry, XATTR_NAME_SMACK, ctx, ctxlen, 0);
}
-static int smack_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
+static int smack_inode_getsecctx(struct inode *inode, struct lsm_context *cp)
{
struct smack_known *skp = smk_of_inode(inode);
- *ctx = skp->smk_known;
- *ctxlen = strlen(skp->smk_known);
+ cp->context = skp->smk_known;
+ cp->len = strlen(skp->smk_known);
return 0;
}
--
2.19.1
^ permalink raw reply related
* [PATCH 38/58] LSM: Use lsm_context in secctx_to_secid hooks
From: Casey Schaufler @ 2019-06-02 16:50 UTC (permalink / raw)
To: casey.schaufler, jmorris, linux-security-module, selinux
Cc: casey, keescook, john.johansen, penguin-kernel, paul, sds
In-Reply-To: <20190602165101.25079-1-casey@schaufler-ca.com>
Convert SELinux, Smack and AppArmor to use the lsm_context structure
instead of a context/secid pair. There is some scaffolding involved
that will be removed when the related data is updated.
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
---
include/linux/lsm_hooks.h | 4 ++--
security/apparmor/include/secid.h | 2 +-
security/apparmor/secid.c | 7 +++----
security/security.c | 6 +++++-
security/selinux/hooks.c | 4 ++--
security/smack/smack_lsm.c | 4 ++--
6 files changed, 15 insertions(+), 12 deletions(-)
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 229899452678..c983d573a005 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -1324,8 +1324,8 @@
* context.
* @secctx_to_secid:
* Convert security context to exported lsm data.
+ * @cp contains the security context.
* @l contains the pointer to the generated security data.
- * @secdata contains the security context.
*
* @release_secctx:
* Release the security context.
@@ -1664,7 +1664,7 @@ union security_list_options {
int (*setprocattr)(const char *name, void *value, size_t size);
int (*ismaclabel)(const char *name);
int (*secid_to_secctx)(struct lsm_export *l, struct lsm_context *cp);
- int (*secctx_to_secid)(const char *secdata, u32 seclen,
+ int (*secctx_to_secid)(const struct lsm_context *cp,
struct lsm_export *l);
void (*release_secctx)(char *secdata, u32 seclen);
diff --git a/security/apparmor/include/secid.h b/security/apparmor/include/secid.h
index 964d3dc92635..acfcf99bff0e 100644
--- a/security/apparmor/include/secid.h
+++ b/security/apparmor/include/secid.h
@@ -27,7 +27,7 @@ struct aa_label;
struct aa_label *aa_secid_to_label(struct lsm_export *l);
int apparmor_secid_to_secctx(struct lsm_export *l, struct lsm_context *cp);
-int apparmor_secctx_to_secid(const char *secdata, u32 seclen,
+int apparmor_secctx_to_secid(const struct lsm_context *cp,
struct lsm_export *l);
void apparmor_release_secctx(char *secdata, u32 seclen);
diff --git a/security/apparmor/secid.c b/security/apparmor/secid.c
index 4e11434605d6..35df38592b6e 100644
--- a/security/apparmor/secid.c
+++ b/security/apparmor/secid.c
@@ -110,13 +110,12 @@ int apparmor_secid_to_secctx(struct lsm_export *l, struct lsm_context *cp)
return 0;
}
-int apparmor_secctx_to_secid(const char *secdata, u32 seclen,
- struct lsm_export *l)
+int apparmor_secctx_to_secid(const struct lsm_context *cp, struct lsm_export *l)
{
struct aa_label *label;
- label = aa_label_strn_parse(&root_ns->unconfined->label, secdata,
- seclen, GFP_KERNEL, false, false);
+ label = aa_label_strn_parse(&root_ns->unconfined->label, cp->context,
+ cp->len, GFP_KERNEL, false, false);
if (IS_ERR(label))
return PTR_ERR(label);
aa_export_secid(l, label->secid);
diff --git a/security/security.c b/security/security.c
index ac0498daa49e..84f27428b62d 100644
--- a/security/security.c
+++ b/security/security.c
@@ -1990,8 +1990,12 @@ EXPORT_SYMBOL(security_secid_to_secctx);
int security_secctx_to_secid(const char *secdata, u32 seclen,
struct lsm_export *l)
{
+ struct lsm_context lc;
+
+ lc.context = secdata;
+ lc.len = seclen;
lsm_export_init(l);
- return call_one_int_hook(secctx_to_secid, 0, secdata, seclen, l);
+ return call_one_int_hook(secctx_to_secid, 0, &lc, l);
}
EXPORT_SYMBOL(security_secctx_to_secid);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 6a2a82dcd948..a2257ccaee5c 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -6310,13 +6310,13 @@ static int selinux_secid_to_secctx(struct lsm_export *l, struct lsm_context *cp)
&cp->context, &cp->len);
}
-static int selinux_secctx_to_secid(const char *secdata, u32 seclen,
+static int selinux_secctx_to_secid(const struct lsm_context *cp,
struct lsm_export *l)
{
u32 secid;
int rc;
- rc = security_context_to_sid(&selinux_state, secdata, seclen,
+ rc = security_context_to_sid(&selinux_state, cp->context, cp->len,
&secid, GFP_KERNEL);
selinux_export_secid(l, secid);
return rc;
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 10d6c6a1a001..78c01ef707eb 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -4455,10 +4455,10 @@ static int smack_secid_to_secctx(struct lsm_export *l, struct lsm_context *cp)
*
* Exists for audit and networking code.
*/
-static int smack_secctx_to_secid(const char *secdata, u32 seclen,
+static int smack_secctx_to_secid(const struct lsm_context *cp,
struct lsm_export *l)
{
- struct smack_known *skp = smk_find_entry(secdata);
+ struct smack_known *skp = smk_find_entry(cp->context);
if (skp)
smack_export_secid(l, skp->smk_secid);
--
2.19.1
^ permalink raw reply related
* [PATCH 36/58] LSM: Create a data structure for a security context
From: Casey Schaufler @ 2019-06-02 16:50 UTC (permalink / raw)
To: casey.schaufler, jmorris, linux-security-module, selinux
Cc: casey, keescook, john.johansen, penguin-kernel, paul, sds
In-Reply-To: <20190602165101.25079-1-casey@schaufler-ca.com>
A "security context" is the text representation of
the information used by LSMs. This provides a structure
so that the use can be made consistant.
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
---
include/linux/security.h | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/include/linux/security.h b/include/linux/security.h
index dde36e850cf0..e12b169deed6 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -116,6 +116,17 @@ static inline bool lsm_export_equal(struct lsm_export *l, struct lsm_export *m)
return true;
}
+/* Text representation of LSM specific security information - a "context" */
+struct lsm_context {
+ char *context;
+ u32 len;
+};
+
+static inline void lsm_context_init(struct lsm_context *cp)
+{
+ memset(cp, 0, sizeof(*cp));
+}
+
/* These functions are in security/commoncap.c */
extern int cap_capable(const struct cred *cred, struct user_namespace *ns,
int cap, unsigned int opts);
--
2.19.1
^ permalink raw reply related
* [PATCH 37/58] LSM: Use lsm_context in secid_to_secctx hooks
From: Casey Schaufler @ 2019-06-02 16:50 UTC (permalink / raw)
To: casey.schaufler, jmorris, linux-security-module, selinux
Cc: casey, keescook, john.johansen, penguin-kernel, paul, sds
In-Reply-To: <20190602165101.25079-1-casey@schaufler-ca.com>
Convert SELinux, Smack and AppArmor to use the lsm_context structure
instead of a context/secid pair. There is some scaffolding involved
that will be removed when the related data is updated.
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
---
include/linux/lsm_hooks.h | 6 ++----
security/apparmor/include/secid.h | 2 +-
security/apparmor/secid.c | 11 +++++------
security/security.c | 12 ++++++++++--
security/selinux/hooks.c | 5 ++---
security/smack/smack_lsm.c | 8 +++-----
6 files changed, 23 insertions(+), 21 deletions(-)
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 0837c214cc17..229899452678 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -1320,9 +1320,8 @@
* length and the next call which actually allocates and returns the
* secdata.
* @l points to the security information.
- * @secdata contains the pointer that stores the converted security
+ * @cp contains the pointer that stores the converted security
* context.
- * @seclen pointer which contains the length of the data
* @secctx_to_secid:
* Convert security context to exported lsm data.
* @l contains the pointer to the generated security data.
@@ -1664,8 +1663,7 @@ union security_list_options {
int (*getprocattr)(struct task_struct *p, char *name, char **value);
int (*setprocattr)(const char *name, void *value, size_t size);
int (*ismaclabel)(const char *name);
- int (*secid_to_secctx)(struct lsm_export *l, char **secdata,
- u32 *seclen);
+ int (*secid_to_secctx)(struct lsm_export *l, struct lsm_context *cp);
int (*secctx_to_secid)(const char *secdata, u32 seclen,
struct lsm_export *l);
void (*release_secctx)(char *secdata, u32 seclen);
diff --git a/security/apparmor/include/secid.h b/security/apparmor/include/secid.h
index 5381eff03d4f..964d3dc92635 100644
--- a/security/apparmor/include/secid.h
+++ b/security/apparmor/include/secid.h
@@ -26,7 +26,7 @@ struct aa_label;
#define AA_SECID_WILDCARD 1
struct aa_label *aa_secid_to_label(struct lsm_export *l);
-int apparmor_secid_to_secctx(struct lsm_export *l, char **secdata, u32 *seclen);
+int apparmor_secid_to_secctx(struct lsm_export *l, struct lsm_context *cp);
int apparmor_secctx_to_secid(const char *secdata, u32 seclen,
struct lsm_export *l);
void apparmor_release_secctx(char *secdata, u32 seclen);
diff --git a/security/apparmor/secid.c b/security/apparmor/secid.c
index 69d98a89db75..4e11434605d6 100644
--- a/security/apparmor/secid.c
+++ b/security/apparmor/secid.c
@@ -81,7 +81,7 @@ static inline void aa_export_secid(struct lsm_export *l, u32 secid)
l->apparmor = secid;
}
-int apparmor_secid_to_secctx(struct lsm_export *l, char **secdata, u32 *seclen)
+int apparmor_secid_to_secctx(struct lsm_export *l, struct lsm_context *cp)
{
/* TODO: cache secctx and ref count so we don't have to recreate */
struct aa_label *label;
@@ -89,13 +89,12 @@ int apparmor_secid_to_secctx(struct lsm_export *l, char **secdata, u32 *seclen)
label = aa_secid_to_label(l);
- AA_BUG(!seclen);
-
if (!label)
return -EINVAL;
- if (secdata)
- len = aa_label_asxprint(secdata, root_ns, label,
+ /* scaffolding check - Casey */
+ if (cp)
+ len = aa_label_asxprint(&cp->context, root_ns, label,
FLAG_SHOW_MODE | FLAG_VIEW_SUBNS |
FLAG_HIDDEN_UNCONFINED | FLAG_ABS_ROOT,
GFP_ATOMIC);
@@ -106,7 +105,7 @@ int apparmor_secid_to_secctx(struct lsm_export *l, char **secdata, u32 *seclen)
if (len < 0)
return -ENOMEM;
- *seclen = len;
+ cp->len = len;
return 0;
}
diff --git a/security/security.c b/security/security.c
index 365970f2501d..ac0498daa49e 100644
--- a/security/security.c
+++ b/security/security.c
@@ -1974,8 +1974,16 @@ EXPORT_SYMBOL(security_ismaclabel);
int security_secid_to_secctx(struct lsm_export *l, char **secdata, u32 *seclen)
{
- return call_one_int_hook(secid_to_secctx, -EOPNOTSUPP, l, secdata,
- seclen);
+ struct lsm_context lc = { .context = NULL, .len = 0, };
+ int rc;
+
+ rc = call_one_int_hook(secid_to_secctx, -EOPNOTSUPP, l, &lc);
+ if (secdata)
+ *secdata = lc.context;
+ else
+ security_release_secctx(lc.context, lc.len);
+ *seclen = lc.len;
+ return rc;
}
EXPORT_SYMBOL(security_secid_to_secctx);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 7dd333f133db..6a2a82dcd948 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -6301,14 +6301,13 @@ static int selinux_ismaclabel(const char *name)
return (strcmp(name, XATTR_SELINUX_SUFFIX) == 0);
}
-static int selinux_secid_to_secctx(struct lsm_export *l, char **secdata,
- u32 *seclen)
+static int selinux_secid_to_secctx(struct lsm_export *l, struct lsm_context *cp)
{
u32 secid;
selinux_import_secid(l, &secid);
return security_sid_to_context(&selinux_state, secid,
- secdata, seclen);
+ &cp->context, &cp->len);
}
static int selinux_secctx_to_secid(const char *secdata, u32 seclen,
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index a837af153ed9..10d6c6a1a001 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -4434,8 +4434,7 @@ static int smack_ismaclabel(const char *name)
*
* Exists for networking code.
*/
-static int smack_secid_to_secctx(struct lsm_export *l, char **secdata,
- u32 *seclen)
+static int smack_secid_to_secctx(struct lsm_export *l, struct lsm_context *cp)
{
struct smack_known *skp;
u32 secid;
@@ -4443,9 +4442,8 @@ static int smack_secid_to_secctx(struct lsm_export *l, char **secdata,
smack_import_secid(l, &secid);
skp = smack_from_secid(secid);
- if (secdata)
- *secdata = skp->smk_known;
- *seclen = strlen(skp->smk_known);
+ cp->context = skp->smk_known;
+ cp->len = strlen(skp->smk_known);
return 0;
}
--
2.19.1
^ permalink raw reply related
* [PATCH 33/58] Smack: Restore the release_secctx hook
From: Casey Schaufler @ 2019-06-02 16:50 UTC (permalink / raw)
To: casey.schaufler, jmorris, linux-security-module, selinux
Cc: casey, keescook, john.johansen, penguin-kernel, paul, sds
In-Reply-To: <20190602165101.25079-1-casey@schaufler-ca.com>
The secid_to_secctx() hook has to be balanced with a release_secctx
hook for stacking. This hook does nothing.
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
---
security/smack/smack_lsm.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 38ea48d22547..a837af153ed9 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -4470,10 +4470,11 @@ static int smack_secctx_to_secid(const char *secdata, u32 seclen,
}
/*
- * There used to be a smack_release_secctx hook
- * that did nothing back when hooks were in a vector.
- * Now that there's a list such a hook adds cost.
+ * There smack_release_secctx hook does nothing
*/
+static void smack_release_secctx(char *secdata, u32 seclen)
+{
+}
static int smack_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen)
{
@@ -4713,6 +4714,7 @@ static struct security_hook_list smack_hooks[] __lsm_ro_after_init = {
LSM_HOOK_INIT(ismaclabel, smack_ismaclabel),
LSM_HOOK_INIT(secid_to_secctx, smack_secid_to_secctx),
LSM_HOOK_INIT(secctx_to_secid, smack_secctx_to_secid),
+ LSM_HOOK_INIT(release_secctx, smack_release_secctx),
LSM_HOOK_INIT(inode_notifysecctx, smack_inode_notifysecctx),
LSM_HOOK_INIT(inode_setsecctx, smack_inode_setsecctx),
LSM_HOOK_INIT(inode_getsecctx, smack_inode_getsecctx),
--
2.19.1
^ permalink raw reply related
* [PATCH 35/58] LSM: Limit calls to certain module hooks
From: Casey Schaufler @ 2019-06-02 16:50 UTC (permalink / raw)
To: casey.schaufler, jmorris, linux-security-module, selinux
Cc: casey, keescook, john.johansen, penguin-kernel, paul, sds
In-Reply-To: <20190602165101.25079-1-casey@schaufler-ca.com>
LSM hooks dealing with security context strings should
only be called for one security module. Add call macros
that invoke a single module hook and us in for those cases.
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
---
security/security.c | 32 ++++++++++++++++++++++++++++----
1 file changed, 28 insertions(+), 4 deletions(-)
diff --git a/security/security.c b/security/security.c
index 69983ad68233..365970f2501d 100644
--- a/security/security.c
+++ b/security/security.c
@@ -698,6 +698,16 @@ int lsm_superblock_alloc(struct super_block *sb)
P->hook.FUNC(__VA_ARGS__); \
} while (0)
+#define call_one_void_hook(FUNC, ...) \
+ do { \
+ struct security_hook_list *P; \
+ \
+ hlist_for_each_entry(P, &security_hook_heads.FUNC, list) { \
+ P->hook.FUNC(__VA_ARGS__); \
+ break; \
+ } \
+ } while (0)
+
#define call_int_hook(FUNC, IRC, ...) ({ \
int RC = IRC; \
do { \
@@ -712,6 +722,19 @@ int lsm_superblock_alloc(struct super_block *sb)
RC; \
})
+#define call_one_int_hook(FUNC, IRC, ...) ({ \
+ int RC = IRC; \
+ do { \
+ struct security_hook_list *P; \
+ \
+ hlist_for_each_entry(P, &security_hook_heads.FUNC, list) { \
+ RC = P->hook.FUNC(__VA_ARGS__); \
+ break; \
+ } \
+ } while (0); \
+ RC; \
+})
+
/* Security operations */
int security_binder_set_context_mgr(struct task_struct *mgr)
@@ -1951,7 +1974,8 @@ EXPORT_SYMBOL(security_ismaclabel);
int security_secid_to_secctx(struct lsm_export *l, char **secdata, u32 *seclen)
{
- return call_int_hook(secid_to_secctx, -EOPNOTSUPP, l, secdata, seclen);
+ return call_one_int_hook(secid_to_secctx, -EOPNOTSUPP, l, secdata,
+ seclen);
}
EXPORT_SYMBOL(security_secid_to_secctx);
@@ -1959,13 +1983,13 @@ int security_secctx_to_secid(const char *secdata, u32 seclen,
struct lsm_export *l)
{
lsm_export_init(l);
- return call_int_hook(secctx_to_secid, 0, secdata, seclen, l);
+ return call_one_int_hook(secctx_to_secid, 0, secdata, seclen, l);
}
EXPORT_SYMBOL(security_secctx_to_secid);
void security_release_secctx(char *secdata, u32 seclen)
{
- call_void_hook(release_secctx, secdata, seclen);
+ call_one_void_hook(release_secctx, secdata, seclen);
}
EXPORT_SYMBOL(security_release_secctx);
@@ -2090,7 +2114,7 @@ EXPORT_SYMBOL(security_sock_rcv_skb);
int security_socket_getpeersec_stream(struct socket *sock, char __user *optval,
int __user *optlen, unsigned len)
{
- return call_int_hook(socket_getpeersec_stream, -ENOPROTOOPT, sock,
+ return call_one_int_hook(socket_getpeersec_stream, -ENOPROTOOPT, sock,
optval, optlen, len);
}
--
2.19.1
^ permalink raw reply related
* [PATCH 02/58] LSM: Infrastructure management of the sock security
From: Casey Schaufler @ 2019-06-02 16:50 UTC (permalink / raw)
To: casey.schaufler, jmorris, linux-security-module, selinux
Cc: casey, keescook, john.johansen, penguin-kernel, paul, sds
In-Reply-To: <20190602165101.25079-1-casey@schaufler-ca.com>
Move management of the sock->sk_security blob out
of the individual security modules and into the security
infrastructure. Instead of allocating the blobs from within
the modules the modules tell the infrastructure how much
space is required, and the space is allocated there.
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
---
include/linux/lsm_hooks.h | 1 +
security/apparmor/include/net.h | 6 ++-
security/apparmor/lsm.c | 38 ++++-----------
security/security.c | 36 +++++++++++++-
security/selinux/hooks.c | 78 +++++++++++++++----------------
security/selinux/include/objsec.h | 5 ++
security/selinux/netlabel.c | 23 ++++-----
security/smack/smack.h | 5 ++
security/smack/smack_lsm.c | 64 ++++++++++++-------------
security/smack/smack_netfilter.c | 8 ++--
10 files changed, 144 insertions(+), 120 deletions(-)
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index f9222a04968d..b353482ea348 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -2047,6 +2047,7 @@ struct lsm_blob_sizes {
int lbs_cred;
int lbs_file;
int lbs_inode;
+ int lbs_sock;
int lbs_superblock;
int lbs_ipc;
int lbs_msg_msg;
diff --git a/security/apparmor/include/net.h b/security/apparmor/include/net.h
index 7334ac966d01..adac04e3b3cc 100644
--- a/security/apparmor/include/net.h
+++ b/security/apparmor/include/net.h
@@ -55,7 +55,11 @@ struct aa_sk_ctx {
struct aa_label *peer;
};
-#define SK_CTX(X) ((X)->sk_security)
+static inline struct aa_sk_ctx *aa_sock(const struct sock *sk)
+{
+ return sk->sk_security + apparmor_blob_sizes.lbs_sock;
+}
+
#define SOCK_ctx(X) SOCK_INODE(X)->i_security
#define DEFINE_AUDIT_NET(NAME, OP, SK, F, T, P) \
struct lsm_network_audit NAME ## _net = { .sk = (SK), \
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index 49d664ddff44..2716e7731279 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -757,33 +757,15 @@ static int apparmor_task_kill(struct task_struct *target, struct kernel_siginfo
return error;
}
-/**
- * apparmor_sk_alloc_security - allocate and attach the sk_security field
- */
-static int apparmor_sk_alloc_security(struct sock *sk, int family, gfp_t flags)
-{
- struct aa_sk_ctx *ctx;
-
- ctx = kzalloc(sizeof(*ctx), flags);
- if (!ctx)
- return -ENOMEM;
-
- SK_CTX(sk) = ctx;
-
- return 0;
-}
-
/**
* apparmor_sk_free_security - free the sk_security field
*/
static void apparmor_sk_free_security(struct sock *sk)
{
- struct aa_sk_ctx *ctx = SK_CTX(sk);
+ struct aa_sk_ctx *ctx = aa_sock(sk);
- SK_CTX(sk) = NULL;
aa_put_label(ctx->label);
aa_put_label(ctx->peer);
- kfree(ctx);
}
/**
@@ -792,8 +774,8 @@ static void apparmor_sk_free_security(struct sock *sk)
static void apparmor_sk_clone_security(const struct sock *sk,
struct sock *newsk)
{
- struct aa_sk_ctx *ctx = SK_CTX(sk);
- struct aa_sk_ctx *new = SK_CTX(newsk);
+ struct aa_sk_ctx *ctx = aa_sock(sk);
+ struct aa_sk_ctx *new = aa_sock(newsk);
new->label = aa_get_label(ctx->label);
new->peer = aa_get_label(ctx->peer);
@@ -844,7 +826,7 @@ static int apparmor_socket_post_create(struct socket *sock, int family,
label = aa_get_current_label();
if (sock->sk) {
- struct aa_sk_ctx *ctx = SK_CTX(sock->sk);
+ struct aa_sk_ctx *ctx = aa_sock(sock->sk);
aa_put_label(ctx->label);
ctx->label = aa_get_label(label);
@@ -1029,7 +1011,7 @@ static int apparmor_socket_shutdown(struct socket *sock, int how)
*/
static int apparmor_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
{
- struct aa_sk_ctx *ctx = SK_CTX(sk);
+ struct aa_sk_ctx *ctx = aa_sock(sk);
if (!skb->secmark)
return 0;
@@ -1042,7 +1024,7 @@ static int apparmor_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
static struct aa_label *sk_peer_label(struct sock *sk)
{
- struct aa_sk_ctx *ctx = SK_CTX(sk);
+ struct aa_sk_ctx *ctx = aa_sock(sk);
if (ctx->peer)
return ctx->peer;
@@ -1126,7 +1108,7 @@ static int apparmor_socket_getpeersec_dgram(struct socket *sock,
*/
static void apparmor_sock_graft(struct sock *sk, struct socket *parent)
{
- struct aa_sk_ctx *ctx = SK_CTX(sk);
+ struct aa_sk_ctx *ctx = aa_sock(sk);
if (!ctx->label)
ctx->label = aa_get_current_label();
@@ -1136,7 +1118,7 @@ static void apparmor_sock_graft(struct sock *sk, struct socket *parent)
static int apparmor_inet_conn_request(struct sock *sk, struct sk_buff *skb,
struct request_sock *req)
{
- struct aa_sk_ctx *ctx = SK_CTX(sk);
+ struct aa_sk_ctx *ctx = aa_sock(sk);
if (!skb->secmark)
return 0;
@@ -1153,6 +1135,7 @@ struct lsm_blob_sizes apparmor_blob_sizes __lsm_ro_after_init = {
.lbs_cred = sizeof(struct aa_task_ctx *),
.lbs_file = sizeof(struct aa_file_ctx),
.lbs_task = sizeof(struct aa_task_ctx),
+ .lbs_sock = sizeof(struct aa_sk_ctx),
};
static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = {
@@ -1189,7 +1172,6 @@ static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = {
LSM_HOOK_INIT(getprocattr, apparmor_getprocattr),
LSM_HOOK_INIT(setprocattr, apparmor_setprocattr),
- LSM_HOOK_INIT(sk_alloc_security, apparmor_sk_alloc_security),
LSM_HOOK_INIT(sk_free_security, apparmor_sk_free_security),
LSM_HOOK_INIT(sk_clone_security, apparmor_sk_clone_security),
@@ -1581,7 +1563,7 @@ static unsigned int apparmor_ip_postroute(void *priv,
if (sk == NULL)
return NF_ACCEPT;
- ctx = SK_CTX(sk);
+ ctx = aa_sock(sk);
if (!apparmor_secmark_check(ctx->label, OP_SENDMSG, AA_MAY_SEND,
skb->secmark, sk))
return NF_ACCEPT;
diff --git a/security/security.c b/security/security.c
index 550988a0f024..e32b7180282e 100644
--- a/security/security.c
+++ b/security/security.c
@@ -32,6 +32,7 @@
#include <linux/string.h>
#include <linux/msg.h>
#include <net/flow.h>
+#include <net/sock.h>
#define MAX_LSM_EVM_XATTR 2
@@ -172,6 +173,7 @@ static void __init lsm_set_blob_sizes(struct lsm_blob_sizes *needed)
lsm_set_blob_size(&needed->lbs_inode, &blob_sizes.lbs_inode);
lsm_set_blob_size(&needed->lbs_ipc, &blob_sizes.lbs_ipc);
lsm_set_blob_size(&needed->lbs_msg_msg, &blob_sizes.lbs_msg_msg);
+ lsm_set_blob_size(&needed->lbs_sock, &blob_sizes.lbs_sock);
lsm_set_blob_size(&needed->lbs_superblock, &blob_sizes.lbs_superblock);
lsm_set_blob_size(&needed->lbs_task, &blob_sizes.lbs_task);
}
@@ -306,6 +308,7 @@ static void __init ordered_lsm_init(void)
init_debug("inode blob size = %d\n", blob_sizes.lbs_inode);
init_debug("ipc blob size = %d\n", blob_sizes.lbs_ipc);
init_debug("msg_msg blob size = %d\n", blob_sizes.lbs_msg_msg);
+ init_debug("sock blob size = %d\n", blob_sizes.lbs_sock);
init_debug("superblock blob size = %d\n", blob_sizes.lbs_superblock);
init_debug("task blob size = %d\n", blob_sizes.lbs_task);
@@ -605,6 +608,28 @@ static void __init lsm_early_task(struct task_struct *task)
panic("%s: Early task alloc failed.\n", __func__);
}
+/**
+ * lsm_sock_alloc - allocate a composite sock blob
+ * @sock: the sock that needs a blob
+ * @priority: allocation mode
+ *
+ * Allocate the sock blob for all the modules
+ *
+ * Returns 0, or -ENOMEM if memory can't be allocated.
+ */
+int lsm_sock_alloc(struct sock *sock, gfp_t priority)
+{
+ if (blob_sizes.lbs_sock == 0) {
+ sock->sk_security = NULL;
+ return 0;
+ }
+
+ sock->sk_security = kzalloc(blob_sizes.lbs_sock, priority);
+ if (sock->sk_security == NULL)
+ return -ENOMEM;
+ return 0;
+}
+
/**
* lsm_superblock_alloc - allocate a composite superblock blob
* @sb: the superblock that needs a blob
@@ -2048,12 +2073,21 @@ EXPORT_SYMBOL(security_socket_getpeersec_dgram);
int security_sk_alloc(struct sock *sk, int family, gfp_t priority)
{
- return call_int_hook(sk_alloc_security, 0, sk, family, priority);
+ int rc = lsm_sock_alloc(sk, priority);
+
+ if (unlikely(rc))
+ return rc;
+ rc = call_int_hook(sk_alloc_security, 0, sk, family, priority);
+ if (unlikely(rc))
+ security_sk_free(sk);
+ return rc;
}
void security_sk_free(struct sock *sk)
{
call_void_hook(sk_free_security, sk);
+ kfree(sk->sk_security);
+ sk->sk_security = NULL;
}
void security_sk_clone(const struct sock *sk, struct sock *newsk)
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 7478d8eda00a..f38a6f484613 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -4319,7 +4319,7 @@ static int socket_sockcreate_sid(const struct task_security_struct *tsec,
static int sock_has_perm(struct sock *sk, u32 perms)
{
- struct sk_security_struct *sksec = sk->sk_security;
+ struct sk_security_struct *sksec = selinux_sock(sk);
struct common_audit_data ad;
struct lsm_network_audit net = {0,};
@@ -4376,7 +4376,7 @@ static int selinux_socket_post_create(struct socket *sock, int family,
isec->initialized = LABEL_INITIALIZED;
if (sock->sk) {
- sksec = sock->sk->sk_security;
+ sksec = selinux_sock(sock->sk);
sksec->sclass = sclass;
sksec->sid = sid;
/* Allows detection of the first association on this socket */
@@ -4392,8 +4392,8 @@ static int selinux_socket_post_create(struct socket *sock, int family,
static int selinux_socket_socketpair(struct socket *socka,
struct socket *sockb)
{
- struct sk_security_struct *sksec_a = socka->sk->sk_security;
- struct sk_security_struct *sksec_b = sockb->sk->sk_security;
+ struct sk_security_struct *sksec_a = selinux_sock(socka->sk);
+ struct sk_security_struct *sksec_b = selinux_sock(sockb->sk);
sksec_a->peer_sid = sksec_b->sid;
sksec_b->peer_sid = sksec_a->sid;
@@ -4408,7 +4408,7 @@ static int selinux_socket_socketpair(struct socket *socka,
static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen)
{
struct sock *sk = sock->sk;
- struct sk_security_struct *sksec = sk->sk_security;
+ struct sk_security_struct *sksec = selinux_sock(sk);
u16 family;
int err;
@@ -4540,7 +4540,7 @@ static int selinux_socket_connect_helper(struct socket *sock,
struct sockaddr *address, int addrlen)
{
struct sock *sk = sock->sk;
- struct sk_security_struct *sksec = sk->sk_security;
+ struct sk_security_struct *sksec = selinux_sock(sk);
int err;
err = sock_has_perm(sk, SOCKET__CONNECT);
@@ -4711,9 +4711,9 @@ static int selinux_socket_unix_stream_connect(struct sock *sock,
struct sock *other,
struct sock *newsk)
{
- struct sk_security_struct *sksec_sock = sock->sk_security;
- struct sk_security_struct *sksec_other = other->sk_security;
- struct sk_security_struct *sksec_new = newsk->sk_security;
+ struct sk_security_struct *sksec_sock = selinux_sock(sock);
+ struct sk_security_struct *sksec_other = selinux_sock(other);
+ struct sk_security_struct *sksec_new = selinux_sock(newsk);
struct common_audit_data ad;
struct lsm_network_audit net = {0,};
int err;
@@ -4745,8 +4745,8 @@ static int selinux_socket_unix_stream_connect(struct sock *sock,
static int selinux_socket_unix_may_send(struct socket *sock,
struct socket *other)
{
- struct sk_security_struct *ssec = sock->sk->sk_security;
- struct sk_security_struct *osec = other->sk->sk_security;
+ struct sk_security_struct *ssec = selinux_sock(sock->sk);
+ struct sk_security_struct *osec = selinux_sock(other->sk);
struct common_audit_data ad;
struct lsm_network_audit net = {0,};
@@ -4788,7 +4788,7 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
u16 family)
{
int err = 0;
- struct sk_security_struct *sksec = sk->sk_security;
+ struct sk_security_struct *sksec = selinux_sock(sk);
u32 sk_sid = sksec->sid;
struct common_audit_data ad;
struct lsm_network_audit net = {0,};
@@ -4821,7 +4821,7 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
{
int err;
- struct sk_security_struct *sksec = sk->sk_security;
+ struct sk_security_struct *sksec = selinux_sock(sk);
u16 family = sk->sk_family;
u32 sk_sid = sksec->sid;
struct common_audit_data ad;
@@ -4889,13 +4889,15 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
return err;
}
-static int selinux_socket_getpeersec_stream(struct socket *sock, char __user *optval,
- int __user *optlen, unsigned len)
+static int selinux_socket_getpeersec_stream(struct socket *sock,
+ __user char *optval,
+ __user int *optlen,
+ unsigned int len)
{
int err = 0;
char *scontext;
u32 scontext_len;
- struct sk_security_struct *sksec = sock->sk->sk_security;
+ struct sk_security_struct *sksec = selinux_sock(sock->sk);
u32 peer_sid = SECSID_NULL;
if (sksec->sclass == SECCLASS_UNIX_STREAM_SOCKET ||
@@ -4955,34 +4957,27 @@ static int selinux_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *
static int selinux_sk_alloc_security(struct sock *sk, int family, gfp_t priority)
{
- struct sk_security_struct *sksec;
-
- sksec = kzalloc(sizeof(*sksec), priority);
- if (!sksec)
- return -ENOMEM;
+ struct sk_security_struct *sksec = selinux_sock(sk);
sksec->peer_sid = SECINITSID_UNLABELED;
sksec->sid = SECINITSID_UNLABELED;
sksec->sclass = SECCLASS_SOCKET;
selinux_netlbl_sk_security_reset(sksec);
- sk->sk_security = sksec;
return 0;
}
static void selinux_sk_free_security(struct sock *sk)
{
- struct sk_security_struct *sksec = sk->sk_security;
+ struct sk_security_struct *sksec = selinux_sock(sk);
- sk->sk_security = NULL;
selinux_netlbl_sk_security_free(sksec);
- kfree(sksec);
}
static void selinux_sk_clone_security(const struct sock *sk, struct sock *newsk)
{
- struct sk_security_struct *sksec = sk->sk_security;
- struct sk_security_struct *newsksec = newsk->sk_security;
+ struct sk_security_struct *sksec = selinux_sock(sk);
+ struct sk_security_struct *newsksec = selinux_sock(newsk);
newsksec->sid = sksec->sid;
newsksec->peer_sid = sksec->peer_sid;
@@ -4996,7 +4991,7 @@ static void selinux_sk_getsecid(struct sock *sk, u32 *secid)
if (!sk)
*secid = SECINITSID_ANY_SOCKET;
else {
- struct sk_security_struct *sksec = sk->sk_security;
+ struct sk_security_struct *sksec = selinux_sock(sk);
*secid = sksec->sid;
}
@@ -5006,7 +5001,7 @@ static void selinux_sock_graft(struct sock *sk, struct socket *parent)
{
struct inode_security_struct *isec =
inode_security_novalidate(SOCK_INODE(parent));
- struct sk_security_struct *sksec = sk->sk_security;
+ struct sk_security_struct *sksec = selinux_sock(sk);
if (sk->sk_family == PF_INET || sk->sk_family == PF_INET6 ||
sk->sk_family == PF_UNIX)
@@ -5021,7 +5016,7 @@ static void selinux_sock_graft(struct sock *sk, struct socket *parent)
static int selinux_sctp_assoc_request(struct sctp_endpoint *ep,
struct sk_buff *skb)
{
- struct sk_security_struct *sksec = ep->base.sk->sk_security;
+ struct sk_security_struct *sksec = selinux_sock(ep->base.sk);
struct common_audit_data ad;
struct lsm_network_audit net = {0,};
u8 peerlbl_active;
@@ -5172,8 +5167,8 @@ static int selinux_sctp_bind_connect(struct sock *sk, int optname,
static void selinux_sctp_sk_clone(struct sctp_endpoint *ep, struct sock *sk,
struct sock *newsk)
{
- struct sk_security_struct *sksec = sk->sk_security;
- struct sk_security_struct *newsksec = newsk->sk_security;
+ struct sk_security_struct *sksec = selinux_sock(sk);
+ struct sk_security_struct *newsksec = selinux_sock(newsk);
/* If policy does not support SECCLASS_SCTP_SOCKET then call
* the non-sctp clone version.
@@ -5190,7 +5185,7 @@ static void selinux_sctp_sk_clone(struct sctp_endpoint *ep, struct sock *sk,
static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb,
struct request_sock *req)
{
- struct sk_security_struct *sksec = sk->sk_security;
+ struct sk_security_struct *sksec = selinux_sock(sk);
int err;
u16 family = req->rsk_ops->family;
u32 connsid;
@@ -5211,7 +5206,7 @@ static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb,
static void selinux_inet_csk_clone(struct sock *newsk,
const struct request_sock *req)
{
- struct sk_security_struct *newsksec = newsk->sk_security;
+ struct sk_security_struct *newsksec = selinux_sock(newsk);
newsksec->sid = req->secid;
newsksec->peer_sid = req->peer_secid;
@@ -5228,7 +5223,7 @@ static void selinux_inet_csk_clone(struct sock *newsk,
static void selinux_inet_conn_established(struct sock *sk, struct sk_buff *skb)
{
u16 family = sk->sk_family;
- struct sk_security_struct *sksec = sk->sk_security;
+ struct sk_security_struct *sksec = selinux_sock(sk);
/* handle mapped IPv4 packets arriving via IPv6 sockets */
if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP))
@@ -5312,7 +5307,7 @@ static int selinux_tun_dev_attach_queue(void *security)
static int selinux_tun_dev_attach(struct sock *sk, void *security)
{
struct tun_security_struct *tunsec = security;
- struct sk_security_struct *sksec = sk->sk_security;
+ struct sk_security_struct *sksec = selinux_sock(sk);
/* we don't currently perform any NetLabel based labeling here and it
* isn't clear that we would want to do so anyway; while we could apply
@@ -5353,7 +5348,7 @@ static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
int err = 0;
u32 perm;
struct nlmsghdr *nlh;
- struct sk_security_struct *sksec = sk->sk_security;
+ struct sk_security_struct *sksec = selinux_sock(sk);
if (skb->len < NLMSG_HDRLEN) {
err = -EINVAL;
@@ -5494,7 +5489,7 @@ static unsigned int selinux_ip_output(struct sk_buff *skb,
return NF_ACCEPT;
/* standard practice, label using the parent socket */
- sksec = sk->sk_security;
+ sksec = selinux_sock(sk);
sid = sksec->sid;
} else
sid = SECINITSID_KERNEL;
@@ -5533,7 +5528,7 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb,
if (sk == NULL)
return NF_ACCEPT;
- sksec = sk->sk_security;
+ sksec = selinux_sock(sk);
ad.type = LSM_AUDIT_DATA_NET;
ad.u.net = &net;
@@ -5625,7 +5620,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb,
u32 skb_sid;
struct sk_security_struct *sksec;
- sksec = sk->sk_security;
+ sksec = selinux_sock(sk);
if (selinux_skb_peerlbl_sid(skb, family, &skb_sid))
return NF_DROP;
/* At this point, if the returned skb peerlbl is SECSID_NULL
@@ -5654,7 +5649,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb,
} else {
/* Locally generated packet, fetch the security label from the
* associated socket. */
- struct sk_security_struct *sksec = sk->sk_security;
+ struct sk_security_struct *sksec = selinux_sock(sk);
peer_sid = sksec->sid;
secmark_perm = PACKET__SEND;
}
@@ -6633,6 +6628,7 @@ struct lsm_blob_sizes selinux_blob_sizes __lsm_ro_after_init = {
.lbs_inode = sizeof(struct inode_security_struct),
.lbs_ipc = sizeof(struct ipc_security_struct),
.lbs_msg_msg = sizeof(struct msg_security_struct),
+ .lbs_sock = sizeof(struct sk_security_struct),
.lbs_superblock = sizeof(struct superblock_security_struct),
};
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h
index d08d7e5d2f93..29f02b8f8f31 100644
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -194,4 +194,9 @@ static inline struct superblock_security_struct *selinux_superblock(
return superblock->s_security + selinux_blob_sizes.lbs_superblock;
}
+static inline struct sk_security_struct *selinux_sock(const struct sock *sock)
+{
+ return sock->sk_security + selinux_blob_sizes.lbs_sock;
+}
+
#endif /* _SELINUX_OBJSEC_H_ */
diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c
index 186e727b737b..c40914a157b7 100644
--- a/security/selinux/netlabel.c
+++ b/security/selinux/netlabel.c
@@ -31,6 +31,7 @@
#include <linux/gfp.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
+#include <linux/lsm_hooks.h>
#include <net/sock.h>
#include <net/netlabel.h>
#include <net/ip.h>
@@ -81,7 +82,7 @@ static int selinux_netlbl_sidlookup_cached(struct sk_buff *skb,
static struct netlbl_lsm_secattr *selinux_netlbl_sock_genattr(struct sock *sk)
{
int rc;
- struct sk_security_struct *sksec = sk->sk_security;
+ struct sk_security_struct *sksec = selinux_sock(sk);
struct netlbl_lsm_secattr *secattr;
if (sksec->nlbl_secattr != NULL)
@@ -114,7 +115,7 @@ static struct netlbl_lsm_secattr *selinux_netlbl_sock_getattr(
const struct sock *sk,
u32 sid)
{
- struct sk_security_struct *sksec = sk->sk_security;
+ struct sk_security_struct *sksec = selinux_sock(sk);
struct netlbl_lsm_secattr *secattr = sksec->nlbl_secattr;
if (secattr == NULL)
@@ -249,7 +250,7 @@ int selinux_netlbl_skbuff_setsid(struct sk_buff *skb,
* being labeled by it's parent socket, if it is just exit */
sk = skb_to_full_sk(skb);
if (sk != NULL) {
- struct sk_security_struct *sksec = sk->sk_security;
+ struct sk_security_struct *sksec = selinux_sock(sk);
if (sksec->nlbl_state != NLBL_REQSKB)
return 0;
@@ -287,7 +288,7 @@ int selinux_netlbl_sctp_assoc_request(struct sctp_endpoint *ep,
{
int rc;
struct netlbl_lsm_secattr secattr;
- struct sk_security_struct *sksec = ep->base.sk->sk_security;
+ struct sk_security_struct *sksec = selinux_sock(ep->base.sk);
struct sockaddr *addr;
struct sockaddr_in addr4;
#if IS_ENABLED(CONFIG_IPV6)
@@ -370,7 +371,7 @@ int selinux_netlbl_inet_conn_request(struct request_sock *req, u16 family)
*/
void selinux_netlbl_inet_csk_clone(struct sock *sk, u16 family)
{
- struct sk_security_struct *sksec = sk->sk_security;
+ struct sk_security_struct *sksec = selinux_sock(sk);
if (family == PF_INET)
sksec->nlbl_state = NLBL_LABELED;
@@ -388,8 +389,8 @@ void selinux_netlbl_inet_csk_clone(struct sock *sk, u16 family)
*/
void selinux_netlbl_sctp_sk_clone(struct sock *sk, struct sock *newsk)
{
- struct sk_security_struct *sksec = sk->sk_security;
- struct sk_security_struct *newsksec = newsk->sk_security;
+ struct sk_security_struct *sksec = selinux_sock(sk);
+ struct sk_security_struct *newsksec = selinux_sock(newsk);
newsksec->nlbl_state = sksec->nlbl_state;
}
@@ -407,7 +408,7 @@ void selinux_netlbl_sctp_sk_clone(struct sock *sk, struct sock *newsk)
int selinux_netlbl_socket_post_create(struct sock *sk, u16 family)
{
int rc;
- struct sk_security_struct *sksec = sk->sk_security;
+ struct sk_security_struct *sksec = selinux_sock(sk);
struct netlbl_lsm_secattr *secattr;
if (family != PF_INET && family != PF_INET6)
@@ -522,7 +523,7 @@ int selinux_netlbl_socket_setsockopt(struct socket *sock,
{
int rc = 0;
struct sock *sk = sock->sk;
- struct sk_security_struct *sksec = sk->sk_security;
+ struct sk_security_struct *sksec = selinux_sock(sk);
struct netlbl_lsm_secattr secattr;
if (selinux_netlbl_option(level, optname) &&
@@ -560,7 +561,7 @@ static int selinux_netlbl_socket_connect_helper(struct sock *sk,
struct sockaddr *addr)
{
int rc;
- struct sk_security_struct *sksec = sk->sk_security;
+ struct sk_security_struct *sksec = selinux_sock(sk);
struct netlbl_lsm_secattr *secattr;
/* connected sockets are allowed to disconnect when the address family
@@ -599,7 +600,7 @@ static int selinux_netlbl_socket_connect_helper(struct sock *sk,
int selinux_netlbl_socket_connect_locked(struct sock *sk,
struct sockaddr *addr)
{
- struct sk_security_struct *sksec = sk->sk_security;
+ struct sk_security_struct *sksec = selinux_sock(sk);
if (sksec->nlbl_state != NLBL_REQSKB &&
sksec->nlbl_state != NLBL_CONNLABELED)
diff --git a/security/smack/smack.h b/security/smack/smack.h
index caecbcba9942..4ac4bf3310d7 100644
--- a/security/smack/smack.h
+++ b/security/smack/smack.h
@@ -375,6 +375,11 @@ static inline struct smack_known **smack_ipc(const struct kern_ipc_perm *ipc)
return ipc->security + smack_blob_sizes.lbs_ipc;
}
+static inline struct socket_smack *smack_sock(const struct sock *sock)
+{
+ return sock->sk_security + smack_blob_sizes.lbs_sock;
+}
+
static inline struct superblock_smack *smack_superblock(
const struct super_block *superblock)
{
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 807eff2ccce9..fd69e1bd841b 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -1439,7 +1439,7 @@ static int smack_inode_getsecurity(struct inode *inode,
if (sock == NULL || sock->sk == NULL)
return -EOPNOTSUPP;
- ssp = sock->sk->sk_security;
+ ssp = smack_sock(sock->sk);
if (strcmp(name, XATTR_SMACK_IPIN) == 0)
isp = ssp->smk_in;
@@ -1821,7 +1821,7 @@ static int smack_file_receive(struct file *file)
if (inode->i_sb->s_magic == SOCKFS_MAGIC) {
sock = SOCKET_I(inode);
- ssp = sock->sk->sk_security;
+ ssp = smack_sock(sock->sk);
tsp = smack_cred(current_cred());
/*
* If the receiving process can't write to the
@@ -2231,11 +2231,7 @@ static void smack_task_to_inode(struct task_struct *p, struct inode *inode)
static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags)
{
struct smack_known *skp = smk_of_current();
- struct socket_smack *ssp;
-
- ssp = kzalloc(sizeof(struct socket_smack), gfp_flags);
- if (ssp == NULL)
- return -ENOMEM;
+ struct socket_smack *ssp = smack_sock(sk);
/*
* Sockets created by kernel threads receive web label.
@@ -2249,11 +2245,10 @@ static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags)
}
ssp->smk_packet = NULL;
- sk->sk_security = ssp;
-
return 0;
}
+#ifdef SMACK_IPV6_PORT_LABELING
/**
* smack_sk_free_security - Free a socket blob
* @sk: the socket
@@ -2262,7 +2257,6 @@ static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags)
*/
static void smack_sk_free_security(struct sock *sk)
{
-#ifdef SMACK_IPV6_PORT_LABELING
struct smk_port_label *spp;
if (sk->sk_family == PF_INET6) {
@@ -2275,9 +2269,8 @@ static void smack_sk_free_security(struct sock *sk)
}
rcu_read_unlock();
}
-#endif
- kfree(sk->sk_security);
}
+#endif
/**
* smack_ipv4host_label - check host based restrictions
@@ -2395,7 +2388,7 @@ static struct smack_known *smack_ipv6host_label(struct sockaddr_in6 *sip)
static int smack_netlabel(struct sock *sk, int labeled)
{
struct smack_known *skp;
- struct socket_smack *ssp = sk->sk_security;
+ struct socket_smack *ssp = smack_sock(sk);
int rc = 0;
/*
@@ -2440,7 +2433,7 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap)
int rc;
int sk_lbl;
struct smack_known *hkp;
- struct socket_smack *ssp = sk->sk_security;
+ struct socket_smack *ssp = smack_sock(sk);
struct smk_audit_info ad;
rcu_read_lock();
@@ -2516,7 +2509,7 @@ static void smk_ipv6_port_label(struct socket *sock, struct sockaddr *address)
{
struct sock *sk = sock->sk;
struct sockaddr_in6 *addr6;
- struct socket_smack *ssp = sock->sk->sk_security;
+ struct socket_smack *ssp = smack_sock(sock->sk);
struct smk_port_label *spp;
unsigned short port = 0;
@@ -2603,7 +2596,7 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address,
int act)
{
struct smk_port_label *spp;
- struct socket_smack *ssp = sk->sk_security;
+ struct socket_smack *ssp = smack_sock(sk);
struct smack_known *skp = NULL;
unsigned short port;
struct smack_known *object;
@@ -2697,7 +2690,7 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
if (sock == NULL || sock->sk == NULL)
return -EOPNOTSUPP;
- ssp = sock->sk->sk_security;
+ ssp = smack_sock(sock->sk);
if (strcmp(name, XATTR_SMACK_IPIN) == 0)
ssp->smk_in = skp;
@@ -2745,7 +2738,7 @@ static int smack_socket_post_create(struct socket *sock, int family,
* Sockets created by kernel threads receive web label.
*/
if (unlikely(current->flags & PF_KTHREAD)) {
- ssp = sock->sk->sk_security;
+ ssp = smack_sock(sock->sk);
ssp->smk_in = &smack_known_web;
ssp->smk_out = &smack_known_web;
}
@@ -2770,8 +2763,8 @@ static int smack_socket_post_create(struct socket *sock, int family,
static int smack_socket_socketpair(struct socket *socka,
struct socket *sockb)
{
- struct socket_smack *asp = socka->sk->sk_security;
- struct socket_smack *bsp = sockb->sk->sk_security;
+ struct socket_smack *asp = smack_sock(socka->sk);
+ struct socket_smack *bsp = smack_sock(sockb->sk);
asp->smk_packet = bsp->smk_out;
bsp->smk_packet = asp->smk_out;
@@ -2825,7 +2818,7 @@ static int smack_socket_connect(struct socket *sock, struct sockaddr *sap,
return 0;
#ifdef SMACK_IPV6_SECMARK_LABELING
- ssp = sock->sk->sk_security;
+ ssp = smack_sock(sock->sk);
#endif
switch (sock->sk->sk_family) {
@@ -3566,9 +3559,9 @@ static int smack_unix_stream_connect(struct sock *sock,
{
struct smack_known *skp;
struct smack_known *okp;
- struct socket_smack *ssp = sock->sk_security;
- struct socket_smack *osp = other->sk_security;
- struct socket_smack *nsp = newsk->sk_security;
+ struct socket_smack *ssp = smack_sock(sock);
+ struct socket_smack *osp = smack_sock(other);
+ struct socket_smack *nsp = smack_sock(newsk);
struct smk_audit_info ad;
int rc = 0;
#ifdef CONFIG_AUDIT
@@ -3614,8 +3607,8 @@ static int smack_unix_stream_connect(struct sock *sock,
*/
static int smack_unix_may_send(struct socket *sock, struct socket *other)
{
- struct socket_smack *ssp = sock->sk->sk_security;
- struct socket_smack *osp = other->sk->sk_security;
+ struct socket_smack *ssp = smack_sock(sock->sk);
+ struct socket_smack *osp = smack_sock(other->sk);
struct smk_audit_info ad;
int rc;
@@ -3652,7 +3645,7 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg,
struct sockaddr_in6 *sap = (struct sockaddr_in6 *) msg->msg_name;
#endif
#ifdef SMACK_IPV6_SECMARK_LABELING
- struct socket_smack *ssp = sock->sk->sk_security;
+ struct socket_smack *ssp = smack_sock(sock->sk);
struct smack_known *rsp;
#endif
int rc = 0;
@@ -3817,7 +3810,7 @@ static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr_in6 *sip)
static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
{
struct netlbl_lsm_secattr secattr;
- struct socket_smack *ssp = sk->sk_security;
+ struct socket_smack *ssp = smack_sock(sk);
struct smack_known *skp = NULL;
int rc = 0;
struct smk_audit_info ad;
@@ -3934,7 +3927,7 @@ static int smack_socket_getpeersec_stream(struct socket *sock,
int slen = 1;
int rc = 0;
- ssp = sock->sk->sk_security;
+ ssp = smack_sock(sock->sk);
if (ssp->smk_packet != NULL) {
rcp = ssp->smk_packet->smk_known;
slen = strlen(rcp) + 1;
@@ -3984,7 +3977,7 @@ static int smack_socket_getpeersec_dgram(struct socket *sock,
switch (family) {
case PF_UNIX:
- ssp = sock->sk->sk_security;
+ ssp = smack_sock(sock->sk);
s = ssp->smk_out->smk_secid;
break;
case PF_INET:
@@ -3997,7 +3990,7 @@ static int smack_socket_getpeersec_dgram(struct socket *sock,
* Translate what netlabel gave us.
*/
if (sock != NULL && sock->sk != NULL)
- ssp = sock->sk->sk_security;
+ ssp = smack_sock(sock->sk);
netlbl_secattr_init(&secattr);
rc = netlbl_skbuff_getattr(skb, family, &secattr);
if (rc == 0) {
@@ -4035,7 +4028,7 @@ static void smack_sock_graft(struct sock *sk, struct socket *parent)
(sk->sk_family != PF_INET && sk->sk_family != PF_INET6))
return;
- ssp = sk->sk_security;
+ ssp = smack_sock(sk);
ssp->smk_in = skp;
ssp->smk_out = skp;
/* cssp->smk_packet is already set in smack_inet_csk_clone() */
@@ -4055,7 +4048,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
{
u16 family = sk->sk_family;
struct smack_known *skp;
- struct socket_smack *ssp = sk->sk_security;
+ struct socket_smack *ssp = smack_sock(sk);
struct netlbl_lsm_secattr secattr;
struct sockaddr_in addr;
struct iphdr *hdr;
@@ -4154,7 +4147,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
static void smack_inet_csk_clone(struct sock *sk,
const struct request_sock *req)
{
- struct socket_smack *ssp = sk->sk_security;
+ struct socket_smack *ssp = smack_sock(sk);
struct smack_known *skp;
if (req->peer_secid != 0) {
@@ -4558,6 +4551,7 @@ struct lsm_blob_sizes smack_blob_sizes __lsm_ro_after_init = {
.lbs_inode = sizeof(struct inode_smack),
.lbs_ipc = sizeof(struct smack_known *),
.lbs_msg_msg = sizeof(struct smack_known *),
+ .lbs_sock = sizeof(struct socket_smack),
.lbs_superblock = sizeof(struct superblock_smack),
};
@@ -4667,7 +4661,9 @@ static struct security_hook_list smack_hooks[] __lsm_ro_after_init = {
LSM_HOOK_INIT(socket_getpeersec_stream, smack_socket_getpeersec_stream),
LSM_HOOK_INIT(socket_getpeersec_dgram, smack_socket_getpeersec_dgram),
LSM_HOOK_INIT(sk_alloc_security, smack_sk_alloc_security),
+#ifdef SMACK_IPV6_PORT_LABELING
LSM_HOOK_INIT(sk_free_security, smack_sk_free_security),
+#endif
LSM_HOOK_INIT(sock_graft, smack_sock_graft),
LSM_HOOK_INIT(inet_conn_request, smack_inet_conn_request),
LSM_HOOK_INIT(inet_csk_clone, smack_inet_csk_clone),
diff --git a/security/smack/smack_netfilter.c b/security/smack/smack_netfilter.c
index e36d17835d4f..701a1cc1bdcc 100644
--- a/security/smack/smack_netfilter.c
+++ b/security/smack/smack_netfilter.c
@@ -31,8 +31,8 @@ static unsigned int smack_ipv6_output(void *priv,
struct socket_smack *ssp;
struct smack_known *skp;
- if (sk && sk->sk_security) {
- ssp = sk->sk_security;
+ if (sk && smack_sock(sk)) {
+ ssp = smack_sock(sk);
skp = ssp->smk_out;
skb->secmark = skp->smk_secid;
}
@@ -49,8 +49,8 @@ static unsigned int smack_ipv4_output(void *priv,
struct socket_smack *ssp;
struct smack_known *skp;
- if (sk && sk->sk_security) {
- ssp = sk->sk_security;
+ if (sk && smack_sock(sk)) {
+ ssp = smack_sock(sk);
skp = ssp->smk_out;
skb->secmark = skp->smk_secid;
}
--
2.19.1
^ permalink raw reply related
* [PATCH 34/58] AppArmor: Remove unnecessary hook stub
From: Casey Schaufler @ 2019-06-02 16:50 UTC (permalink / raw)
To: casey.schaufler, jmorris, linux-security-module, selinux
Cc: casey, keescook, john.johansen, penguin-kernel, paul, sds
In-Reply-To: <20190602165101.25079-1-casey@schaufler-ca.com>
Remove the getpeersec_dgram hook stub. It's unnecessary
and disrupts stacking.
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
---
security/apparmor/lsm.c | 12 ++----------
1 file changed, 2 insertions(+), 10 deletions(-)
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index 24b638bd4305..76c409737370 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -1094,15 +1094,9 @@ static int apparmor_socket_getpeersec_stream(struct socket *sock,
* @secid: pointer to where to put the secid of the packet
*
* Sets the netlabel socket state on sk from parent
+ *
+ * The TODO stub interfered with stacking and was removed - Casey
*/
-static int apparmor_socket_getpeersec_dgram(struct socket *sock,
- struct sk_buff *skb,
- struct lsm_export *l)
-
-{
- /* TODO: requires secid support */
- return -ENOPROTOOPT;
-}
/**
* apparmor_sock_graft - Initialize newly created socket
@@ -1202,8 +1196,6 @@ static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = {
#endif
LSM_HOOK_INIT(socket_getpeersec_stream,
apparmor_socket_getpeersec_stream),
- LSM_HOOK_INIT(socket_getpeersec_dgram,
- apparmor_socket_getpeersec_dgram),
LSM_HOOK_INIT(sock_graft, apparmor_sock_graft),
#ifdef CONFIG_NETWORK_SECMARK
LSM_HOOK_INIT(inet_conn_request, apparmor_inet_conn_request),
--
2.19.1
^ permalink raw reply related
* [PATCH 32/58] IMA: FIXUP prototype using lsm_export
From: Casey Schaufler @ 2019-06-02 16:50 UTC (permalink / raw)
To: casey.schaufler, jmorris, linux-security-module, selinux
Cc: casey, keescook, john.johansen, penguin-kernel, paul, sds
In-Reply-To: <20190602165101.25079-1-casey@schaufler-ca.com>
Fix the prototype on a function stub
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
---
security/integrity/ima/ima.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 8b109ad0de2e..7ae41218eb07 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -309,8 +309,8 @@ static inline int security_filter_rule_init(u32 field, u32 op, char *rulestr,
return -EINVAL;
}
-static inline int security_filter_rule_match(u32 secid, u32 field, u32 op,
- void *lsmrule)
+static inline int security_filter_rule_match(struct lsm_export *l, u32 field,
+ u32 op, void *lsmrule)
{
return -EINVAL;
}
--
2.19.1
^ permalink raw reply related
* [PATCH 30/58] Netlabel: Replace secids with lsm_export
From: Casey Schaufler @ 2019-06-02 16:50 UTC (permalink / raw)
To: casey.schaufler, jmorris, linux-security-module, selinux
Cc: casey, keescook, john.johansen, penguin-kernel, paul, sds
In-Reply-To: <20190602165101.25079-1-casey@schaufler-ca.com>
Convert to lsm_export structures instead of u32 secids.
Clean out the associated scaffolding. This requires changes
to several internal interfaces, but no change in behavior.
Change the LOC tag type to pass an lsm_export instead of
a single u32. As this tag is only used locally there is
no change to externally exposed interfaces.
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
---
include/net/netlabel.h | 10 ++---
net/ipv4/cipso_ipv4.c | 13 ++++---
net/netlabel/netlabel_kapi.c | 5 +--
net/netlabel/netlabel_unlabeled.c | 65 ++++++++++++-------------------
net/netlabel/netlabel_unlabeled.h | 2 +-
net/netlabel/netlabel_user.c | 7 ++--
net/netlabel/netlabel_user.h | 5 +--
security/selinux/netlabel.c | 2 +-
security/selinux/ss/services.c | 9 +++--
security/smack/smack_lsm.c | 5 ++-
security/smack/smackfs.c | 12 ++++--
11 files changed, 64 insertions(+), 71 deletions(-)
diff --git a/include/net/netlabel.h b/include/net/netlabel.h
index 72d6435fc16c..546c75f27d05 100644
--- a/include/net/netlabel.h
+++ b/include/net/netlabel.h
@@ -111,7 +111,7 @@ struct calipso_doi;
/* NetLabel audit information */
struct netlbl_audit {
- u32 secid;
+ struct lsm_export le;
kuid_t loginuid;
unsigned int sessionid;
};
@@ -180,7 +180,7 @@ struct netlbl_lsm_catmap {
* @attr.mls: MLS sensitivity label
* @attr.mls.cat: MLS category bitmap
* @attr.mls.lvl: MLS sensitivity level
- * @attr.secid: LSM specific secid token
+ * @attr.le: LSM specific data
*
* Description:
* This structure is used to pass security attributes between NetLabel and the
@@ -215,7 +215,7 @@ struct netlbl_lsm_secattr {
struct netlbl_lsm_catmap *cat;
u32 lvl;
} mls;
- u32 secid;
+ struct lsm_export le;
} attr;
};
@@ -429,7 +429,7 @@ int netlbl_cfg_unlbl_static_add(struct net *net,
const void *addr,
const void *mask,
u16 family,
- u32 secid,
+ struct lsm_export *l,
struct netlbl_audit *audit_info);
int netlbl_cfg_unlbl_static_del(struct net *net,
const char *dev_name,
@@ -537,7 +537,7 @@ static inline int netlbl_cfg_unlbl_static_add(struct net *net,
const void *addr,
const void *mask,
u16 family,
- u32 secid,
+ struct lsm_export *l,
struct netlbl_audit *audit_info)
{
return -ENOSYS;
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c
index f0165c5f376b..1defea2488b3 100644
--- a/net/ipv4/cipso_ipv4.c
+++ b/net/ipv4/cipso_ipv4.c
@@ -122,13 +122,16 @@ int cipso_v4_rbm_strictvalid = 1;
*
* 0 8 16 24 32
* +----------+----------+----------+----------+
- * | 10000000 | 00000110 | 32-bit secid value |
+ * | 10000000 | 00000110 | SELinux secid |
* +----------+----------+----------+----------+
- * | in (host byte order)|
+ * | Smack secid | AppArmor secid |
+ * +----------+----------+----------+----------+
+ * | LSM export flags |
* +----------+----------+
*
+ * All secid and flag fields are in host byte order.
*/
-#define CIPSO_V4_TAG_LOC_BLEN 6
+#define CIPSO_V4_TAG_LOC_BLEN (2 + sizeof(struct lsm_export))
/*
* Helper Functions
@@ -1481,7 +1484,7 @@ static int cipso_v4_gentag_loc(const struct cipso_v4_doi *doi_def,
buffer[0] = CIPSO_V4_TAG_LOCAL;
buffer[1] = CIPSO_V4_TAG_LOC_BLEN;
- *(u32 *)&buffer[2] = secattr->attr.secid;
+ memcpy(&buffer[2], &secattr->attr.le, sizeof(secattr->attr.le));
return CIPSO_V4_TAG_LOC_BLEN;
}
@@ -1501,7 +1504,7 @@ static int cipso_v4_parsetag_loc(const struct cipso_v4_doi *doi_def,
const unsigned char *tag,
struct netlbl_lsm_secattr *secattr)
{
- secattr->attr.secid = *(u32 *)&tag[2];
+ memcpy(&secattr->attr.le, &tag[2], sizeof(secattr->attr.le));
secattr->flags |= NETLBL_SECATTR_SECID;
return 0;
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c
index ee3e5b6471a6..849064422e0b 100644
--- a/net/netlabel/netlabel_kapi.c
+++ b/net/netlabel/netlabel_kapi.c
@@ -224,7 +224,7 @@ int netlbl_cfg_unlbl_static_add(struct net *net,
const void *addr,
const void *mask,
u16 family,
- u32 secid,
+ struct lsm_export *l,
struct netlbl_audit *audit_info)
{
u32 addr_len;
@@ -243,8 +243,7 @@ int netlbl_cfg_unlbl_static_add(struct net *net,
}
return netlbl_unlhsh_add(net,
- dev_name, addr, mask, addr_len,
- secid, audit_info);
+ dev_name, addr, mask, addr_len, l, audit_info);
}
/**
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c
index 7f245d593c8f..f79ab91bf25e 100644
--- a/net/netlabel/netlabel_unlabeled.c
+++ b/net/netlabel/netlabel_unlabeled.c
@@ -80,7 +80,7 @@ struct netlbl_unlhsh_tbl {
#define netlbl_unlhsh_addr4_entry(iter) \
container_of(iter, struct netlbl_unlhsh_addr4, list)
struct netlbl_unlhsh_addr4 {
- u32 secid;
+ struct lsm_export le;
struct netlbl_af4list list;
struct rcu_head rcu;
@@ -88,7 +88,7 @@ struct netlbl_unlhsh_addr4 {
#define netlbl_unlhsh_addr6_entry(iter) \
container_of(iter, struct netlbl_unlhsh_addr6, list)
struct netlbl_unlhsh_addr6 {
- u32 secid;
+ struct lsm_export le;
struct netlbl_af6list list;
struct rcu_head rcu;
@@ -244,7 +244,7 @@ static struct netlbl_unlhsh_iface *netlbl_unlhsh_search_iface(int ifindex)
static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface,
const struct in_addr *addr,
const struct in_addr *mask,
- u32 secid)
+ struct lsm_export *l)
{
int ret_val;
struct netlbl_unlhsh_addr4 *entry;
@@ -256,7 +256,7 @@ static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface,
entry->list.addr = addr->s_addr & mask->s_addr;
entry->list.mask = mask->s_addr;
entry->list.valid = 1;
- entry->secid = secid;
+ entry->le = *l;
spin_lock(&netlbl_unlhsh_lock);
ret_val = netlbl_af4list_add(&entry->list, &iface->addr4_list);
@@ -284,7 +284,7 @@ static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface,
static int netlbl_unlhsh_add_addr6(struct netlbl_unlhsh_iface *iface,
const struct in6_addr *addr,
const struct in6_addr *mask,
- u32 secid)
+ struct lsm_export *l)
{
int ret_val;
struct netlbl_unlhsh_addr6 *entry;
@@ -300,7 +300,7 @@ static int netlbl_unlhsh_add_addr6(struct netlbl_unlhsh_iface *iface,
entry->list.addr.s6_addr32[3] &= mask->s6_addr32[3];
entry->list.mask = *mask;
entry->list.valid = 1;
- entry->secid = secid;
+ entry->le = *l;
spin_lock(&netlbl_unlhsh_lock);
ret_val = netlbl_af6list_add(&entry->list, &iface->addr6_list);
@@ -379,7 +379,7 @@ int netlbl_unlhsh_add(struct net *net,
const void *addr,
const void *mask,
u32 addr_len,
- u32 secid,
+ struct lsm_export *l,
struct netlbl_audit *audit_info)
{
int ret_val;
@@ -389,7 +389,6 @@ int netlbl_unlhsh_add(struct net *net,
struct audit_buffer *audit_buf = NULL;
char *secctx = NULL;
u32 secctx_len;
- struct lsm_export le;
if (addr_len != sizeof(struct in_addr) &&
addr_len != sizeof(struct in6_addr))
@@ -422,7 +421,7 @@ int netlbl_unlhsh_add(struct net *net,
const struct in_addr *addr4 = addr;
const struct in_addr *mask4 = mask;
- ret_val = netlbl_unlhsh_add_addr4(iface, addr4, mask4, secid);
+ ret_val = netlbl_unlhsh_add_addr4(iface, addr4, mask4, l);
if (audit_buf != NULL)
netlbl_af4list_audit_addr(audit_buf, 1,
dev_name,
@@ -435,7 +434,7 @@ int netlbl_unlhsh_add(struct net *net,
const struct in6_addr *addr6 = addr;
const struct in6_addr *mask6 = mask;
- ret_val = netlbl_unlhsh_add_addr6(iface, addr6, mask6, secid);
+ ret_val = netlbl_unlhsh_add_addr6(iface, addr6, mask6, l);
if (audit_buf != NULL)
netlbl_af6list_audit_addr(audit_buf, 1,
dev_name,
@@ -452,10 +451,7 @@ int netlbl_unlhsh_add(struct net *net,
unlhsh_add_return:
rcu_read_unlock();
if (audit_buf != NULL) {
- lsm_export_to_all(&le, secid);
- if (security_secid_to_secctx(&le,
- &secctx,
- &secctx_len) == 0) {
+ if (security_secid_to_secctx(l, &secctx, &secctx_len) == 0) {
audit_log_format(audit_buf, " sec_obj=%s", secctx);
security_release_secctx(secctx, secctx_len);
}
@@ -490,7 +486,6 @@ static int netlbl_unlhsh_remove_addr4(struct net *net,
struct net_device *dev;
char *secctx;
u32 secctx_len;
- struct lsm_export le;
spin_lock(&netlbl_unlhsh_lock);
list_entry = netlbl_af4list_remove(addr->s_addr, mask->s_addr,
@@ -510,10 +505,8 @@ static int netlbl_unlhsh_remove_addr4(struct net *net,
addr->s_addr, mask->s_addr);
if (dev != NULL)
dev_put(dev);
- if (entry != NULL)
- lsm_export_to_all(&le, entry->secid);
if (entry != NULL &&
- security_secid_to_secctx(&le,
+ security_secid_to_secctx(&entry->le,
&secctx, &secctx_len) == 0) {
audit_log_format(audit_buf, " sec_obj=%s", secctx);
security_release_secctx(secctx, secctx_len);
@@ -555,7 +548,6 @@ static int netlbl_unlhsh_remove_addr6(struct net *net,
struct net_device *dev;
char *secctx;
u32 secctx_len;
- struct lsm_export le;
spin_lock(&netlbl_unlhsh_lock);
list_entry = netlbl_af6list_remove(addr, mask, &iface->addr6_list);
@@ -574,10 +566,8 @@ static int netlbl_unlhsh_remove_addr6(struct net *net,
addr, mask);
if (dev != NULL)
dev_put(dev);
- if (entry != NULL)
- lsm_export_to_all(&le, entry->secid);
if (entry != NULL &&
- security_secid_to_secctx(&le,
+ security_secid_to_secctx(&entry->le,
&secctx, &secctx_len) == 0) {
audit_log_format(audit_buf, " sec_obj=%s", secctx);
security_release_secctx(secctx, secctx_len);
@@ -903,7 +893,6 @@ static int netlbl_unlabel_staticadd(struct sk_buff *skb,
void *addr;
void *mask;
u32 addr_len;
- u32 secid;
struct lsm_export le;
struct netlbl_audit audit_info;
@@ -932,9 +921,8 @@ static int netlbl_unlabel_staticadd(struct sk_buff *skb,
if (ret_val != 0)
return ret_val;
- lsm_export_secid(&le, &secid);
return netlbl_unlhsh_add(&init_net,
- dev_name, addr, mask, addr_len, secid,
+ dev_name, addr, mask, addr_len, &le,
&audit_info);
}
@@ -956,7 +944,6 @@ static int netlbl_unlabel_staticadddef(struct sk_buff *skb,
void *addr;
void *mask;
u32 addr_len;
- u32 secid;
struct lsm_export le;
struct netlbl_audit audit_info;
@@ -983,10 +970,8 @@ static int netlbl_unlabel_staticadddef(struct sk_buff *skb,
if (ret_val != 0)
return ret_val;
- lsm_export_secid(&le, &secid);
return netlbl_unlhsh_add(&init_net,
- NULL, addr, mask, addr_len, secid,
- &audit_info);
+ NULL, addr, mask, addr_len, &le, &audit_info);
}
/**
@@ -1097,10 +1082,9 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd,
struct netlbl_unlhsh_walk_arg *cb_arg = arg;
struct net_device *dev;
void *data;
- u32 secid;
char *secctx;
u32 secctx_len;
- struct lsm_export le;
+ struct lsm_export *lep;
data = genlmsg_put(cb_arg->skb, NETLINK_CB(cb_arg->nl_cb->skb).portid,
cb_arg->seq, &netlbl_unlabel_gnl_family,
@@ -1138,7 +1122,7 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd,
if (ret_val != 0)
goto list_cb_failure;
- secid = addr4->secid;
+ lep = (struct lsm_export *)&addr4->le;
} else {
ret_val = nla_put_in6_addr(cb_arg->skb,
NLBL_UNLABEL_A_IPV6ADDR,
@@ -1152,11 +1136,10 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd,
if (ret_val != 0)
goto list_cb_failure;
- secid = addr6->secid;
+ lep = (struct lsm_export *)&addr6->le;
}
- lsm_export_to_all(&le, secid);
- ret_val = security_secid_to_secctx(&le, &secctx, &secctx_len);
+ ret_val = security_secid_to_secctx(lep, &secctx, &secctx_len);
if (ret_val != 0)
goto list_cb_failure;
ret_val = nla_put(cb_arg->skb,
@@ -1501,26 +1484,30 @@ int netlbl_unlabel_getattr(const struct sk_buff *skb,
case PF_INET: {
struct iphdr *hdr4;
struct netlbl_af4list *addr4;
+ struct lsm_export *lep;
hdr4 = ip_hdr(skb);
addr4 = netlbl_af4list_search(hdr4->saddr,
&iface->addr4_list);
if (addr4 == NULL)
goto unlabel_getattr_nolabel;
- secattr->attr.secid = netlbl_unlhsh_addr4_entry(addr4)->secid;
+ lep = &netlbl_unlhsh_addr4_entry(addr4)->le;
+ secattr->attr.le = *lep;
break;
}
#if IS_ENABLED(CONFIG_IPV6)
case PF_INET6: {
struct ipv6hdr *hdr6;
struct netlbl_af6list *addr6;
+ struct lsm_export *lep;
hdr6 = ipv6_hdr(skb);
addr6 = netlbl_af6list_search(&hdr6->saddr,
&iface->addr6_list);
if (addr6 == NULL)
goto unlabel_getattr_nolabel;
- secattr->attr.secid = netlbl_unlhsh_addr6_entry(addr6)->secid;
+ lep = &netlbl_unlhsh_addr6_entry(addr6)->le;
+ secattr->attr.le = *lep;
break;
}
#endif /* IPv6 */
@@ -1554,13 +1541,11 @@ int __init netlbl_unlabel_defconf(void)
int ret_val;
struct netlbl_dom_map *entry;
struct netlbl_audit audit_info;
- struct lsm_export le;
/* Only the kernel is allowed to call this function and the only time
* it is called is at bootup before the audit subsystem is reporting
* messages so don't worry to much about these values. */
- security_task_getsecid(current, &le);
- lsm_export_secid(&le, &audit_info.secid);
+ security_task_getsecid(current, &audit_info.le);
audit_info.loginuid = GLOBAL_ROOT_UID;
audit_info.sessionid = 0;
diff --git a/net/netlabel/netlabel_unlabeled.h b/net/netlabel/netlabel_unlabeled.h
index 3a9e5dc9511b..0803f1e6e3c1 100644
--- a/net/netlabel/netlabel_unlabeled.h
+++ b/net/netlabel/netlabel_unlabeled.h
@@ -225,7 +225,7 @@ int netlbl_unlhsh_add(struct net *net,
const void *addr,
const void *mask,
u32 addr_len,
- u32 secid,
+ struct lsm_export *l,
struct netlbl_audit *audit_info);
int netlbl_unlhsh_remove(struct net *net,
const char *dev_name,
diff --git a/net/netlabel/netlabel_user.c b/net/netlabel/netlabel_user.c
index 1079cdea872c..2cc96305c841 100644
--- a/net/netlabel/netlabel_user.c
+++ b/net/netlabel/netlabel_user.c
@@ -100,7 +100,6 @@ struct audit_buffer *netlbl_audit_start_common(int type,
struct audit_buffer *audit_buf;
char *secctx;
u32 secctx_len;
- struct lsm_export le;
if (audit_enabled == AUDIT_OFF)
return NULL;
@@ -113,9 +112,9 @@ struct audit_buffer *netlbl_audit_start_common(int type,
from_kuid(&init_user_ns, audit_info->loginuid),
audit_info->sessionid);
- lsm_export_to_all(&le, audit_info->secid);
- if (audit_info->secid != 0 &&
- security_secid_to_secctx(&le, &secctx, &secctx_len) == 0) {
+ if (lsm_export_any(&audit_info->le) &&
+ security_secid_to_secctx(&audit_info->le, &secctx,
+ &secctx_len) == 0) {
audit_log_format(audit_buf, " subj=%s", secctx);
security_release_secctx(secctx, secctx_len);
}
diff --git a/net/netlabel/netlabel_user.h b/net/netlabel/netlabel_user.h
index 2dbc4276bdcc..ee73711e0756 100644
--- a/net/netlabel/netlabel_user.h
+++ b/net/netlabel/netlabel_user.h
@@ -48,10 +48,7 @@
static inline void netlbl_netlink_auditinfo(struct sk_buff *skb,
struct netlbl_audit *audit_info)
{
- struct lsm_export le;
-
- security_task_getsecid(current, &le);
- lsm_export_secid(&le, &audit_info->secid);
+ security_task_getsecid(current, &audit_info->le);
audit_info->loginuid = audit_get_loginuid(current);
audit_info->sessionid = audit_get_sessionid(current);
}
diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c
index c40914a157b7..4bbd50237a8a 100644
--- a/security/selinux/netlabel.c
+++ b/security/selinux/netlabel.c
@@ -122,7 +122,7 @@ static struct netlbl_lsm_secattr *selinux_netlbl_sock_getattr(
return NULL;
if ((secattr->flags & NETLBL_SECATTR_SECID) &&
- (secattr->attr.secid == sid))
+ (secattr->attr.le.selinux == sid))
return secattr;
return NULL;
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 626b877363fb..8a197b387056 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -3596,8 +3596,9 @@ int security_netlbl_secattr_to_sid(struct selinux_state *state,
if (secattr->flags & NETLBL_SECATTR_CACHE)
*sid = *(u32 *)secattr->cache->data;
- else if (secattr->flags & NETLBL_SECATTR_SECID)
- *sid = secattr->attr.secid;
+ else if (secattr->flags & NETLBL_SECATTR_SECID &&
+ (secattr->attr.le.flags & LSM_EXPORT_SELINUX))
+ *sid = secattr->attr.le.selinux;
else if (secattr->flags & NETLBL_SECATTR_MLS_LVL) {
rc = -EIDRM;
ctx = sidtab_search(sidtab, SECINITSID_NETMSG);
@@ -3670,7 +3671,9 @@ int security_netlbl_sid_to_secattr(struct selinux_state *state,
if (secattr->domain == NULL)
goto out;
- secattr->attr.secid = sid;
+ lsm_export_init(&secattr->attr.le);
+ secattr->attr.le.flags = LSM_EXPORT_SELINUX;
+ secattr->attr.le.selinux = sid;
secattr->flags |= NETLBL_SECATTR_DOMAIN_CPY | NETLBL_SECATTR_SECID;
mls_export_netlbl_lvl(policydb, ctx, secattr);
rc = mls_export_netlbl_cat(policydb, ctx, secattr);
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index ecd636e5c75c..38ea48d22547 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -3756,11 +3756,12 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap,
return &smack_known_web;
return &smack_known_star;
}
- if ((sap->flags & NETLBL_SECATTR_SECID) != 0)
+ if ((sap->flags & NETLBL_SECATTR_SECID) != 0 &&
+ (sap->attr.le.flags & LSM_EXPORT_SMACK))
/*
* Looks like a fallback, which gives us a secid.
*/
- return smack_from_secid(sap->attr.secid);
+ return smack_from_secid(sap->attr.le.smack);
/*
* Without guidance regarding the smack value
* for the packet fall back on the network
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index faf2ea3968b3..28c567465f6c 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -197,7 +197,8 @@ static void smk_netlabel_audit_set(struct netlbl_audit *nap)
nap->loginuid = audit_get_loginuid(current);
nap->sessionid = audit_get_sessionid(current);
- nap->secid = skp->smk_secid;
+ nap->le.flags = LSM_EXPORT_SMACK;
+ nap->le.smack = skp->smk_secid;
}
/*
@@ -1150,6 +1151,7 @@ static void smk_net4addr_insert(struct smk_net4addr *new)
static ssize_t smk_write_net4addr(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
+ struct lsm_export le;
struct smk_net4addr *snp;
struct sockaddr_in newname;
char *smack;
@@ -1281,10 +1283,14 @@ static ssize_t smk_write_net4addr(struct file *file, const char __user *buf,
* this host so that incoming packets get labeled.
* but only if we didn't get the special CIPSO option
*/
- if (rc == 0 && skp != NULL)
+ if (rc == 0 && skp != NULL) {
+ lsm_export_init(&le);
+ le.flags = LSM_EXPORT_SMACK;
+ le.smack = snp->smk_label->smk_secid;
rc = netlbl_cfg_unlbl_static_add(&init_net, NULL,
&snp->smk_host, &snp->smk_mask, PF_INET,
- snp->smk_label->smk_secid, &audit_info);
+ &le, &audit_info);
+ }
if (rc == 0)
rc = count;
--
2.19.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox