summaryrefslogtreecommitdiffstats
path: root/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0030-Smack-bidirectional-UDS-connect-check.patch
diff options
context:
space:
mode:
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.patch204
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
+