diff options
Diffstat (limited to 'meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0030-Smack-bidirectional-UDS-connect-check.patch')
-rw-r--r-- | meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0030-Smack-bidirectional-UDS-connect-check.patch | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0030-Smack-bidirectional-UDS-connect-check.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0030-Smack-bidirectional-UDS-connect-check.patch new file mode 100644 index 0000000..bc65513 --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0030-Smack-bidirectional-UDS-connect-check.patch @@ -0,0 +1,204 @@ +From dab2915e5899611c1d90d5c35d4b463145ce9fad Mon Sep 17 00:00:00 2001 +From: Casey Schaufler <casey@schaufler-ca.com> +Date: Thu, 10 Apr 2014 16:37:08 -0700 +Subject: [PATCH 30/54] Smack: bidirectional UDS connect check + +Smack IPC policy requires that the sender have write access +to the receiver. UDS streams don't do per-packet checks. The +only check is done at connect time. The existing code checks +if the connecting process can write to the other, but not the +other way around. This change adds a check that the other end +can write to the connecting process. + +Targeted for git://git.gitorious.org/smack-next/kernel.git + +Signed-off-by: Casey Schuafler <casey@schaufler-ca.com> +--- + security/smack/smack.h | 6 +++--- + security/smack/smack_lsm.c | 44 ++++++++++++++++++++++++-------------------- + 2 files changed, 27 insertions(+), 23 deletions(-) + +diff --git a/security/smack/smack.h b/security/smack/smack.h +index fade085..020307e 100644 +--- a/security/smack/smack.h ++++ b/security/smack/smack.h +@@ -80,8 +80,8 @@ struct superblock_smack { + + struct socket_smack { + struct smack_known *smk_out; /* outbound label */ +- char *smk_in; /* inbound label */ +- char *smk_packet; /* TCP peer label */ ++ struct smack_known *smk_in; /* inbound label */ ++ struct smack_known *smk_packet; /* TCP peer label */ + }; + + /* +@@ -133,7 +133,7 @@ struct smk_port_label { + struct list_head list; + struct sock *smk_sock; /* socket initialized on */ + unsigned short smk_port; /* the port number */ +- char *smk_in; /* incoming label */ ++ struct smack_known *smk_in; /* inbound label */ + struct smack_known *smk_out; /* outgoing label */ + }; + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index b259a0d..21ef3a1 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -1095,7 +1095,7 @@ static int smack_inode_getsecurity(const struct inode *inode, + ssp = sock->sk->sk_security; + + if (strcmp(name, XATTR_SMACK_IPIN) == 0) +- isp = ssp->smk_in; ++ isp = ssp->smk_in->smk_known; + else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) + isp = ssp->smk_out->smk_known; + else +@@ -1859,7 +1859,7 @@ static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags) + if (ssp == NULL) + return -ENOMEM; + +- ssp->smk_in = skp->smk_known; ++ ssp->smk_in = skp; + ssp->smk_out = skp; + ssp->smk_packet = NULL; + +@@ -2099,7 +2099,7 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address, + + if (act == SMK_RECEIVING) { + skp = smack_net_ambient; +- object = ssp->smk_in; ++ object = ssp->smk_in->smk_known; + } else { + skp = ssp->smk_out; + object = smack_net_ambient->smk_known; +@@ -2129,9 +2129,9 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address, + list_for_each_entry(spp, &smk_ipv6_port_list, list) { + if (spp->smk_port != port) + continue; +- object = spp->smk_in; ++ object = spp->smk_in->smk_known; + if (act == SMK_CONNECTING) +- ssp->smk_packet = spp->smk_out->smk_known; ++ ssp->smk_packet = spp->smk_out; + break; + } + +@@ -2195,7 +2195,7 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name, + ssp = sock->sk->sk_security; + + if (strcmp(name, XATTR_SMACK_IPIN) == 0) +- ssp->smk_in = skp->smk_known; ++ ssp->smk_in = skp; + else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) { + ssp->smk_out = skp; + if (sock->sk->sk_family == PF_INET) { +@@ -3054,30 +3054,34 @@ static int smack_unix_stream_connect(struct sock *sock, + struct sock *other, struct sock *newsk) + { + 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 smk_audit_info ad; + int rc = 0; +- + #ifdef CONFIG_AUDIT + struct lsm_network_audit net; +- +- smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); +- smk_ad_setfield_u_net_sk(&ad, other); + #endif + + if (!smack_privileged(CAP_MAC_OVERRIDE)) { + skp = ssp->smk_out; +- rc = smk_access(skp, osp->smk_in, MAY_WRITE, &ad); ++ okp = osp->smk_out; ++#ifdef CONFIG_AUDIT ++ smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); ++ smk_ad_setfield_u_net_sk(&ad, other); ++#endif ++ rc = smk_access(skp, okp->smk_known, MAY_WRITE, &ad); ++ if (rc == 0) ++ rc = smk_access(okp, okp->smk_known, MAY_WRITE, NULL); + } + + /* + * Cross reference the peer labels for SO_PEERSEC. + */ + if (rc == 0) { +- nsp->smk_packet = ssp->smk_out->smk_known; +- ssp->smk_packet = osp->smk_out->smk_known; ++ nsp->smk_packet = ssp->smk_out; ++ ssp->smk_packet = osp->smk_out; + } + + return rc; +@@ -3109,7 +3113,7 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other) + return 0; + + skp = ssp->smk_out; +- return smk_access(skp, osp->smk_in, MAY_WRITE, &ad); ++ return smk_access(skp, osp->smk_in->smk_known, MAY_WRITE, &ad); + } + + /** +@@ -3204,7 +3208,7 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap, + if (found) + return skp; + +- if (ssp != NULL && ssp->smk_in == smack_known_star.smk_known) ++ if (ssp != NULL && ssp->smk_in == &smack_known_star) + return &smack_known_web; + return &smack_known_star; + } +@@ -3323,7 +3327,7 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) + * This is the simplist possible security model + * for networking. + */ +- rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad); ++ rc = smk_access(skp, ssp->smk_in->smk_known, MAY_WRITE, &ad); + if (rc != 0) + netlbl_skbuff_err(skb, rc, 0); + break; +@@ -3358,7 +3362,7 @@ static int smack_socket_getpeersec_stream(struct socket *sock, + + ssp = sock->sk->sk_security; + if (ssp->smk_packet != NULL) { +- rcp = ssp->smk_packet; ++ rcp = ssp->smk_packet->smk_known; + slen = strlen(rcp) + 1; + } + +@@ -3443,7 +3447,7 @@ static void smack_sock_graft(struct sock *sk, struct socket *parent) + return; + + ssp = sk->sk_security; +- ssp->smk_in = skp->smk_known; ++ ssp->smk_in = skp; + ssp->smk_out = skp; + /* cssp->smk_packet is already set in smack_inet_csk_clone() */ + } +@@ -3503,7 +3507,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, + * Receiving a packet requires that the other end be able to write + * here. Read access is not required. + */ +- rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad); ++ rc = smk_access(skp, ssp->smk_in->smk_known, MAY_WRITE, &ad); + if (rc != 0) + return rc; + +@@ -3547,7 +3551,7 @@ static void smack_inet_csk_clone(struct sock *sk, + + if (req->peer_secid != 0) { + skp = smack_from_secid(req->peer_secid); +- ssp->smk_packet = skp->smk_known; ++ ssp->smk_packet = skp; + } else + ssp->smk_packet = NULL; + } +-- +2.1.4 + |