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