Skip to content

Commit 5483ece

Browse files
committed
Merge branch 'sctp-support-per-endpoint-auth-and-asconf-flags'
Xin Long says: ==================== sctp: support per endpoint auth and asconf flags This patchset mostly does 3 things: 1. add per endpint asconf flag and use asconf flag properly and add SCTP_ASCONF_SUPPORTED sockopt. 2. use auth flag properly and add SCTP_AUTH_SUPPORTED sockopt. 3. remove the 'global feature switch' to discard chunks. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents af80970 + 2f75763 commit 5483ece

File tree

10 files changed

+325
-136
lines changed

10 files changed

+325
-136
lines changed

include/net/sctp/auth.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,5 +107,7 @@ int sctp_auth_del_key_id(struct sctp_endpoint *ep,
107107
struct sctp_association *asoc, __u16 key_id);
108108
int sctp_auth_deact_key_id(struct sctp_endpoint *ep,
109109
struct sctp_association *asoc, __u16 key_id);
110+
int sctp_auth_init(struct sctp_endpoint *ep, gfp_t gfp);
111+
void sctp_auth_free(struct sctp_endpoint *ep);
110112

111113
#endif

include/net/sctp/structs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1325,6 +1325,7 @@ struct sctp_endpoint {
13251325
__u8 auth_enable:1,
13261326
intl_enable:1,
13271327
prsctp_enable:1,
1328+
asconf_enable:1,
13281329
reconf_enable:1;
13291330

13301331
__u8 strreset_enable;

include/uapi/linux/sctp.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ typedef __s32 sctp_assoc_t;
134134
#define SCTP_INTERLEAVING_SUPPORTED 125
135135
#define SCTP_SENDMSG_CONNECT 126
136136
#define SCTP_EVENT 127
137+
#define SCTP_ASCONF_SUPPORTED 128
138+
#define SCTP_AUTH_SUPPORTED 129
137139

138140
/* PR-SCTP policies */
139141
#define SCTP_PR_SCTP_NONE 0x0000

net/sctp/associola.c

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ static struct sctp_association *sctp_association_init(
5454
const struct sock *sk,
5555
enum sctp_scope scope, gfp_t gfp)
5656
{
57-
struct net *net = sock_net(sk);
5857
struct sctp_sock *sp;
5958
struct sctp_paramhdr *p;
6059
int i;
@@ -214,14 +213,6 @@ static struct sctp_association *sctp_association_init(
214213
asoc->peer.sack_needed = 1;
215214
asoc->peer.sack_generation = 1;
216215

217-
/* Assume that the peer will tell us if he recognizes ASCONF
218-
* as part of INIT exchange.
219-
* The sctp_addip_noauth option is there for backward compatibility
220-
* and will revert old behavior.
221-
*/
222-
if (net->sctp.addip_noauth)
223-
asoc->peer.asconf_capable = 1;
224-
225216
/* Create an input queue. */
226217
sctp_inq_init(&asoc->base.inqueue);
227218
sctp_inq_set_th_handler(&asoc->base.inqueue, sctp_assoc_bh_rcv);

net/sctp/auth.c

Lines changed: 94 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ int sctp_auth_asoc_init_active_key(struct sctp_association *asoc, gfp_t gfp)
389389
/* If we don't support AUTH, or peer is not capable
390390
* we don't need to do anything.
391391
*/
392-
if (!asoc->ep->auth_enable || !asoc->peer.auth_capable)
392+
if (!asoc->peer.auth_capable)
393393
return 0;
394394

395395
/* If the key_id is non-zero and we couldn't find an
@@ -675,7 +675,7 @@ int sctp_auth_send_cid(enum sctp_cid chunk, const struct sctp_association *asoc)
675675
if (!asoc)
676676
return 0;
677677

678-
if (!asoc->ep->auth_enable || !asoc->peer.auth_capable)
678+
if (!asoc->peer.auth_capable)
679679
return 0;
680680

681681
return __sctp_auth_cid(chunk, asoc->peer.peer_chunks);
@@ -687,7 +687,7 @@ int sctp_auth_recv_cid(enum sctp_cid chunk, const struct sctp_association *asoc)
687687
if (!asoc)
688688
return 0;
689689

690-
if (!asoc->ep->auth_enable)
690+
if (!asoc->peer.auth_capable)
691691
return 0;
692692

693693
return __sctp_auth_cid(chunk,
@@ -831,10 +831,15 @@ int sctp_auth_set_key(struct sctp_endpoint *ep,
831831
/* Try to find the given key id to see if
832832
* we are doing a replace, or adding a new key
833833
*/
834-
if (asoc)
834+
if (asoc) {
835+
if (!asoc->peer.auth_capable)
836+
return -EACCES;
835837
sh_keys = &asoc->endpoint_shared_keys;
836-
else
838+
} else {
839+
if (!ep->auth_enable)
840+
return -EACCES;
837841
sh_keys = &ep->endpoint_shared_keys;
842+
}
838843

839844
key_for_each(shkey, sh_keys) {
840845
if (shkey->key_id == auth_key->sca_keynumber) {
@@ -875,10 +880,15 @@ int sctp_auth_set_active_key(struct sctp_endpoint *ep,
875880
int found = 0;
876881

877882
/* The key identifier MUST correst to an existing key */
878-
if (asoc)
883+
if (asoc) {
884+
if (!asoc->peer.auth_capable)
885+
return -EACCES;
879886
sh_keys = &asoc->endpoint_shared_keys;
880-
else
887+
} else {
888+
if (!ep->auth_enable)
889+
return -EACCES;
881890
sh_keys = &ep->endpoint_shared_keys;
891+
}
882892

883893
key_for_each(key, sh_keys) {
884894
if (key->key_id == key_id) {
@@ -911,11 +921,15 @@ int sctp_auth_del_key_id(struct sctp_endpoint *ep,
911921
* The key identifier MUST correst to an existing key
912922
*/
913923
if (asoc) {
924+
if (!asoc->peer.auth_capable)
925+
return -EACCES;
914926
if (asoc->active_key_id == key_id)
915927
return -EINVAL;
916928

917929
sh_keys = &asoc->endpoint_shared_keys;
918930
} else {
931+
if (!ep->auth_enable)
932+
return -EACCES;
919933
if (ep->active_key_id == key_id)
920934
return -EINVAL;
921935

@@ -950,11 +964,15 @@ int sctp_auth_deact_key_id(struct sctp_endpoint *ep,
950964
* The key identifier MUST correst to an existing key
951965
*/
952966
if (asoc) {
967+
if (!asoc->peer.auth_capable)
968+
return -EACCES;
953969
if (asoc->active_key_id == key_id)
954970
return -EINVAL;
955971

956972
sh_keys = &asoc->endpoint_shared_keys;
957973
} else {
974+
if (!ep->auth_enable)
975+
return -EACCES;
958976
if (ep->active_key_id == key_id)
959977
return -EINVAL;
960978

@@ -989,3 +1007,72 @@ int sctp_auth_deact_key_id(struct sctp_endpoint *ep,
9891007

9901008
return 0;
9911009
}
1010+
1011+
int sctp_auth_init(struct sctp_endpoint *ep, gfp_t gfp)
1012+
{
1013+
int err = -ENOMEM;
1014+
1015+
/* Allocate space for HMACS and CHUNKS authentication
1016+
* variables. There are arrays that we encode directly
1017+
* into parameters to make the rest of the operations easier.
1018+
*/
1019+
if (!ep->auth_hmacs_list) {
1020+
struct sctp_hmac_algo_param *auth_hmacs;
1021+
1022+
auth_hmacs = kzalloc(struct_size(auth_hmacs, hmac_ids,
1023+
SCTP_AUTH_NUM_HMACS), gfp);
1024+
if (!auth_hmacs)
1025+
goto nomem;
1026+
/* Initialize the HMACS parameter.
1027+
* SCTP-AUTH: Section 3.3
1028+
* Every endpoint supporting SCTP chunk authentication MUST
1029+
* support the HMAC based on the SHA-1 algorithm.
1030+
*/
1031+
auth_hmacs->param_hdr.type = SCTP_PARAM_HMAC_ALGO;
1032+
auth_hmacs->param_hdr.length =
1033+
htons(sizeof(struct sctp_paramhdr) + 2);
1034+
auth_hmacs->hmac_ids[0] = htons(SCTP_AUTH_HMAC_ID_SHA1);
1035+
ep->auth_hmacs_list = auth_hmacs;
1036+
}
1037+
1038+
if (!ep->auth_chunk_list) {
1039+
struct sctp_chunks_param *auth_chunks;
1040+
1041+
auth_chunks = kzalloc(sizeof(*auth_chunks) +
1042+
SCTP_NUM_CHUNK_TYPES, gfp);
1043+
if (!auth_chunks)
1044+
goto nomem;
1045+
/* Initialize the CHUNKS parameter */
1046+
auth_chunks->param_hdr.type = SCTP_PARAM_CHUNKS;
1047+
auth_chunks->param_hdr.length =
1048+
htons(sizeof(struct sctp_paramhdr));
1049+
ep->auth_chunk_list = auth_chunks;
1050+
}
1051+
1052+
/* Allocate and initialize transorms arrays for supported
1053+
* HMACs.
1054+
*/
1055+
err = sctp_auth_init_hmacs(ep, gfp);
1056+
if (err)
1057+
goto nomem;
1058+
1059+
return 0;
1060+
1061+
nomem:
1062+
/* Free all allocations */
1063+
kfree(ep->auth_hmacs_list);
1064+
kfree(ep->auth_chunk_list);
1065+
ep->auth_hmacs_list = NULL;
1066+
ep->auth_chunk_list = NULL;
1067+
return err;
1068+
}
1069+
1070+
void sctp_auth_free(struct sctp_endpoint *ep)
1071+
{
1072+
kfree(ep->auth_hmacs_list);
1073+
kfree(ep->auth_chunk_list);
1074+
ep->auth_hmacs_list = NULL;
1075+
ep->auth_chunk_list = NULL;
1076+
sctp_auth_destroy_hmacs(ep->auth_hmacs);
1077+
ep->auth_hmacs = NULL;
1078+
}

net/sctp/endpointola.c

Lines changed: 7 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -43,62 +43,21 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
4343
gfp_t gfp)
4444
{
4545
struct net *net = sock_net(sk);
46-
struct sctp_hmac_algo_param *auth_hmacs = NULL;
47-
struct sctp_chunks_param *auth_chunks = NULL;
4846
struct sctp_shared_key *null_key;
49-
int err;
5047

5148
ep->digest = kzalloc(SCTP_SIGNATURE_SIZE, gfp);
5249
if (!ep->digest)
5350
return NULL;
5451

52+
ep->asconf_enable = net->sctp.addip_enable;
5553
ep->auth_enable = net->sctp.auth_enable;
5654
if (ep->auth_enable) {
57-
/* Allocate space for HMACS and CHUNKS authentication
58-
* variables. There are arrays that we encode directly
59-
* into parameters to make the rest of the operations easier.
60-
*/
61-
auth_hmacs = kzalloc(struct_size(auth_hmacs, hmac_ids,
62-
SCTP_AUTH_NUM_HMACS), gfp);
63-
if (!auth_hmacs)
64-
goto nomem;
65-
66-
auth_chunks = kzalloc(sizeof(*auth_chunks) +
67-
SCTP_NUM_CHUNK_TYPES, gfp);
68-
if (!auth_chunks)
55+
if (sctp_auth_init(ep, gfp))
6956
goto nomem;
70-
71-
/* Initialize the HMACS parameter.
72-
* SCTP-AUTH: Section 3.3
73-
* Every endpoint supporting SCTP chunk authentication MUST
74-
* support the HMAC based on the SHA-1 algorithm.
75-
*/
76-
auth_hmacs->param_hdr.type = SCTP_PARAM_HMAC_ALGO;
77-
auth_hmacs->param_hdr.length =
78-
htons(sizeof(struct sctp_paramhdr) + 2);
79-
auth_hmacs->hmac_ids[0] = htons(SCTP_AUTH_HMAC_ID_SHA1);
80-
81-
/* Initialize the CHUNKS parameter */
82-
auth_chunks->param_hdr.type = SCTP_PARAM_CHUNKS;
83-
auth_chunks->param_hdr.length =
84-
htons(sizeof(struct sctp_paramhdr));
85-
86-
/* If the Add-IP functionality is enabled, we must
87-
* authenticate, ASCONF and ASCONF-ACK chunks
88-
*/
89-
if (net->sctp.addip_enable) {
90-
auth_chunks->chunks[0] = SCTP_CID_ASCONF;
91-
auth_chunks->chunks[1] = SCTP_CID_ASCONF_ACK;
92-
auth_chunks->param_hdr.length =
93-
htons(sizeof(struct sctp_paramhdr) + 2);
57+
if (ep->asconf_enable) {
58+
sctp_auth_ep_add_chunkid(ep, SCTP_CID_ASCONF);
59+
sctp_auth_ep_add_chunkid(ep, SCTP_CID_ASCONF_ACK);
9460
}
95-
96-
/* Allocate and initialize transorms arrays for supported
97-
* HMACs.
98-
*/
99-
err = sctp_auth_init_hmacs(ep, gfp);
100-
if (err)
101-
goto nomem;
10261
}
10362

10463
/* Initialize the base structure. */
@@ -145,8 +104,6 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
145104
/* Add the null key to the endpoint shared keys list and
146105
* set the hmcas and chunks pointers.
147106
*/
148-
ep->auth_hmacs_list = auth_hmacs;
149-
ep->auth_chunk_list = auth_chunks;
150107
ep->prsctp_enable = net->sctp.prsctp_enable;
151108
ep->reconf_enable = net->sctp.reconf_enable;
152109

@@ -157,11 +114,8 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
157114
return ep;
158115

159116
nomem_shkey:
160-
sctp_auth_destroy_hmacs(ep->auth_hmacs);
117+
sctp_auth_free(ep);
161118
nomem:
162-
/* Free all allocations */
163-
kfree(auth_hmacs);
164-
kfree(auth_chunks);
165119
kfree(ep->digest);
166120
return NULL;
167121

@@ -244,11 +198,7 @@ static void sctp_endpoint_destroy(struct sctp_endpoint *ep)
244198
* chunks and hmacs arrays that were allocated
245199
*/
246200
sctp_auth_destroy_keys(&ep->endpoint_shared_keys);
247-
kfree(ep->auth_hmacs_list);
248-
kfree(ep->auth_chunk_list);
249-
250-
/* AUTH - Free any allocated HMAC transform containers */
251-
sctp_auth_destroy_hmacs(ep->auth_hmacs);
201+
sctp_auth_free(ep);
252202

253203
/* Cleanup. */
254204
sctp_inq_free(&ep->base.inqueue);

net/sctp/sm_make_chunk.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,6 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
207207
const struct sctp_bind_addr *bp,
208208
gfp_t gfp, int vparam_len)
209209
{
210-
struct net *net = sock_net(asoc->base.sk);
211210
struct sctp_supported_ext_param ext_param;
212211
struct sctp_adaptation_ind_param aiparam;
213212
struct sctp_paramhdr *auth_chunks = NULL;
@@ -255,7 +254,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
255254
* the ASCONF,the ASCONF-ACK, and the AUTH chunks in its INIT and
256255
* INIT-ACK parameters.
257256
*/
258-
if (net->sctp.addip_enable) {
257+
if (asoc->ep->asconf_enable) {
259258
extensions[num_ext] = SCTP_CID_ASCONF;
260259
extensions[num_ext+1] = SCTP_CID_ASCONF_ACK;
261260
num_ext += 2;
@@ -1964,7 +1963,9 @@ static int sctp_process_hn_param(const struct sctp_association *asoc,
19641963
return 0;
19651964
}
19661965

1967-
static int sctp_verify_ext_param(struct net *net, union sctp_params param)
1966+
static int sctp_verify_ext_param(struct net *net,
1967+
const struct sctp_endpoint *ep,
1968+
union sctp_params param)
19681969
{
19691970
__u16 num_ext = ntohs(param.p->length) - sizeof(struct sctp_paramhdr);
19701971
int have_asconf = 0;
@@ -1991,7 +1992,7 @@ static int sctp_verify_ext_param(struct net *net, union sctp_params param)
19911992
if (net->sctp.addip_noauth)
19921993
return 1;
19931994

1994-
if (net->sctp.addip_enable && !have_auth && have_asconf)
1995+
if (ep->asconf_enable && !have_auth && have_asconf)
19951996
return 0;
19961997

19971998
return 1;
@@ -2001,7 +2002,6 @@ static void sctp_process_ext_param(struct sctp_association *asoc,
20012002
union sctp_params param)
20022003
{
20032004
__u16 num_ext = ntohs(param.p->length) - sizeof(struct sctp_paramhdr);
2004-
struct net *net = sock_net(asoc->base.sk);
20052005
int i;
20062006

20072007
for (i = 0; i < num_ext; i++) {
@@ -2023,7 +2023,7 @@ static void sctp_process_ext_param(struct sctp_association *asoc,
20232023
break;
20242024
case SCTP_CID_ASCONF:
20252025
case SCTP_CID_ASCONF_ACK:
2026-
if (net->sctp.addip_enable)
2026+
if (asoc->ep->asconf_enable)
20272027
asoc->peer.asconf_capable = 1;
20282028
break;
20292029
case SCTP_CID_I_DATA:
@@ -2145,12 +2145,12 @@ static enum sctp_ierror sctp_verify_param(struct net *net,
21452145
break;
21462146

21472147
case SCTP_PARAM_SUPPORTED_EXT:
2148-
if (!sctp_verify_ext_param(net, param))
2148+
if (!sctp_verify_ext_param(net, ep, param))
21492149
return SCTP_IERROR_ABORT;
21502150
break;
21512151

21522152
case SCTP_PARAM_SET_PRIMARY:
2153-
if (net->sctp.addip_enable)
2153+
if (ep->asconf_enable)
21542154
break;
21552155
goto fallthrough;
21562156

@@ -2605,7 +2605,7 @@ static int sctp_process_param(struct sctp_association *asoc,
26052605
break;
26062606

26072607
case SCTP_PARAM_SET_PRIMARY:
2608-
if (!net->sctp.addip_enable)
2608+
if (!ep->asconf_enable)
26092609
goto fall_through;
26102610

26112611
addr_param = param.v + sizeof(struct sctp_addip_param);

0 commit comments

Comments
 (0)