]>
Commit | Line | Data |
---|---|---|
4ba76501 A |
1 | #include <errno.h> |
2 | #include <stdio.h> | |
3 | #include <stdlib.h> | |
4 | #include <string.h> | |
5 | #include <strings.h> | |
6 | ||
7 | #include <net/route.h> | |
8 | #include <sys/socket.h> | |
9 | #include <unistd.h> | |
10 | ||
11 | #include <darwintest.h> | |
12 | ||
13 | #define ROUNDUP32(n) (((n) + sizeof(uint32_t) - 1) & ~(sizeof(uint32_t) - 1)) | |
14 | ||
15 | T_DECL(route_output_stack_oflow_56033075, "Stack overflow via ma_copy through route_output") | |
16 | { | |
17 | int s; | |
18 | uint8_t buf[ | |
19 | sizeof(struct rt_msghdr) + | |
20 | ROUNDUP32(sizeof(struct sockaddr_storage) + 1) + /* RTAX_DST */ | |
21 | ROUNDUP32(sizeof(struct sockaddr_storage) + 1) + /* RTAX_GATEWAY */ | |
22 | ROUNDUP32(sizeof(struct sockaddr_storage) + 1) /* RTAX_NETMASK */ | |
23 | ]; | |
24 | struct rt_msghdr *rtm = (struct rt_msghdr *)buf; | |
25 | struct sockaddr *sa; | |
26 | size_t len; | |
27 | ||
28 | bzero(buf, sizeof(buf)); | |
29 | rtm->rtm_type = RTM_GET; | |
30 | rtm->rtm_version = RTM_VERSION; | |
31 | rtm->rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK; | |
32 | len = sizeof(struct rt_msghdr); | |
33 | ||
34 | /* RTAX_DST: */ | |
35 | sa = (struct sockaddr *)(rtm + 1); | |
36 | sa->sa_family = AF_INET6; | |
37 | sa->sa_len = sizeof(struct sockaddr_storage) + 1; | |
38 | memset(&sa->sa_data[0], 0xff, sa->sa_len); | |
39 | len += ROUNDUP32(sa->sa_len); | |
40 | ||
41 | /* RTAX_GATEWAY: */ | |
42 | sa = (struct sockaddr *)((void *)buf + len); | |
43 | sa->sa_family = AF_INET6; | |
44 | sa->sa_len = sizeof(struct sockaddr_storage) + 1; | |
45 | memset(&sa->sa_data[0], 0xff, sa->sa_len); | |
46 | len += ROUNDUP32(sa->sa_len); | |
47 | ||
48 | /* RTAX_NETMASK: */ | |
49 | sa = (struct sockaddr *)((void *)buf + len); | |
50 | sa->sa_family = AF_INET6; | |
51 | sa->sa_len = sizeof(struct sockaddr_storage) + 1; | |
52 | memset(&sa->sa_data[0], 0x41, sa->sa_len); | |
53 | len += ROUNDUP32(sa->sa_len); | |
54 | ||
55 | T_SETUPBEGIN; | |
56 | T_ASSERT_POSIX_SUCCESS(s = socket(PF_ROUTE, SOCK_RAW, PF_ROUTE), NULL); | |
57 | T_SETUPEND; | |
58 | ||
59 | /* check we get EINVAL for > sizeof(struct sockaddr_storage): */ | |
60 | rtm->rtm_msglen = len; | |
61 | T_ASSERT_EQ(-1, send(s, buf, len, 0), NULL); | |
62 | T_ASSERT_EQ(EINVAL, errno, NULL); | |
63 | ||
64 | /* now check the ok case: */ | |
65 | len = sizeof(struct rt_msghdr); | |
66 | ||
67 | /* RTAX_DST: */ | |
68 | sa = (struct sockaddr *)(rtm + 1); | |
69 | sa->sa_family = AF_INET6; | |
70 | sa->sa_len = sizeof(struct sockaddr_storage); | |
71 | len += ROUNDUP32(sa->sa_len); | |
72 | ||
73 | /* RTAX_GATEWAY: */ | |
74 | sa = (struct sockaddr *)((void *)buf + len); | |
75 | sa->sa_family = AF_INET6; | |
76 | sa->sa_len = sizeof(struct sockaddr_storage); | |
77 | len += ROUNDUP32(sa->sa_len); | |
78 | ||
79 | /* RTAX_NETMASK: */ | |
80 | sa = (struct sockaddr *)((void *)buf + len); | |
81 | sa->sa_family = AF_INET6; | |
82 | sa->sa_len = sizeof(struct sockaddr_storage); | |
83 | len += ROUNDUP32(sa->sa_len); | |
84 | ||
85 | rtm->rtm_msglen = len; | |
86 | T_ASSERT_EQ(-1, send(s, buf, len, 0), NULL); | |
87 | T_ASSERT_EQ(ESRCH, errno, NULL); | |
88 | } |