@@ -112,6 +112,10 @@ static inline void lsm_export_secid(struct lsm_export *data, u32 *secid)
case LSM_EXPORT_APPARMOR:
*secid = data->apparmor;
break;
+ case LSM_EXPORT_SELINUX | LSM_EXPORT_SMACK | LSM_EXPORT_APPARMOR:
+ /* For scaffolding only */
+ *secid = data->selinux;
+ break;
default:
pr_warn("%s flags=0x%u - not a valid set\n", __func__,
data->flags);
@@ -431,7 +435,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(u32 secid, char **secdata, u32 *seclen);
+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);
void security_release_secctx(char *secdata, u32 seclen);
@@ -1198,7 +1202,8 @@ static inline int security_ismaclabel(const char *name)
return 0;
}
-static inline int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
+static inline int security_secid_to_secctx(struct lsm_export *l,
+ char **secdata, u32 *seclen)
{
return -EOPNOTSUPP;
}
@@ -33,7 +33,6 @@ struct scm_cookie {
struct scm_fp_list *fp; /* Passed files */
struct scm_creds creds; /* Skb credentials */
#ifdef CONFIG_SECURITY_NETWORK
- u32 secid; /* Passed security ID */
struct lsm_export le; /* Passed LSM data */
#endif
};
@@ -48,7 +47,6 @@ struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl);
static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm)
{
security_socket_getpeersec_dgram(sock, NULL, &scm->le);
- lsm_export_secid(&scm->le, &scm->secid);
}
#else
static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm)
@@ -99,7 +97,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->secid, &secdata, &seclen);
+ err = security_secid_to_secctx(&scm->le, &secdata, &seclen);
if (!err) {
put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, seclen, secdata);
@@ -1418,7 +1418,10 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
case AUDIT_SIGNAL_INFO:
len = 0;
if (audit_sig_sid) {
- err = security_secid_to_secctx(audit_sig_sid, &ctx, &len);
+ struct lsm_export le;
+
+ lsm_export_to_all(&le, audit_sig_sid);
+ err = security_secid_to_secctx(&le, &ctx, &len);
if (err)
return err;
}
@@ -2167,8 +2170,10 @@ void audit_log_name(struct audit_context *context, struct audit_names *n,
if (n->osid != 0) {
char *ctx = NULL;
u32 len;
- if (security_secid_to_secctx(
- n->osid, &ctx, &len)) {
+ struct lsm_export le;
+
+ lsm_export_to_all(&le, n->osid);
+ if (security_secid_to_secctx(&le, &ctx, &len)) {
audit_log_format(ab, " osid=%u", n->osid);
if (call_panic)
*call_panic = 2;
@@ -2207,12 +2212,14 @@ int audit_log_task_context(struct audit_buffer *ab)
unsigned len;
int error;
u32 sid;
+ struct lsm_export le;
security_task_getsecid(current, &sid);
if (!sid)
return 0;
- error = security_secid_to_secctx(sid, &ctx, &len);
+ lsm_export_to_all(&le, sid);
+ error = security_secid_to_secctx(&le, &ctx, &len);
if (error) {
if (error != -EINVAL)
goto error_path;
@@ -943,6 +943,7 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid,
char *ctx = NULL;
u32 len;
int rc = 0;
+ struct lsm_export le;
ab = audit_log_start(context, GFP_KERNEL, AUDIT_OBJ_PID);
if (!ab)
@@ -952,7 +953,8 @@ 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 (sid) {
- if (security_secid_to_secctx(sid, &ctx, &len)) {
+ lsm_export_to_all(&le, sid);
+ if (security_secid_to_secctx(&le, &ctx, &len)) {
audit_log_format(ab, " obj=(none)");
rc = 1;
} else {
@@ -1168,7 +1170,9 @@ static void show_special(struct audit_context *context, int *call_panic)
if (osid) {
char *ctx = NULL;
u32 len;
- if (security_secid_to_secctx(osid, &ctx, &len)) {
+ struct lsm_export le;
+ lsm_export_to_all(&le, osid);
+ if (security_secid_to_secctx(&le, &ctx, &len)) {
audit_log_format(ab, " osid=%u", osid);
*call_panic = 1;
} else {
@@ -132,15 +132,14 @@ static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb)
{
struct lsm_export le;
char *secdata;
- u32 seclen, secid;
+ u32 seclen;
int err;
err = security_socket_getpeersec_dgram(NULL, skb, &le);
if (err)
return;
- lsm_export_secid(&le, &secid);
- err = security_secid_to_secctx(secid, &secdata, &seclen);
+ err = security_secid_to_secctx(&le, &secdata, &seclen);
if (err)
return;
@@ -330,8 +330,10 @@ static int ctnetlink_dump_secctx(struct sk_buff *skb, const struct nf_conn *ct)
struct nlattr *nest_secctx;
int len, ret;
char *secctx;
+ struct lsm_export le;
- ret = security_secid_to_secctx(ct->secmark, &secctx, &len);
+ lsm_export_to_all(&le, ct->secmark);
+ ret = security_secid_to_secctx(&le, &secctx, &len);
if (ret)
return 0;
@@ -615,8 +617,10 @@ static inline int ctnetlink_secctx_size(const struct nf_conn *ct)
{
#ifdef CONFIG_NF_CONNTRACK_SECMARK
int len, ret;
+ struct lsm_export le;
- ret = security_secid_to_secctx(ct->secmark, NULL, &len);
+ lsm_export_to_all(&le, ct->secmark);
+ ret = security_secid_to_secctx(&le, NULL, &len);
if (ret)
return 0;
@@ -171,7 +171,9 @@ static void ct_show_secctx(struct seq_file *s, const struct nf_conn *ct)
int ret;
u32 len;
char *secctx;
+ struct lsm_export le;
+ lsm_export_to_all(&le, ct->secmark);
ret = security_secid_to_secctx(ct->secmark, &secctx, &len);
if (ret)
return;
@@ -309,13 +309,17 @@ 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;
+
if (!skb || !sk_fullsock(skb->sk))
return 0;
read_lock_bh(&skb->sk->sk_callback_lock);
- if (skb->secmark)
+ if (skb->secmark) {
+ lsm_export_to_all(&le, skb->secmark);
security_secid_to_secctx(skb->secmark, secdata, &seclen);
+ }
read_unlock_bh(&skb->sk->sk_callback_lock);
#endif
@@ -389,6 +389,7 @@ 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))
@@ -451,7 +452,8 @@ int netlbl_unlhsh_add(struct net *net,
unlhsh_add_return:
rcu_read_unlock();
if (audit_buf != NULL) {
- if (security_secid_to_secctx(secid,
+ lsm_export_to_all(&le, secid);
+ if (security_secid_to_secctx(&le,
&secctx,
&secctx_len) == 0) {
audit_log_format(audit_buf, " sec_obj=%s", secctx);
@@ -488,6 +490,7 @@ 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,
@@ -507,8 +510,10 @@ 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(entry->secid,
+ security_secid_to_secctx(&le,
&secctx, &secctx_len) == 0) {
audit_log_format(audit_buf, " sec_obj=%s", secctx);
security_release_secctx(secctx, secctx_len);
@@ -550,6 +555,7 @@ 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);
@@ -568,8 +574,10 @@ 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(entry->secid,
+ security_secid_to_secctx(&le,
&secctx, &secctx_len) == 0) {
audit_log_format(audit_buf, " sec_obj=%s", secctx);
security_release_secctx(secctx, secctx_len);
@@ -1092,6 +1100,7 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd,
u32 secid;
char *secctx;
u32 secctx_len;
+ struct lsm_export le;
data = genlmsg_put(cb_arg->skb, NETLINK_CB(cb_arg->nl_cb->skb).portid,
cb_arg->seq, &netlbl_unlabel_gnl_family,
@@ -1146,7 +1155,8 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd,
secid = addr6->secid;
}
- ret_val = security_secid_to_secctx(secid, &secctx, &secctx_len);
+ lsm_export_to_all(&le, secid);
+ ret_val = security_secid_to_secctx(&le, &secctx, &secctx_len);
if (ret_val != 0)
goto list_cb_failure;
ret_val = nla_put(cb_arg->skb,
@@ -141,17 +141,20 @@ static struct hlist_head *unix_sockets_unbound(void *addr)
#ifdef CONFIG_SECURITY_NETWORK
static void unix_get_secdata(struct scm_cookie *scm, struct sk_buff *skb)
{
- UNIXCB(skb).secid = scm->secid;
+ lsm_export_secid(&scm->le, &(UNIXCB(skb).secid));
}
static inline void unix_set_secdata(struct scm_cookie *scm, struct sk_buff *skb)
{
- scm->secid = UNIXCB(skb).secid;
+ lsm_export_to_all(&scm->le, UNIXCB(skb).secid);
}
static inline bool unix_secdata_eq(struct scm_cookie *scm, struct sk_buff *skb)
{
- return (scm->secid == UNIXCB(skb).secid);
+ u32 best_secid;
+
+ lsm_export_secid(&scm->le, &best_secid);
+ return (best_secid == UNIXCB(skb).secid);
}
#else
static inline void unix_get_secdata(struct scm_cookie *scm, struct sk_buff *skb)
@@ -1943,13 +1943,9 @@ int security_ismaclabel(const char *name)
}
EXPORT_SYMBOL(security_ismaclabel);
-int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
+int security_secid_to_secctx(struct lsm_export *l, char **secdata, u32 *seclen)
{
- struct lsm_export data;
-
- lsm_export_to_all(&data, secid);
- return call_int_hook(secid_to_secctx, -EOPNOTSUPP, &data, secdata,
- seclen);
+ return call_int_hook(secid_to_secctx, -EOPNOTSUPP, l, secdata, seclen);
}
EXPORT_SYMBOL(security_secid_to_secctx);
Convert security_secid_to_secctx to use the lsm_export structure instead of a u32 secid. 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 | 9 +++++++-- include/net/scm.h | 4 +--- kernel/audit.c | 15 +++++++++++---- kernel/auditsc.c | 8 ++++++-- net/ipv4/ip_sockglue.c | 5 ++--- net/netfilter/nf_conntrack_netlink.c | 8 ++++++-- net/netfilter/nf_conntrack_standalone.c | 2 ++ net/netfilter/nfnetlink_queue.c | 6 +++++- net/netlabel/netlabel_unlabeled.c | 18 ++++++++++++++---- net/unix/af_unix.c | 9 ++++++--- security/security.c | 8 ++------ 11 files changed, 62 insertions(+), 30 deletions(-)