Skip to content

Commit c081d53

Browse files
lxindavem330
authored andcommitted
security: pass asoc to sctp_assoc_request and sctp_sk_clone
This patch is to move secid and peer_secid from endpoint to association, and pass asoc to sctp_assoc_request and sctp_sk_clone instead of ep. As ep is the local endpoint and asoc represents a connection, and in SCTP one sk/ep could have multiple asoc/connection, saving secid/peer_secid for new asoc will overwrite the old asoc's. Note that since asoc can be passed as NULL, security_sctp_assoc_request() is moved to the place right after the new_asoc is created in sctp_sf_do_5_1B_init() and sctp_sf_do_unexpected_init(). v1->v2: - fix the description of selinux_netlbl_skbuff_setsid(), as Jakub noticed. - fix the annotation in selinux_sctp_assoc_request(), as Richard Noticed. Fixes: 72e89f5 ("security: Add support for SCTP security hooks") Reported-by: Prashanth Prahlad <[email protected]> Reviewed-by: Richard Haines <[email protected]> Tested-by: Richard Haines <[email protected]> Signed-off-by: Xin Long <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 843c3cb commit c081d53

File tree

11 files changed

+76
-77
lines changed

11 files changed

+76
-77
lines changed

Documentation/security/SCTP.rst

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@ described in the `SCTP SELinux Support`_ chapter.
2626

2727
security_sctp_assoc_request()
2828
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
29-
Passes the ``@ep`` and ``@chunk->skb`` of the association INIT packet to the
29+
Passes the ``@asoc`` and ``@chunk->skb`` of the association INIT packet to the
3030
security module. Returns 0 on success, error on failure.
3131
::
3232

33-
@ep - pointer to sctp endpoint structure.
33+
@asoc - pointer to sctp association structure.
3434
@skb - pointer to skbuff of association packet.
3535

3636

@@ -117,9 +117,9 @@ Called whenever a new socket is created by **accept**\(2)
117117
calls **sctp_peeloff**\(3).
118118
::
119119

120-
@ep - pointer to current sctp endpoint structure.
120+
@asoc - pointer to current sctp association structure.
121121
@sk - pointer to current sock structure.
122-
@sk - pointer to new sock structure.
122+
@newsk - pointer to new sock structure.
123123

124124

125125
security_inet_conn_established()
@@ -200,22 +200,22 @@ hooks with the SELinux specifics expanded below::
200200

201201
security_sctp_assoc_request()
202202
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
203-
Passes the ``@ep`` and ``@chunk->skb`` of the association INIT packet to the
203+
Passes the ``@asoc`` and ``@chunk->skb`` of the association INIT packet to the
204204
security module. Returns 0 on success, error on failure.
205205
::
206206

207-
@ep - pointer to sctp endpoint structure.
207+
@asoc - pointer to sctp association structure.
208208
@skb - pointer to skbuff of association packet.
209209

210210
The security module performs the following operations:
211-
IF this is the first association on ``@ep->base.sk``, then set the peer
211+
IF this is the first association on ``@asoc->base.sk``, then set the peer
212212
sid to that in ``@skb``. This will ensure there is only one peer sid
213-
assigned to ``@ep->base.sk`` that may support multiple associations.
213+
assigned to ``@asoc->base.sk`` that may support multiple associations.
214214

215-
ELSE validate the ``@ep->base.sk peer_sid`` against the ``@skb peer sid``
215+
ELSE validate the ``@asoc->base.sk peer_sid`` against the ``@skb peer sid``
216216
to determine whether the association should be allowed or denied.
217217

218-
Set the sctp ``@ep sid`` to socket's sid (from ``ep->base.sk``) with
218+
Set the sctp ``@asoc sid`` to socket's sid (from ``asoc->base.sk``) with
219219
MLS portion taken from ``@skb peer sid``. This will be used by SCTP
220220
TCP style sockets and peeled off connections as they cause a new socket
221221
to be generated.
@@ -259,13 +259,13 @@ security_sctp_sk_clone()
259259
Called whenever a new socket is created by **accept**\(2) (i.e. a TCP style
260260
socket) or when a socket is 'peeled off' e.g userspace calls
261261
**sctp_peeloff**\(3). ``security_sctp_sk_clone()`` will set the new
262-
sockets sid and peer sid to that contained in the ``@ep sid`` and
263-
``@ep peer sid`` respectively.
262+
sockets sid and peer sid to that contained in the ``@asoc sid`` and
263+
``@asoc peer sid`` respectively.
264264
::
265265

