On 5/31/2023 4:05 AM, GONG, Ruiqi wrote: > As the security infrastructure has taken over the management of multiple > *_security blobs that are accessed by multiple security modules, and > sk->sk_security shares the same situation, move its management out of > individual security modules and into the security infrastructure as > well. The infrastructure does the memory allocation, and each relavant > module uses its own share. Do you have a reason to make this change? The LSM infrastructure manages other security blobs to enable multiple concurrently active LSMs to use the blob. If only one LSM on a system can use the socket blob there's no reason to move the management. > > Signed-off-by: GONG, Ruiqi <gongruiqi@xxxxxxxxxxxxxxx> > --- > include/linux/lsm_hooks.h | 1 + > security/apparmor/include/net.h | 2 +- > security/apparmor/lsm.c | 20 +------- > security/security.c | 35 ++++++++++++- > security/selinux/hooks.c | 81 ++++++++++++++----------------- > security/selinux/include/objsec.h | 4 ++ > security/selinux/netlabel.c | 22 ++++----- > security/smack/smack.h | 5 ++ > security/smack/smack_lsm.c | 65 +++++++++++-------------- > security/smack/smack_netfilter.c | 4 +- > 10 files changed, 125 insertions(+), 114 deletions(-) > > diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h > index ab2b2fafa4a4..67b6e87ca6ec 100644 > --- a/include/linux/lsm_hooks.h > +++ b/include/linux/lsm_hooks.h > @@ -62,6 +62,7 @@ struct lsm_blob_sizes { > int lbs_superblock; > int lbs_ipc; > int lbs_msg_msg; > + int lbs_sock; > int lbs_task; > }; > > diff --git a/security/apparmor/include/net.h b/security/apparmor/include/net.h > index 6fa440b5daed..9eb159c09578 100644 > --- a/security/apparmor/include/net.h > +++ b/security/apparmor/include/net.h > @@ -51,7 +51,7 @@ struct aa_sk_ctx { > struct aa_label *peer; > }; > > -#define SK_CTX(X) ((X)->sk_security) > +#define SK_CTX(X) ((X)->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 f431251ffb91..3dd849a6d7a1 100644 > --- a/security/apparmor/lsm.c > +++ b/security/apparmor/lsm.c > @@ -818,22 +818,6 @@ 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 > */ > @@ -841,10 +825,8 @@ static void apparmor_sk_free_security(struct sock *sk) > { > struct aa_sk_ctx *ctx = SK_CTX(sk); > > - SK_CTX(sk) = NULL; > aa_put_label(ctx->label); > aa_put_label(ctx->peer); > - kfree(ctx); > } > > /** > @@ -1212,6 +1194,7 @@ static int apparmor_inet_conn_request(const struct sock *sk, struct sk_buff *skb > struct lsm_blob_sizes apparmor_blob_sizes __ro_after_init = { > .lbs_cred = sizeof(struct aa_label *), > .lbs_file = sizeof(struct aa_file_ctx), > + .lbs_sock = sizeof(struct aa_sk_ctx), > .lbs_task = sizeof(struct aa_task_ctx), > }; > > @@ -1250,7 +1233,6 @@ static struct security_hook_list apparmor_hooks[] __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), > > diff --git a/security/security.c b/security/security.c > index b720424ca37d..e71f4717cde5 100644 > --- a/security/security.c > +++ b/security/security.c > @@ -30,6 +30,7 @@ > #include <linux/string.h> > #include <linux/msg.h> > #include <net/flow.h> > +#include <net/sock.h> > > #define MAX_LSM_EVM_XATTR 2 > > @@ -210,6 +211,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); > } > @@ -376,6 +378,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); > > @@ -733,6 +736,27 @@ static int lsm_superblock_alloc(struct super_block *sb) > return 0; > } > > +/** > + * lsm_sock_alloc - allocate a composite socket blob > + * @sk: the socket that needs a blob > + * > + * Allocate the socket blob for all the modules > + * > + * Returns 0, or -ENOMEM if memory can't be allocated. > + */ > +static int lsm_sock_alloc(struct sock *sk) > +{ > + if (blob_sizes.lbs_sock == 0) { > + sk->sk_security = NULL; > + return 0; > + } > + > + sk->sk_security = kzalloc(blob_sizes.lbs_sock, GFP_KERNEL); > + if (sk->sk_security == NULL) > + return -ENOMEM; > + return 0; > +} > + > /* > * The default value of the LSM hook is defined in linux/lsm_hook_defs.h and > * can be accessed with: > @@ -4369,7 +4393,14 @@ 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); > + > + 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; > } > > /** > @@ -4381,6 +4412,8 @@ int security_sk_alloc(struct sock *sk, int family, gfp_t priority) > void security_sk_free(struct sock *sk) > { > call_void_hook(sk_free_security, sk); > + kfree(sk->sk_security); > + sk->sk_security = NULL; > } > > /** > diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c > index d06e350fedee..f8397f05dc90 100644 > --- a/security/selinux/hooks.c > +++ b/security/selinux/hooks.c > @@ -4497,7 +4497,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,}; > > @@ -4552,7 +4552,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 */ > @@ -4568,8 +4568,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; > @@ -4584,7 +4584,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; > > @@ -4717,7 +4717,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); > @@ -4895,9 +4895,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; > @@ -4928,8 +4928,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,}; > > @@ -4968,7 +4968,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,}; > @@ -5000,7 +5000,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; > @@ -5073,7 +5073,7 @@ static int selinux_socket_getpeersec_stream(struct socket *sock, > int err = 0; > char *scontext = NULL; > 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 || > @@ -5131,34 +5131,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; > @@ -5172,7 +5165,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; > } > @@ -5182,7 +5175,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) > @@ -5199,7 +5192,7 @@ static int selinux_sctp_process_new_assoc(struct sctp_association *asoc, > { > struct sock *sk = asoc->base.sk; > u16 family = sk->sk_family; > - 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,}; > int err; > @@ -5256,7 +5249,7 @@ static int selinux_sctp_process_new_assoc(struct sctp_association *asoc, > static int selinux_sctp_assoc_request(struct sctp_association *asoc, > struct sk_buff *skb) > { > - struct sk_security_struct *sksec = asoc->base.sk->sk_security; > + struct sk_security_struct *sksec = selinux_sock(asoc->base.sk); > u32 conn_sid; > int err; > > @@ -5289,7 +5282,7 @@ static int selinux_sctp_assoc_request(struct sctp_association *asoc, > static int selinux_sctp_assoc_established(struct sctp_association *asoc, > struct sk_buff *skb) > { > - struct sk_security_struct *sksec = asoc->base.sk->sk_security; > + struct sk_security_struct *sksec = selinux_sock(asoc->base.sk); > > if (!selinux_policycap_extsockclass()) > return 0; > @@ -5388,8 +5381,8 @@ static int selinux_sctp_bind_connect(struct sock *sk, int optname, > static void selinux_sctp_sk_clone(struct sctp_association *asoc, 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. > @@ -5405,8 +5398,8 @@ static void selinux_sctp_sk_clone(struct sctp_association *asoc, struct sock *sk > > static int selinux_mptcp_add_subflow(struct sock *sk, struct sock *ssk) > { > - struct sk_security_struct *ssksec = ssk->sk_security; > - struct sk_security_struct *sksec = sk->sk_security; > + struct sk_security_struct *ssksec = selinux_sock(ssk); > + struct sk_security_struct *sksec = selinux_sock(sk); > > ssksec->sclass = sksec->sclass; > ssksec->sid = sksec->sid; > @@ -5421,7 +5414,7 @@ static int selinux_mptcp_add_subflow(struct sock *sk, struct sock *ssk) > static int selinux_inet_conn_request(const 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; > @@ -5442,7 +5435,7 @@ static int selinux_inet_conn_request(const 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; > @@ -5459,7 +5452,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)) > @@ -5540,7 +5533,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 > @@ -5666,7 +5659,7 @@ static unsigned int selinux_ip_output(void *priv, 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; > @@ -5689,7 +5682,7 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb, > sk = skb_to_full_sk(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; > @@ -5779,9 +5772,8 @@ static unsigned int selinux_ip_postroute(void *priv, > * selinux_inet_conn_request(). See also selinux_ip_output() > * for similar problems. */ > u32 skb_sid; > - struct sk_security_struct *sksec; > + struct sk_security_struct *sksec = selinux_sock(sk); > > - sksec = sk->sk_security; > if (selinux_skb_peerlbl_sid(skb, family, &skb_sid)) > return NF_DROP; > /* At this point, if the returned skb peerlbl is SECSID_NULL > @@ -5810,7 +5802,7 @@ static unsigned int selinux_ip_postroute(void *priv, > } 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; > } > @@ -5856,7 +5848,7 @@ static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb) > unsigned int data_len = skb->len; > unsigned char *data = skb->data; > struct nlmsghdr *nlh; > - struct sk_security_struct *sksec = sk->sk_security; > + struct sk_security_struct *sksec = selinux_sock(sk); > u16 sclass = sksec->sclass; > u32 perm; > > @@ -6814,6 +6806,7 @@ struct lsm_blob_sizes selinux_blob_sizes __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 2953132408bf..49221f441c68 100644 > --- a/security/selinux/include/objsec.h > +++ b/security/selinux/include/objsec.h > @@ -194,4 +194,8 @@ 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 *sk) > +{ > + return sk->sk_security + selinux_blob_sizes.lbs_sock; > +} > #endif /* _SELINUX_OBJSEC_H_ */ > diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c > index 528f5186e912..9755561aa466 100644 > --- a/security/selinux/netlabel.c > +++ b/security/selinux/netlabel.c > @@ -68,7 +68,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) > @@ -100,7 +100,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) > @@ -239,7 +239,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; > @@ -276,7 +276,7 @@ int selinux_netlbl_sctp_assoc_request(struct sctp_association *asoc, > { > int rc; > struct netlbl_lsm_secattr secattr; > - struct sk_security_struct *sksec = asoc->base.sk->sk_security; > + struct sk_security_struct *sksec = selinux_sock(asoc->base.sk); > struct sockaddr_in addr4; > struct sockaddr_in6 addr6; > > @@ -355,7 +355,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; > @@ -373,8 +373,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; > } > @@ -392,7 +392,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) > @@ -506,7 +506,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) && > @@ -544,7 +544,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 > @@ -583,7 +583,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 aa15ff56ed6e..2d0163076eca 100644 > --- a/security/smack/smack.h > +++ b/security/smack/smack.h > @@ -355,6 +355,11 @@ static inline struct superblock_smack *smack_superblock( > return superblock->s_security + smack_blob_sizes.lbs_superblock; > } > > +static inline struct socket_smack *smack_sock(const struct sock *sk) > +{ > + return sk->sk_security + smack_blob_sizes.lbs_sock; > +} > + > /* > * Is the directory transmuting? > */ > diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c > index 6e270cf3fd30..ab026ff79504 100644 > --- a/security/smack/smack_lsm.c > +++ b/security/smack/smack_lsm.c > @@ -1502,7 +1502,7 @@ static int smack_inode_getsecurity(struct mnt_idmap *idmap, > 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; > @@ -1890,7 +1890,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 > @@ -2310,11 +2310,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. > @@ -2328,8 +2324,6 @@ 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; > } > > @@ -2355,7 +2349,6 @@ static void smack_sk_free_security(struct sock *sk) > rcu_read_unlock(); > } > #endif > - kfree(sk->sk_security); > } > > /** > @@ -2367,8 +2360,8 @@ static void smack_sk_free_security(struct sock *sk) > */ > static void smack_sk_clone_security(const struct sock *sk, struct sock *newsk) > { > - struct socket_smack *ssp_old = sk->sk_security; > - struct socket_smack *ssp_new = newsk->sk_security; > + struct socket_smack *ssp_old = smack_sock(sk); > + struct socket_smack *ssp_new = smack_sock(newsk); > > *ssp_new = *ssp_old; > } > @@ -2484,7 +2477,7 @@ static struct smack_known *smack_ipv6host_label(struct sockaddr_in6 *sip) > */ > static int smack_netlbl_add(struct sock *sk) > { > - struct socket_smack *ssp = sk->sk_security; > + struct socket_smack *ssp = smack_sock(sk); > struct smack_known *skp = ssp->smk_out; > int rc; > > @@ -2516,7 +2509,7 @@ static int smack_netlbl_add(struct sock *sk) > */ > static void smack_netlbl_delete(struct sock *sk) > { > - struct socket_smack *ssp = sk->sk_security; > + struct socket_smack *ssp = smack_sock(sk); > > /* > * Take the label off the socket if one is set. > @@ -2548,7 +2541,7 @@ static int smk_ipv4_check(struct sock *sk, struct sockaddr_in *sap) > struct smack_known *skp; > int rc = 0; > 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(); > @@ -2621,7 +2614,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; > > @@ -2709,7 +2702,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; > @@ -2803,7 +2796,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; > @@ -2851,7 +2844,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; > } > @@ -2876,8 +2869,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; > @@ -2940,7 +2933,7 @@ static int smack_socket_connect(struct socket *sock, struct sockaddr *sap, > if (__is_defined(SMACK_IPV6_SECMARK_LABELING)) > rsp = smack_ipv6host_label(sip); > if (rsp != NULL) { > - struct socket_smack *ssp = sock->sk->sk_security; > + struct socket_smack *ssp = smack_sock(sock->sk); > > rc = smk_ipv6_check(ssp->smk_out, rsp, sip, > SMK_CONNECTING); > @@ -3671,9 +3664,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 > @@ -3719,8 +3712,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; > > @@ -3757,7 +3750,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; > @@ -3969,7 +3962,7 @@ static struct smack_known *smack_from_netlbl(const struct sock *sk, u16 family, > netlbl_secattr_init(&secattr); > > if (sk) > - ssp = sk->sk_security; > + ssp = smack_sock(sk); > > if (netlbl_skbuff_getattr(skb, family, &secattr) == 0) { > skp = smack_from_secattr(&secattr, ssp); > @@ -3991,7 +3984,7 @@ static struct smack_known *smack_from_netlbl(const struct sock *sk, u16 family, > */ > static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) > { > - 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; > @@ -4090,12 +4083,11 @@ static int smack_socket_getpeersec_stream(struct socket *sock, > sockptr_t optval, sockptr_t optlen, > unsigned int len) > { > - struct socket_smack *ssp; > + struct socket_smack *ssp = smack_sock(sock->sk); > char *rcp = ""; > u32 slen = 1; > int rc = 0; > > - ssp = sock->sk->sk_security; > if (ssp->smk_packet != NULL) { > rcp = ssp->smk_packet->smk_known; > slen = strlen(rcp) + 1; > @@ -4145,7 +4137,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: > @@ -4194,7 +4186,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() */ > @@ -4214,7 +4206,7 @@ static int smack_inet_conn_request(const 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 sockaddr_in addr; > struct iphdr *hdr; > struct smack_known *hskp; > @@ -4300,7 +4292,7 @@ static int smack_inet_conn_request(const 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) { > @@ -4868,6 +4860,7 @@ struct lsm_blob_sizes smack_blob_sizes __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), > }; > > diff --git a/security/smack/smack_netfilter.c b/security/smack/smack_netfilter.c > index b945c1d3a743..bad71b7e648d 100644 > --- a/security/smack/smack_netfilter.c > +++ b/security/smack/smack_netfilter.c > @@ -26,8 +26,8 @@ static unsigned int smack_ip_output(void *priv, > struct socket_smack *ssp; > struct smack_known *skp; > > - if (sk && sk->sk_security) { > - ssp = sk->sk_security; > + if (sk) { > + ssp = smack_sock(sk); > skp = ssp->smk_out; > skb->secmark = skp->smk_secid; > }