lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Date:	Sat,  4 Aug 2012 15:34:07 -0600
From:	Jan Ariyasu <jan.ariyasu@...il.com>
To:	Vlad Yasevich <vyasevich@...il.com>,
	"David S. Miller" <davem@...emloft.net>,
	linux-sctp@...r.kernel.org, netdev@...r.kernel.org,
	linux-kernel@...r.kernel.org
Cc:	Jan Ariyasu <jan.ariyasu@...com>
Subject: [PATCH 10/13] SCTP: enable per-namespace authentication configuration.

This is the first of three patches to set authentication
by namespace.  In this patch, the relevant routines in auth.c
now check to see if auth_enable is set as a namespace parameter
instead of checking the global parameter sctp_auth_enable.

Signed-off-by: Jan Ariyasu <jan.ariyasu@...com>
---
 include/net/sctp/auth.h    |   14 +++++++++-----
 include/net/sctp/structs.h |    3 ++-
 net/sctp/associola.c       |    7 ++++---
 net/sctp/auth.c            |   29 +++++++++++++++++++----------
 net/sctp/chunk.c           |    5 +++--
 net/sctp/endpointola.c     |    6 ++++--
 net/sctp/sm_make_chunk.c   |    2 +-
 net/sctp/sm_sideeffect.c   |    2 +-
 net/sctp/sm_statefuns.c    |   16 ++++++++--------
 net/sctp/socket.c          |   10 ++++++----
 10 files changed, 57 insertions(+), 37 deletions(-)

diff --git a/include/net/sctp/auth.h b/include/net/sctp/auth.h
index 49bc957..e4e88cb 100644
--- a/include/net/sctp/auth.h
+++ b/include/net/sctp/auth.h
@@ -89,14 +89,15 @@ static inline void sctp_auth_key_hold(struct sctp_auth_bytes *key)
 void sctp_auth_key_put(struct sctp_auth_bytes *key);
 struct sctp_shared_key *sctp_auth_shkey_create(__u16 key_id, gfp_t gfp);
 void sctp_auth_destroy_keys(struct list_head *keys);
-int sctp_auth_asoc_init_active_key(struct sctp_association *asoc, gfp_t gfp);
+int sctp_auth_asoc_init_active_key(struct net *net,
+				   struct sctp_association *asoc, gfp_t gfp);
 struct sctp_shared_key *sctp_auth_get_shkey(
 				const struct sctp_association *asoc,
 				__u16 key_id);
 int sctp_auth_asoc_copy_shkeys(const struct sctp_endpoint *ep,
 				struct sctp_association *asoc,
 				gfp_t gfp);
-int sctp_auth_init_hmacs(struct sctp_endpoint *ep, gfp_t gfp);
+int sctp_auth_init_hmacs(struct net *net, struct sctp_endpoint *ep, gfp_t gfp);
 void sctp_auth_destroy_hmacs(struct crypto_hash *auth_hmacs[]);
 struct sctp_hmac *sctp_auth_get_hmac(__u16 hmac_id);
 struct sctp_hmac *sctp_auth_asoc_get_hmac(const struct sctp_association *asoc);
@@ -104,8 +105,10 @@ void sctp_auth_asoc_set_default_hmac(struct sctp_association *asoc,
 				     struct sctp_hmac_algo_param *hmacs);
 int sctp_auth_asoc_verify_hmac_id(const struct sctp_association *asoc,
 				    __be16 hmac_id);
-int sctp_auth_send_cid(sctp_cid_t chunk, const struct sctp_association *asoc);
-int sctp_auth_recv_cid(sctp_cid_t chunk, const struct sctp_association *asoc);
+int sctp_auth_send_cid(struct net *net,
+			sctp_cid_t chunk, const struct sctp_association *asoc);
+int sctp_auth_recv_cid(struct net *net,
+			sctp_cid_t chunk, const struct sctp_association *asoc);
 void sctp_auth_calculate_hmac(const struct sctp_association *asoc,
 			    struct sk_buff *skb,
 			    struct sctp_auth_chunk *auth, gfp_t gfp);
