@@ -443,7 +443,8 @@ 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(u32 secid, char **secdata, u32 *seclen);
-int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid);
+int security_secctx_to_secid(const char *secdata, u32 seclen,
+ struct lsmblob *l);
void security_release_secctx(char *secdata, u32 seclen);
void security_inode_invalidate_secctx(struct inode *inode);
@@ -1226,7 +1227,7 @@ static inline int security_secid_to_secctx(u32 secid, char **secdata, u32 *secle
static inline int security_secctx_to_secid(const char *secdata,
u32 seclen,
- u32 *secid)
+ struct lsmblob *l)
{
return -EOPNOTSUPP;
}
@@ -725,14 +725,12 @@ EXPORT_SYMBOL(set_security_override);
int set_security_override_from_ctx(struct cred *new, const char *secctx)
{
struct lsmblob le;
- u32 secid;
int ret;
- ret = security_secctx_to_secid(secctx, strlen(secctx), &secid);
+ ret = security_secctx_to_secid(secctx, strlen(secctx), &le);
if (ret < 0)
return ret;
- lsmblob_init(&le, secid);
return set_security_override(new, &le);
}
EXPORT_SYMBOL(set_security_override_from_ctx);
@@ -576,21 +576,20 @@ static const struct nla_policy nft_secmark_policy[NFTA_SECMARK_MAX + 1] = {
static int nft_secmark_compute_secid(struct nft_secmark *priv)
{
- u32 tmp_secid = 0;
+ struct lsmblob le;
int err;
- err = security_secctx_to_secid(priv->ctx, strlen(priv->ctx), &tmp_secid);
+ err = security_secctx_to_secid(priv->ctx, strlen(priv->ctx), &le);
if (err)
return err;
- if (!tmp_secid)
- return -ENOENT;
-
- err = security_secmark_relabel_packet(tmp_secid);
+ /* Using le[1] is scaffolding */
+ err = security_secmark_relabel_packet(le.secid[1]);
if (err)
return err;
- priv->secid = tmp_secid;
+ /* Using le[1] is scaffolding */
+ priv->secid = le.secid[1];
return 0;
}
@@ -49,13 +49,13 @@ secmark_tg(struct sk_buff *skb, const struct xt_action_param *par)
static int checkentry_lsm(struct xt_secmark_target_info *info)
{
+ struct lsmblob le;
int err;
info->secctx[SECMARK_SECCTX_MAX - 1] = '\0';
info->secid = 0;
- err = security_secctx_to_secid(info->secctx, strlen(info->secctx),
- &info->secid);
+ err = security_secctx_to_secid(info->secctx, strlen(info->secctx), &le);
if (err) {
if (err == -EINVAL)
pr_info_ratelimited("invalid security context \'%s\'\n",
@@ -63,6 +63,8 @@ static int checkentry_lsm(struct xt_secmark_target_info *info)
return err;
}
+ /* scaffolding during the transition */
+ info->secid = le.secid[1];
if (!info->secid) {
pr_info_ratelimited("unable to map security context \'%s\'\n",
info->secctx);
@@ -895,7 +895,7 @@ static int netlbl_unlabel_staticadd(struct sk_buff *skb,
void *addr;
void *mask;
u32 addr_len;
- u32 secid;
+ struct lsmblob le;
struct netlbl_audit audit_info;
/* Don't allow users to add both IPv4 and IPv6 addresses for a
@@ -919,12 +919,13 @@ static int netlbl_unlabel_staticadd(struct sk_buff *skb,
ret_val = security_secctx_to_secid(
nla_data(info->attrs[NLBL_UNLABEL_A_SECCTX]),
nla_len(info->attrs[NLBL_UNLABEL_A_SECCTX]),
- &secid);
+ &le);
if (ret_val != 0)
return ret_val;
+ /* scaffolding with the [1] */
return netlbl_unlhsh_add(&init_net,
- dev_name, addr, mask, addr_len, secid,
+ dev_name, addr, mask, addr_len, le.secid[1],
&audit_info);
}
@@ -946,7 +947,7 @@ static int netlbl_unlabel_staticadddef(struct sk_buff *skb,
void *addr;
void *mask;
u32 addr_len;
- u32 secid;
+ struct lsmblob le;
struct netlbl_audit audit_info;
/* Don't allow users to add both IPv4 and IPv6 addresses for a
@@ -968,12 +969,13 @@ static int netlbl_unlabel_staticadddef(struct sk_buff *skb,
ret_val = security_secctx_to_secid(
nla_data(info->attrs[NLBL_UNLABEL_A_SECCTX]),
nla_len(info->attrs[NLBL_UNLABEL_A_SECCTX]),
- &secid);
+ &le);
if (ret_val != 0)
return ret_val;
+ /* scaffolding with the [1] */
return netlbl_unlhsh_add(&init_net,
- NULL, addr, mask, addr_len, secid,
+ NULL, addr, mask, addr_len, le.secid[1],
&audit_info);
}
@@ -1994,10 +1994,19 @@ int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
}
EXPORT_SYMBOL(security_secid_to_secctx);
-int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)
+int security_secctx_to_secid(const char *secdata, u32 seclen, struct lsmblob *l)
{
- *secid = 0;
- return call_int_hook(secctx_to_secid, 0, secdata, seclen, secid);
+ struct security_hook_list *hp;
+ int rc;
+
+ lsmblob_init(l, 0);
+ hlist_for_each_entry(hp, &security_hook_heads.secctx_to_secid, list) {
+ rc = hp->hook.secctx_to_secid(secdata, seclen,
+ &l->secid[hp->slot]);
+ if (rc != 0)
+ return rc;
+ }
+ return 0;
}
EXPORT_SYMBOL(security_secctx_to_secid);
Change security_secctx_to_secid() to fill in a lsmblob instead of a u32 secid. Multiple LSMs may be able to interpret the string, and this allows for setting whichever secid is appropriate. In some cases there is scaffolding where other interfaces have yet to be converted. Signed-off-by: Casey Schaufler <casey@schaufler-ca.com> --- include/linux/security.h | 5 +++-- kernel/cred.c | 4 +--- net/netfilter/nft_meta.c | 13 ++++++------- net/netfilter/xt_SECMARK.c | 6 ++++-- net/netlabel/netlabel_unlabeled.c | 14 ++++++++------ security/security.c | 15 ++++++++++++--- 6 files changed, 34 insertions(+), 23 deletions(-)