8 #include <sys/socket.h>
11 #include <darwintest.h>
13 #define ROUNDUP32(n) (((n) + sizeof(uint32_t) - 1) & ~(sizeof(uint32_t) - 1))
15 T_DECL(route_output_stack_oflow_56033075
, "Stack overflow via ma_copy through route_output")
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 */
24 struct rt_msghdr
*rtm
= (struct rt_msghdr
*)buf
;
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
);
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
);
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
);
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
);
56 T_ASSERT_POSIX_SUCCESS(s
= socket(PF_ROUTE
, SOCK_RAW
, PF_ROUTE
), NULL
);
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
);
64 /* now check the ok case: */
65 len
= sizeof(struct rt_msghdr
);
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
);
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
);
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
);
85 rtm
->rtm_msglen
= len
;
86 T_ASSERT_EQ(-1, send(s
, buf
, len
, 0), NULL
);
87 T_ASSERT_EQ(ESRCH
, errno
, NULL
);