@@ -117,7 +120,8 @@ int sctp_auth_ep_set_hmacs(struct sctp_endpoint *ep,
 int sctp_auth_set_key(struct sctp_endpoint *ep,
 		      struct sctp_association *asoc,
 		      struct sctp_authkey *auth_key);
-int sctp_auth_set_active_key(struct sctp_endpoint *ep,
+int sctp_auth_set_active_key(struct net *net,
+		      struct sctp_endpoint *ep,
 		      struct sctp_association *asoc,
 		      __u16 key_id);
 int sctp_auth_del_key_id(struct sctp_endpoint *ep,
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index b016da6..dc2998a 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -805,7 +805,8 @@ struct sctp_datamsg {
 	   can_delay;	    /* should this message be Nagle delayed */
 };
 
-struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *,
+struct sctp_datamsg *sctp_datamsg_from_user(struct net *,
+					    struct sctp_association *,
 					    struct sctp_sndrcvinfo *,
 					    struct msghdr *, int len);
 void sctp_datamsg_free(struct sctp_datamsg *);
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index b778eba..b640162 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -1147,8 +1147,9 @@ static void sctp_assoc_bh_rcv(struct work_struct *work)
 		 *    MUST silently discard these chunks if they are not placed
 		 *    after an AUTH chunk in the packet.
 		 */
-		if (sctp_auth_recv_cid(subtype.chunk, asoc) && !chunk->auth)
-			continue;
+		if (sctp_auth_recv_cid(net, subtype.chunk, asoc) &&
+			!chunk->auth)
+				continue;
 
 		/* Remember where the last DATA chunk came from so we
 		 * know where to send the SACK.
@@ -1305,7 +1306,7 @@ void sctp_assoc_update(struct net *net,
 	new->peer.peer_hmacs = NULL;
 
 	sctp_auth_key_put(asoc->asoc_shared_key);
-	sctp_auth_asoc_init_active_key(asoc, GFP_ATOMIC);
+	sctp_auth_asoc_init_active_key(net, asoc, GFP_ATOMIC);
 }
 
 /* Update the retran path for sending a retransmitted packet.
diff --git a/net/sctp/auth.c b/net/sctp/auth.c
index bf81204..36d8059 100644
--- a/net/sctp/auth.c
+++ b/net/sctp/auth.c
@@ -390,15 +390,18 @@ nomem:
 /* Public interface to creat the association shared key.
  * See code above for the algorithm.
  */
-int sctp_auth_asoc_init_active_key(struct sctp_association *asoc, gfp_t gfp)
+int sctp_auth_asoc_init_active_key(struct net *net,
+				   struct sctp_association *asoc,
+				   gfp_t gfp)
 {
 	struct sctp_auth_bytes	*secret;
 	struct sctp_shared_key *ep_key;
+	struct sctp_net_params *net_params = sctp_get_params(net);
 
 	/* If we don't support AUTH, or peer is not capable
 	 * we don't need to do anything.
 	 */
-	if (!sctp_auth_enable || !asoc->peer.auth_capable)
+	if (!net_params->auth_enable || !asoc->peer.auth_capable)
 		return 0;
 
 	/* If the key_id is non-zero and we couldn't find an
@@ -443,13 +446,14 @@ struct sctp_shared_key *sctp_auth_get_shkey(
  * user context.  This forces us to pre-allocated all possible transforms
  * at the endpoint init time.
  */
-int sctp_auth_init_hmacs(struct sctp_endpoint *ep, gfp_t gfp)
+int sctp_auth_init_hmacs(struct net *net, struct sctp_endpoint *ep, gfp_t gfp)
 {
 	struct crypto_hash *tfm = NULL;
 	__u16   id;
+	struct sctp_net_params *net_params = sctp_get_params(net);
 
 	/* if the transforms are already allocted, we are done */
-	if (!sctp_auth_enable) {
+	if (!net_params->auth_enable) {
 		ep->auth_hmacs = NULL;
 		return 0;
 	}
@@ -672,18 +676,22 @@ static int __sctp_auth_cid(sctp_cid_t chunk, struct sctp_chunks_param *param)
 }
 
 /* Check if peer requested that this chunk is authenticated */
-int sctp_auth_send_cid(sctp_cid_t chunk, const struct sctp_association *asoc)
+int sctp_auth_send_cid(struct net *net, sctp_cid_t chunk,
+		       const struct sctp_association *asoc)
 {
-	if (!sctp_auth_enable || !asoc || !asoc->peer.auth_capable)
+	struct sctp_net_params *net_params = sctp_get_params(net);
+	if (!net_params->auth_enable || !asoc || !asoc->peer.auth_capable)
 		return 0;
 
 	return __sctp_auth_cid(chunk, asoc->peer.peer_chunks);
 }
 
 /* Check if we requested that peer authenticate this chunk. */
-int sctp_auth_recv_cid(sctp_cid_t chunk, const struct sctp_association *asoc)
+int sctp_auth_recv_cid(struct net *net, sctp_cid_t chunk,
+			const struct sctp_association *asoc)
 {
-	if (!sctp_auth_enable || !asoc)
+	struct sctp_net_params *net_params = sctp_get_params(net);
+	if (!net_params->auth_enable || !asoc)
 		return 0;
 
 	return __sctp_auth_cid(chunk,
@@ -876,7 +884,8 @@ nomem:
 	return -ENOMEM;
 }
 
-int sctp_auth_set_active_key(struct sctp_endpoint *ep,
+int sctp_auth_set_active_key(struct net *net,
+			     struct sctp_endpoint *ep,
 			     struct sctp_association *asoc,
 			     __u16  key_id)
 {
@@ -902,7 +911,7 @@ int sctp_auth_set_active_key(struct sctp_endpoint *ep,
 
 	if (asoc) {
 		asoc->active_key_id = key_id;
-		sctp_auth_asoc_init_active_key(asoc, GFP_KERNEL);
+		sctp_auth_asoc_init_active_key(net, asoc, GFP_KERNEL);
 	} else
 		ep->active_key_id = key_id;
 
diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c
index 6c85564..5211278 100644
--- a/net/sctp/chunk.c
+++ b/net/sctp/chunk.c
@@ -169,7 +169,8 @@ static void sctp_datamsg_assign(struct sctp_datamsg *msg, struct sctp_chunk *chu
  * with a reasonable guess than always doing our fragmentation on the
  * soft-interrupt.
  */
-struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
+struct sctp_datamsg *sctp_datamsg_from_user(struct net *net,
+					    struct sctp_association *asoc,
 					    struct sctp_sndrcvinfo *sinfo,
 					    struct msghdr *msgh, int msg_len)
 {
@@ -209,7 +210,7 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
 	 * we need to accound for bundling of the AUTH chunks along with
 	 * DATA.
 	 */
-	if (sctp_auth_send_cid(SCTP_CID_DATA, asoc)) {
+	if (sctp_auth_send_cid(net, SCTP_CID_DATA, asoc)) {
 		struct sctp_hmac *hmac_desc = sctp_auth_asoc_get_hmac(asoc);
 
 		if (hmac_desc)
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c
index de42bd4..750df47 100644
--- a/net/sctp/endpointola.c
+++ b/net/sctp/endpointola.c
@@ -69,6 +69,7 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
 	struct sctp_chunks_param *auth_chunks = NULL;
 	struct sctp_shared_key *null_key;
 	int err;
+	struct net *net = sock_net(sk);
 
 	ep->digest = kzalloc(SCTP_SIGNATURE_SIZE, gfp);
 	if (!ep->digest)
@@ -163,7 +164,7 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
 	list_add(&null_key->key_list, &ep->endpoint_shared_keys);
 
 	/* Allocate and initialize transorms arrays for suported HMACs. */
-	err = sctp_auth_init_hmacs(ep, gfp);
+	err = sctp_auth_init_hmacs(net, ep, gfp);
 	if (err)
 		goto nomem_hmacs;
 
@@ -465,7 +466,8 @@ normal:
 		}
 
 		state = asoc ? asoc->state : SCTP_STATE_CLOSED;
-		if (sctp_auth_recv_cid(subtype.chunk, asoc) && !chunk->auth)
+		if (sctp_auth_recv_cid(sock_net(sk), subtype.chunk, asoc)
+			&& !chunk->auth)
 			continue;
 
 		/* Remember where the last DATA chunk came from so we
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index af02b44..1d6c8b6 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -1365,7 +1365,7 @@ struct sctp_chunk *sctp_make_chunk(const struct sctp_association *asoc,
 	retval->chunk_end = ((__u8 *)chunk_hdr) + sizeof(struct sctp_chunkhdr);
 
 	/* Determine if the chunk needs to be authenticated */
-	if (sctp_auth_send_cid(type, asoc))
+	if (sctp_auth_send_cid(&init_net, type, asoc))
 		retval->auth = 1;
 
 	/* Set the skb to the belonging sock for accounting.  */
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index c683d88..7bd2d6d 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -1711,7 +1711,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
 			break;
 
 		case SCTP_CMD_ASSOC_SHKEY:
-			error = sctp_auth_asoc_init_active_key(asoc,
+			error = sctp_auth_asoc_init_active_key(net, asoc,
 						GFP_ATOMIC);
 			break;
 		case SCTP_CMD_UPDATE_INITTAG:
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 0d4aaa9..4cd027a 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -572,14 +572,14 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(struct net *net,
 		 * can't destroy this association just because the packet
 		 * was malformed.
 		 */
-		if (sctp_auth_recv_cid(SCTP_CID_ABORT, asoc))
-			return sctp_sf_pdiscard(net, ep, asoc, type, arg,
-						commands);
+		if (sctp_auth_recv_cid(net, SCTP_CID_ABORT, asoc))
+			return sctp_sf_pdiscard(net, ep, asoc, type,
+						arg, commands);
 
 		SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
 		return sctp_stop_t1_and_abort(net, commands, error,
-					      ECONNREFUSED, asoc,
-					      chunk->transport);
+						ECONNREFUSED,
+						asoc, chunk->transport);
 	}
 
 	/* Tag the variable length parameters.  Note that we never
@@ -757,7 +757,7 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(struct net *net,
 	 * sctp_process_init, set up the assocaition shared keys as
 	 * necessary so that we can potentially authenticate the ACK
 	 */
-	error = sctp_auth_asoc_init_active_key(new_asoc, GFP_ATOMIC);
+	error = sctp_auth_asoc_init_active_key(net, new_asoc, GFP_ATOMIC);
 	if (error)
 		goto nomem_init;
 
@@ -4364,7 +4364,7 @@ static sctp_disposition_t sctp_sf_abort_violation(
 	 * can't destroy this association just because the packet
 	 * was malformed.
 	 */
-	if (sctp_auth_recv_cid(SCTP_CID_ABORT, asoc))
+	if (sctp_auth_recv_cid(net, SCTP_CID_ABORT, asoc))
 		goto discard;
 
 	/* Make the abort chunk. */
@@ -4490,7 +4490,7 @@ static sctp_disposition_t sctp_sf_violation_paramlen(
 	struct sctp_paramhdr *param = ext;
 	struct sctp_chunk *abort = NULL;
 
-	if (sctp_auth_recv_cid(SCTP_CID_ABORT, asoc))
+	if (sctp_auth_recv_cid(net, SCTP_CID_ABORT, asoc))
 		goto discard;
 
 	/* Make the abort chunk. */
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 78e4576..d14ac7d 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -101,9 +101,9 @@ static struct sctp_af *sctp_sockaddr_af(struct sctp_sock *opt,
 					union sctp_addr *addr, int len);
 static int sctp_bindx_add(struct sock *, struct sockaddr *, int);
 static int sctp_bindx_rem(struct sock *, struct sockaddr *, int);
-static int sctp_send_asconf_add_ip(struct net*, struct sock *,
+static int sctp_send_asconf_add_ip(struct net *, struct sock *,
 				   struct sockaddr *, int);
-static int sctp_send_asconf_del_ip(struct net*, struct sock *,
+static int sctp_send_asconf_del_ip(struct net *, struct sock *,
 				   struct sockaddr *, int);
 static int sctp_send_asconf(struct sctp_association *asoc,
 			    struct sctp_chunk *chunk);
@@ -1599,6 +1599,7 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
 	__u16 sinfo_flags = 0;
 	struct sctp_datamsg *datamsg;
 	int msg_flags = msg->msg_flags;
+	struct net *net = sock_net(sk);
 
 	SCTP_DEBUG_PRINTK("sctp_sendmsg(sk: %p, msg: %p, msg_len: %zu)\n",
 			  sk, msg, msg_len);
@@ -1920,7 +1921,7 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
 	}
 
 	/* Break the message into multiple chunks of maximum size. */
-	datamsg = sctp_datamsg_from_user(asoc, sinfo, msg, msg_len);
+	datamsg = sctp_datamsg_from_user(net, asoc, sinfo, msg, msg_len);
 	if (!datamsg) {
 		err = -ENOMEM;
 		goto out_free;
@@ -3409,6 +3410,7 @@ static int sctp_setsockopt_active_key(struct sock *sk,
 {
 	struct sctp_authkeyid val;
 	struct sctp_association *asoc;
+	struct net *net = sock_net(sk);
 
 	if (!sctp_auth_enable)
 		return -EACCES;
@@ -3422,7 +3424,7 @@ static int sctp_setsockopt_active_key(struct sock *sk,
 	if (!asoc && val.scact_assoc_id && sctp_style(sk, UDP))
 		return -EINVAL;
 
-	return sctp_auth_set_active_key(sctp_sk(sk)->ep, asoc,
+	return sctp_auth_set_active_key(net, sctp_sk(sk)->ep, asoc,
 					val.scact_keynumber);
 }
 
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