DORMANTno replies

[PATCH 10/13] SCTP: enable per-namespace authentication configuration.

From: Jan Ariyasu <hidden>
Date: 2012-08-04 21:34:26
Also in: linux-sctp, lkml
Subsystem: networking [general], sctp protocol, the rest · Maintainers: "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Marcelo Ricardo Leitner, Xin Long, Linus Torvalds

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 <redacted>
---
 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
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help