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 } 89