266-
@ep - pointer to current sctp endpoint structure.
266+
@asoc - pointer to current sctp association structure.
267267
@sk - pointer to current sock structure.
268-
@sk - pointer to new sock structure.
268+
@newsk - pointer to new sock structure.
269269

270270

271271
security_inet_conn_established()

include/linux/lsm_hook_defs.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -329,11 +329,11 @@ LSM_HOOK(int, 0, tun_dev_create, void)
329329
LSM_HOOK(int, 0, tun_dev_attach_queue, void *security)
330330
LSM_HOOK(int, 0, tun_dev_attach, struct sock *sk, void *security)
331331
LSM_HOOK(int, 0, tun_dev_open, void *security)
332-
LSM_HOOK(int, 0, sctp_assoc_request, struct sctp_endpoint *ep,
332+
LSM_HOOK(int, 0, sctp_assoc_request, struct sctp_association *asoc,
333333
struct sk_buff *skb)
334334
LSM_HOOK(int, 0, sctp_bind_connect, struct sock *sk, int optname,
335335
struct sockaddr *address, int addrlen)
336-
LSM_HOOK(void, LSM_RET_VOID, sctp_sk_clone, struct sctp_endpoint *ep,
336+
LSM_HOOK(void, LSM_RET_VOID, sctp_sk_clone, struct sctp_association *asoc,
337337
struct sock *sk, struct sock *newsk)
338338
#endif /* CONFIG_SECURITY_NETWORK */
339339

include/linux/lsm_hooks.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1027,9 +1027,9 @@
10271027
* Security hooks for SCTP
10281028
*
10291029
* @sctp_assoc_request:
1030-
* Passes the @ep and @chunk->skb of the association INIT packet to
1030+
* Passes the @asoc and @chunk->skb of the association INIT packet to
10311031
* the security module.
1032-
* @ep pointer to sctp endpoint structure.
1032+
* @asoc pointer to sctp association structure.
10331033
* @skb pointer to skbuff of association packet.
10341034
* Return 0 on success, error on failure.
10351035
* @sctp_bind_connect:
@@ -1047,9 +1047,9 @@
10471047
* Called whenever a new socket is created by accept(2) (i.e. a TCP
10481048
* style socket) or when a socket is 'peeled off' e.g userspace
10491049
* calls sctp_peeloff(3).
1050-
* @ep pointer to current sctp endpoint structure.
1050+
* @asoc pointer to current sctp association structure.
10511051
* @sk pointer to current sock structure.
1052-
* @sk pointer to new sock structure.
1052+
* @newsk pointer to new sock structure.
10531053
*
10541054
* Security hooks for Infiniband
10551055
*

include/linux/security.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ struct xfrm_policy;
179179
struct xfrm_state;
180180
struct xfrm_user_sec_ctx;
181181
struct seq_file;
182-
struct sctp_endpoint;
182+
struct sctp_association;
183183

184184
#ifdef CONFIG_MMU
185185
extern unsigned long mmap_min_addr;
@@ -1425,10 +1425,10 @@ int security_tun_dev_create(void);
14251425
int security_tun_dev_attach_queue(void *security);
14261426
int security_tun_dev_attach(struct sock *sk, void *security);
14271427
int security_tun_dev_open(void *security);
1428-
int security_sctp_assoc_request(struct sctp_endpoint *ep, struct sk_buff *skb);
1428+
int security_sctp_assoc_request(struct sctp_association *asoc, struct sk_buff *skb);
14291429
int security_sctp_bind_connect(struct sock *sk, int optname,
14301430
struct sockaddr *address, int addrlen);
1431-
void security_sctp_sk_clone(struct sctp_endpoint *ep, struct sock *sk,
1431+
void security_sctp_sk_clone(struct sctp_association *asoc, struct sock *sk,
14321432
struct sock *newsk);
14331433

14341434
#else /* CONFIG_SECURITY_NETWORK */
@@ -1631,7 +1631,7 @@ static inline int security_tun_dev_open(void *security)
16311631
return 0;
16321632
}
16331633

1634-
static inline int security_sctp_assoc_request(struct sctp_endpoint *ep,
1634+
static inline int security_sctp_assoc_request(struct sctp_association *asoc,
16351635
struct sk_buff *skb)
16361636
{
16371637
return 0;
@@ -1644,7 +1644,7 @@ static inline int security_sctp_bind_connect(struct sock *sk, int optname,
16441644
return 0;
16451645
}
16461646

1647-
static inline void security_sctp_sk_clone(struct sctp_endpoint *ep,
1647+
static inline void security_sctp_sk_clone(struct sctp_association *asoc,
16481648
struct sock *sk,
16491649
struct sock *newsk)
16501650
{

include/net/sctp/structs.h

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1355,16 +1355,6 @@ struct sctp_endpoint {
13551355
reconf_enable:1;
13561356

13571357
__u8 strreset_enable;
1358-
1359-
/* Security identifiers from incoming (INIT). These are set by
1360-
* security_sctp_assoc_request(). These will only be used by
1361-
* SCTP TCP type sockets and peeled off connections as they
1362-
* cause a new socket to be generated. security_sctp_sk_clone()
1363-
* will then plug these into the new socket.
1364-
*/
1365-
1366-
u32 secid;
1367-
u32 peer_secid;
13681358
};
13691359

13701360
/* Recover the outter endpoint structure. */
@@ -2104,6 +2094,16 @@ struct sctp_association {
21042094
__u64 abandoned_unsent[SCTP_PR_INDEX(MAX) + 1];
21052095
__u64 abandoned_sent[SCTP_PR_INDEX(MAX) + 1];
21062096

2097+
/* Security identifiers from incoming (INIT). These are set by
2098+
* security_sctp_assoc_request(). These will only be used by
2099+
* SCTP TCP type sockets and peeled off connections as they
2100+
* cause a new socket to be generated. security_sctp_sk_clone()
2101+
* will then plug these into the new socket.
2102+
*/
2103+
2104+
u32 secid;
2105+
u32 peer_secid;
2106+
21072107
struct rcu_head rcu;
21082108
};
21092109

net/sctp/sm_statefuns.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -326,11 +326,6 @@ enum sctp_disposition sctp_sf_do_5_1B_init(struct net *net,
326326
struct sctp_packet *packet;
327327
int len;
328328

329-
/* Update socket peer label if first association. */
330-
if (security_sctp_assoc_request((struct sctp_endpoint *)ep,
331-
chunk->skb))
332-
return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
333-
334329
/* 6.10 Bundling
335330
* An endpoint MUST NOT bundle INIT, INIT ACK or
336331
* SHUTDOWN COMPLETE with any other chunks.
@@ -415,6 +410,12 @@ enum sctp_disposition sctp_sf_do_5_1B_init(struct net *net,
415410
if (!new_asoc)
416411
goto nomem;
417412

413+
/* Update socket peer label if first association. */
414+
if (security_sctp_assoc_request(new_asoc, chunk->skb)) {
415+
sctp_association_free(new_asoc);
416+
return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
417+
}
418+
418419
if (sctp_assoc_set_bind_addr_from_ep(new_asoc,
419420
sctp_scope(sctp_source(chunk)),
420421
GFP_ATOMIC) < 0)
@@ -780,7 +781,6 @@ enum sctp_disposition sctp_sf_do_5_1D_ce(struct net *net,
780781
}
781782
}
782783

783-
784784
/* Delay state machine commands until later.
785785
*
786786
* Re-build the bind address for the association is done in
@@ -1517,11 +1517,6 @@ static enum sctp_disposition sctp_sf_do_unexpected_init(
15171517
struct sctp_packet *packet;
15181518
int len;
15191519

1520-
/* Update socket peer label if first association. */
1521-
if (security_sctp_assoc_request((struct sctp_endpoint *)ep,
1522-
chunk->skb))
1523-
return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
1524-
15251520
/* 6.10 Bundling
15261521
* An endpoint MUST NOT bundle INIT, INIT ACK or
15271522
* SHUTDOWN COMPLETE with any other chunks.
@@ -1594,6 +1589,12 @@ static enum sctp_disposition sctp_sf_do_unexpected_init(
15941589
if (!new_asoc)
15951590
goto nomem;
15961591

1592+
/* Update socket peer label if first association. */
1593+
if (security_sctp_assoc_request(new_asoc, chunk->skb)) {
1594+
sctp_association_free(new_asoc);
1595+
return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
1596+
}
1597+
15971598
if (sctp_assoc_set_bind_addr_from_ep(new_asoc,
15981599
sctp_scope(sctp_source(chunk)), GFP_ATOMIC) < 0)
15991600
goto nomem;
@@ -2255,8 +2256,7 @@ enum sctp_disposition sctp_sf_do_5_2_4_dupcook(
22552256
}
22562257

22572258
/* Update socket peer label if first association. */
2258-
if (security_sctp_assoc_request((struct sctp_endpoint *)ep,
2259-
chunk->skb)) {
2259+
if (security_sctp_assoc_request(new_asoc, chunk->skb)) {
22602260
sctp_association_free(new_asoc);
22612261
return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
22622262
}

net/sctp/socket.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9412,7 +9412,6 @@ void sctp_copy_sock(struct sock *newsk, struct sock *sk,
94129412
struct inet_sock *inet = inet_sk(sk);
94139413
struct inet_sock *newinet;
94149414
struct sctp_sock *sp = sctp_sk(sk);
9415-
struct sctp_endpoint *ep = sp->ep;
94169415

94179416
newsk->sk_type = sk->sk_type;
94189417
newsk->sk_bound_dev_if = sk->sk_bound_dev_if;
@@ -9457,9 +9456,9 @@ void sctp_copy_sock(struct sock *newsk, struct sock *sk,
94579456
net_enable_timestamp();
94589457

94599458
/* Set newsk security attributes from original sk and connection
9460-
* security attribute from ep.
9459+
* security attribute from asoc.
94619460
*/
9462-
security_sctp_sk_clone(ep, sk, newsk);
9461+
security_sctp_sk_clone(asoc, sk, newsk);
94639462
}
94649463

94659464
static inline void sctp_copy_descendant(struct sock *sk_to,

security/security.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2367,9 +2367,9 @@ int security_tun_dev_open(void *security)
23672367
}
23682368
EXPORT_SYMBOL(security_tun_dev_open);
23692369

2370-
int security_sctp_assoc_request(struct sctp_endpoint *ep, struct sk_buff *skb)
2370+
int security_sctp_assoc_request(struct sctp_association *asoc, struct sk_buff *skb)
23712371
{
2372-
return call_int_hook(sctp_assoc_request, 0, ep, skb);
2372+
return call_int_hook(sctp_assoc_request, 0, asoc, skb);
23732373
}
23742374
EXPORT_SYMBOL(security_sctp_assoc_request);
23752375

@@ -2381,10 +2381,10 @@ int security_sctp_bind_connect(struct sock *sk, int optname,
23812381
}
23822382
EXPORT_SYMBOL(security_sctp_bind_connect);
23832383

2384-
void security_sctp_sk_clone(struct sctp_endpoint *ep, struct sock *sk,
2384+
void security_sctp_sk_clone(struct sctp_association *asoc, struct sock *sk,
23852385
struct sock *newsk)
23862386
{
2387-
call_void_hook(sctp_sk_clone, ep, sk, newsk);
2387+
call_void_hook(sctp_sk_clone, asoc, sk, newsk);
23882388
}
23892389
EXPORT_SYMBOL(security_sctp_sk_clone);
23902390

security/selinux/hooks.c

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5339,10 +5339,10 @@ static void selinux_sock_graft(struct sock *sk, struct socket *parent)
53395339
* connect(2), sctp_connectx(3) or sctp_sendmsg(3) (with no association
53405340
* already present).
53415341
*/
5342-
static int selinux_sctp_assoc_request(struct sctp_endpoint *ep,
5342+
static int selinux_sctp_assoc_request(struct sctp_association *asoc,
53435343
struct sk_buff *skb)
53445344
{
5345-
struct sk_security_struct *sksec = ep->base.sk->sk_security;
5345+
struct sk_security_struct *sksec = asoc->base.sk->sk_security;
53465346
struct common_audit_data ad;
53475347
struct lsm_network_audit net = {0,};
53485348
u8 peerlbl_active;
@@ -5359,7 +5359,7 @@ static int selinux_sctp_assoc_request(struct sctp_endpoint *ep,
53595359
/* This will return peer_sid = SECSID_NULL if there are
53605360
* no peer labels, see security_net_peersid_resolve().
53615361
*/
5362-
err = selinux_skb_peerlbl_sid(skb, ep->base.sk->sk_family,
5362+
err = selinux_skb_peerlbl_sid(skb, asoc->base.sk->sk_family,
53635363
&peer_sid);
53645364
if (err)
53655365
return err;
@@ -5383,7 +5383,7 @@ static int selinux_sctp_assoc_request(struct sctp_endpoint *ep,
53835383
*/
53845384
ad.type = LSM_AUDIT_DATA_NET;
53855385
ad.u.net = &net;
5386-
ad.u.net->sk = ep->base.sk;
5386+
ad.u.net->sk = asoc->base.sk;
53875387
err = avc_has_perm(&selinux_state,
53885388
sksec->peer_sid, peer_sid, sksec->sclass,
53895389
SCTP_SOCKET__ASSOCIATION, &ad);
@@ -5392,7 +5392,7 @@ static int selinux_sctp_assoc_request(struct sctp_endpoint *ep,
53925392
}
53935393

53945394
/* Compute the MLS component for the connection and store
5395-
* the information in ep. This will be used by SCTP TCP type
5395+
* the information in asoc. This will be used by SCTP TCP type
53965396
* sockets and peeled off connections as they cause a new
53975397
* socket to be generated. selinux_sctp_sk_clone() will then
53985398
* plug this into the new socket.
@@ -5401,11 +5401,11 @@ static int selinux_sctp_assoc_request(struct sctp_endpoint *ep,
54015401
if (err)
54025402
return err;
54035403

5404-
ep->secid = conn_sid;
5405-
ep->peer_secid = peer_sid;
5404+
asoc->secid = conn_sid;
5405+
asoc->peer_secid = peer_sid;
54065406

54075407
/* Set any NetLabel labels including CIPSO/CALIPSO options. */
5408-
return selinux_netlbl_sctp_assoc_request(ep, skb);
5408+
return selinux_netlbl_sctp_assoc_request(asoc, skb);
54095409
}
54105410

54115411
/* Check if sctp IPv4/IPv6 addresses are valid for binding or connecting
@@ -5490,7 +5490,7 @@ static int selinux_sctp_bind_connect(struct sock *sk, int optname,
54905490
}
54915491

54925492
/* Called whenever a new socket is created by accept(2) or sctp_peeloff(3). */
5493-
static void selinux_sctp_sk_clone(struct sctp_endpoint *ep, struct sock *sk,
5493+
static void selinux_sctp_sk_clone(struct sctp_association *asoc, struct sock *sk,
54945494
struct sock *newsk)
54955495
{
54965496
struct sk_security_struct *sksec = sk->sk_security;
@@ -5502,8 +5502,8 @@ static void selinux_sctp_sk_clone(struct sctp_endpoint *ep, struct sock *sk,
55025502
if (!selinux_policycap_extsockclass())
55035503
return selinux_sk_clone_security(sk, newsk);
55045504

5505-
newsksec->sid = ep->secid;
5506-
newsksec->peer_sid = ep->peer_secid;
5505+
newsksec->sid = asoc->secid;
5506+
newsksec->peer_sid = asoc->peer_secid;
55075507
newsksec->sclass = sksec->sclass;
55085508
selinux_netlbl_sctp_sk_clone(sk, newsk);
55095509
}

security/selinux/include/netlabel.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ int selinux_netlbl_skbuff_getsid(struct sk_buff *skb,
3939
int selinux_netlbl_skbuff_setsid(struct sk_buff *skb,
4040
u16 family,
4141
u32 sid);
42-
int selinux_netlbl_sctp_assoc_request(struct sctp_endpoint *ep,
42+
int selinux_netlbl_sctp_assoc_request(struct sctp_association *asoc,
4343
struct sk_buff *skb);
4444
int selinux_netlbl_inet_conn_request(struct request_sock *req, u16 family);
4545
void selinux_netlbl_inet_csk_clone(struct sock *sk, u16 family);
@@ -98,7 +98,7 @@ static inline int selinux_netlbl_skbuff_setsid(struct sk_buff *skb,
9898
return 0;
9999
}
100100

101-
static inline int selinux_netlbl_sctp_assoc_request(struct sctp_endpoint *ep,
101+
static inline int selinux_netlbl_sctp_assoc_request(struct sctp_association *asoc,
102102
struct sk_buff *skb)
103103
{
104104
return 0;

0 commit comments

Comments
 (0)