Skip to content

Commit 859ccfd

Browse files
committed
tests/sctp: fix setting of the SCTP_EVENTS sockopt
First, the setting of SCTP_EVENTS socket option in sctp_server.c is completely wrong -- it assumes little-endian byte order and uses a plain int instead of the dedicated sctp_event_subscribe struct. Second, the usage in sctp_peeloff_server.c is correct, but it may lead to errors when the SCTP header definitions are newer than what the kernel supports. In such case the size of struct sctp_event_subscribe may be higher than the kernel's version and the setsockopt(2) may fail with -EINVAL due to the 'optlen > sizeof(struct sctp_event_subscribe)' check in net/sctp/socket.c:sctp_setsockopt_events(). To fix this, introduce a common function that does what the sctp_peeloff_server's set_subscr_events() did, but also truncates the optlen to only those fields that we use. Fixes: c38b57f ("selinux-testsuite: Add SCTP test support") Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
1 parent 9ee4101 commit 859ccfd

File tree

4 files changed

+30
-21
lines changed

4 files changed

+30
-21
lines changed

tests/sctp/sctp_common.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
#include "sctp_common.h"
22

3+
#define member_size(type, member) sizeof(((type *)0)->member)
4+
#define sizeof_up_to(type, member) (offsetof(type, member) + member_size(type, member))
5+
36
void print_context(int fd, char *text)
47
{
58
char *context;
@@ -99,3 +102,20 @@ void print_ip_option(int fd, bool ipv4, char *text)
99102
printf("%s No IP Options set\n", text);
100103
}
101104
}
105+
106+
int set_subscr_events(int fd, int data_io, int association)
107+
{
108+
struct sctp_event_subscribe subscr_events;
109+
110+
memset(&subscr_events, 0, sizeof(subscr_events));
111+
subscr_events.sctp_data_io_event = data_io;
112+
subscr_events.sctp_association_event = association;
113+
114+
/*
115+
* Truncate optlen to just the fields we touch to avoid errors when
116+
* the uapi headers are newer than the running kernel.
117+
*/
118+
return setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &subscr_events,
119+
sizeof_up_to(struct sctp_event_subscribe,
120+
sctp_association_event));
121+
}

tests/sctp/sctp_common.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,4 @@ void print_context(int fd, char *text);
2525
void print_addr_info(struct sockaddr *sin, char *text);
2626
char *get_ip_option(int fd, bool ipv4, socklen_t *opt_len);
2727
void print_ip_option(int fd, bool ipv4, char *text);
28+
int set_subscr_events(int fd, int data_io, int association);

tests/sctp/sctp_peeloff_server.c

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,6 @@ static void usage(char *progname)
1616
exit(1);
1717
}
1818

19-
static void set_subscr_events(int fd, int value)
20-
{
21-
int result;
22-
struct sctp_event_subscribe subscr_events;
23-
24-
memset(&subscr_events, 0, sizeof(subscr_events));
25-
subscr_events.sctp_association_event = value;
26-
/* subscr_events.sctp_data_io_event = value; */
27-
28-
result = setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS,
29-
&subscr_events, sizeof(subscr_events));
30-
if (result < 0) {
31-
perror("Server setsockopt: SCTP_EVENTS");
32-
close(fd);
33-
exit(1);
34-
}
35-
}
36-
3719
static sctp_assoc_t handle_event(void *buf)
3820
{
3921
union sctp_notification *snp = buf;
@@ -166,7 +148,13 @@ int main(int argc, char **argv)
166148
}
167149

168150
do {
169-
set_subscr_events(sock, 1); /* Get assoc_id for sctp_peeloff() */
151+
/* Get assoc_id for sctp_peeloff() */
152+
result = set_subscr_events(sock, 0, 1);
153+
if (result < 0) {
154+
perror("Server setsockopt: SCTP_EVENTS");
155+
close(sock);
156+
exit(1);
157+
}
170158
sinlen = sizeof(sin);
171159
flags = 0;
172160

@@ -192,7 +180,7 @@ int main(int argc, char **argv)
192180
exit(1);
193181
}
194182
/* No more notifications */
195-
set_subscr_events(sock, 0);
183+
set_subscr_events(sock, 0, 0);
196184

197185
peeloff_sk = sctp_peeloff(sock, assoc_id);
198186
if (peeloff_sk < 0) {

tests/sctp/sctp_server.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ int main(int argc, char **argv)
134134
}
135135

136136
/* Enables sctp_data_io_events for sctp_recvmsg(3) for assoc_id. */
137-
result = setsockopt(sock, SOL_SCTP, SCTP_EVENTS, &on, sizeof(on));
137+
result = set_subscr_events(sock, on, 0);
138138
if (result < 0) {
139139
perror("Server setsockopt: SCTP_EVENTS");
140140
close(sock);

0 commit comments

Comments
 (0)