83 lines · cpp
1// Test that ASan detects buffer overflow on read from socket via recvfrom.2//3// RUN: %clangxx_asan %s -DRECVFROM -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-RECVFROM4// RUN: %clangxx_asan %s -DSENDTO -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-SENDTO5// RUN: %clangxx_asan %s -DSENDTO -o %t && %env_asan_opts=intercept_send=0 %run %t 2>&16//7// This will try to fast unwind on Arm Thumb, where fast unwinding does not work.8// UNSUPPORTED: android, !fast-unwinder-works9 10#include <stdio.h>11#include <unistd.h>12#include <stdlib.h>13#include <string.h>14#include <netdb.h>15#include <sys/types.h>16#include <sys/socket.h>17#include <pthread.h>18 19#define CHECK_ERROR(p, m) \20 do { \21 if (p) { \22 fprintf(stderr, "ERROR " m "\n"); \23 exit(1); \24 } \25 } while (0)26 27const int kBufSize = 10;28int sockfd;29 30static void *client_thread_udp(void *data) {31#ifdef SENDTO32 const char buf[kBufSize / 2] = {0, };33#else34 const char buf[kBufSize] = {0, };35#endif36 struct sockaddr_in serveraddr;37 socklen_t addrlen = sizeof(serveraddr);38 39 int succeeded = getsockname(sockfd, (struct sockaddr *)&serveraddr, &addrlen);40 CHECK_ERROR(succeeded < 0, "in getsockname");41 42 succeeded = sendto(sockfd, buf, kBufSize, 0, (struct sockaddr *)&serveraddr,43 sizeof(serveraddr));44 // CHECK-SENDTO: {{READ of size 10 at 0x.* thread T1}}45 // CHECK-SENDTO: {{ #1 0x.* in client_thread_udp.*recvfrom.cpp:}}[[@LINE-3]]46 CHECK_ERROR(succeeded < 0, "in sending message");47 return NULL;48}49 50int main() {51#ifdef RECVFROM52 char buf[kBufSize / 2];53#else54 char buf[kBufSize];55#endif56 pthread_t client_thread;57 struct sockaddr_in serveraddr;58 59 sockfd = socket(AF_INET, SOCK_DGRAM, 0);60 CHECK_ERROR(sockfd < 0, "opening socket");61 62 memset(&serveraddr, 0, sizeof(serveraddr));63 serveraddr.sin_family = AF_INET;64 serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);65 serveraddr.sin_port = 0;66 67 int bound = bind(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr));68 CHECK_ERROR(bound < 0, "on binding");69 70 int succeeded =71 pthread_create(&client_thread, NULL, client_thread_udp, &serveraddr);72 CHECK_ERROR(succeeded, "creating thread");73 74 recvfrom(sockfd, buf, kBufSize, 0, NULL, NULL); // BOOM75 // CHECK-RECVFROM: {{WRITE of size 10 at 0x.* thread T0}}76 // CHECK-RECVFROM: {{ #1 0x.* in main.*recvfrom.cpp:}}[[@LINE-2]]77 // CHECK-RECVFROM: {{Address 0x.* is located in stack of thread T0 at offset}}78 // CHECK-RECVFROM-NEXT: in{{.*}}main{{.*}}recvfrom.cpp79 succeeded = pthread_join(client_thread, NULL);80 CHECK_ERROR(succeeded, "joining thread");81 return 0;82}83