2371 lines · cpp
1// RUN: %clang_dfsan %s -o %t && env DFSAN_OPTIONS="strict_data_dependencies=0" %run %t2// RUN: %clang_dfsan -DSTRICT_DATA_DEPENDENCIES %s -o %t && %run %t3// RUN: %clang_dfsan -DORIGIN_TRACKING -mllvm -dfsan-track-origins=1 -mllvm -dfsan-combine-pointer-labels-on-load=false -DSTRICT_DATA_DEPENDENCIES %s -o %t && %run %t4// RUN: %clang_dfsan -DORIGIN_TRACKING -mllvm -dfsan-track-origins=1 -mllvm -dfsan-combine-pointer-labels-on-load=false -no-pie %s -o %t && env DFSAN_OPTIONS="strict_data_dependencies=0" %run %t5//6// Tests custom implementations of various glibc functions.7 8#pragma clang diagnostic ignored "-Wformat-extra-args"9 10#include <sanitizer/dfsan_interface.h>11 12#include <arpa/inet.h>13#include <assert.h>14#include <fcntl.h>15#include <link.h>16#include <poll.h>17#include <pthread.h>18#include <pwd.h>19#include <sched.h>20#include <signal.h>21#include <stdint.h>22#include <stdio.h>23#include <stdlib.h>24#include <string.h>25#include <strings.h>26#include <sys/epoll.h>27#include <sys/resource.h>28#include <sys/select.h>29#include <sys/socket.h>30#include <sys/stat.h>31#include <sys/time.h>32#include <sys/types.h>33#include <time.h>34#include <unistd.h>35 36dfsan_label i_label = 0;37dfsan_label j_label = 0;38dfsan_label k_label = 0;39dfsan_label m_label = 0;40dfsan_label n_label = 0;41dfsan_label i_j_label = 0;42 43#define ASSERT_ZERO_LABEL(data) \44 assert(0 == dfsan_get_label((long) (data)))45 46#define ASSERT_READ_ZERO_LABEL(ptr, size) \47 assert(0 == dfsan_read_label(ptr, size))48 49#define ASSERT_LABEL(data, label) \50 assert(label == dfsan_get_label((long) (data)))51 52#define ASSERT_READ_LABEL(ptr, size, label) \53 assert(label == dfsan_read_label(ptr, size))54 55#ifdef ORIGIN_TRACKING56#define ASSERT_ZERO_ORIGIN(data) \57 assert(0 == dfsan_get_origin((long)(data)))58#else59#define ASSERT_ZERO_ORIGIN(data)60#endif61 62#ifdef ORIGIN_TRACKING63#define ASSERT_ZERO_ORIGINS(ptr, size) \64 for (int i = 0; i < size; ++i) { \65 assert(0 == dfsan_get_origin((long)(((char *)ptr)[i]))); \66 }67#else68#define ASSERT_ZERO_ORIGINS(ptr, size)69#endif70 71#ifdef ORIGIN_TRACKING72#define ASSERT_ORIGIN(data, origin) \73 assert(origin == dfsan_get_origin((long)(data)))74#else75#define ASSERT_ORIGIN(data, origin)76#endif77 78#ifdef ORIGIN_TRACKING79#define ASSERT_ORIGINS(ptr, size, origin) \80 for (int i = 0; i < size; ++i) { \81 assert(origin == dfsan_get_origin((long)(((char *)ptr)[i]))); \82 }83#else84#define ASSERT_ORIGINS(ptr, size, origin)85#endif86 87#ifdef ORIGIN_TRACKING88#define ASSERT_INIT_ORIGIN(ptr, origin) \89 assert(origin == dfsan_get_init_origin(ptr))90#else91#define ASSERT_INIT_ORIGIN(ptr, origin)92#endif93 94#ifdef ORIGIN_TRACKING95#define ASSERT_INIT_ORIGIN_EQ_ORIGIN(ptr, data) \96 assert(dfsan_get_origin((long)(data)) == dfsan_get_init_origin(ptr))97#else98#define ASSERT_INIT_ORIGIN_EQ_ORIGIN(ptr, data)99#endif100 101#ifdef ORIGIN_TRACKING102#define ASSERT_INIT_ORIGINS(ptr, size, origin) \103 for (int i = 0; i < size; ++i) { \104 assert(origin == dfsan_get_init_origin(&((char *)ptr)[i])); \105 }106#else107#define ASSERT_INIT_ORIGINS(ptr, size, origin)108#endif109 110#ifdef ORIGIN_TRACKING111#define ASSERT_EQ_ORIGIN(data1, data2) \112 assert(dfsan_get_origin((long)(data1)) == dfsan_get_origin((long)(data2)))113#else114#define ASSERT_EQ_ORIGIN(data1, data2)115#endif116 117#ifdef ORIGIN_TRACKING118#define DEFINE_AND_SAVE_ORIGINS(val) \119 dfsan_origin val##_o[sizeof(val)]; \120 for (int i = 0; i < sizeof(val); ++i) \121 val##_o[i] = dfsan_get_origin((long)(((char *)(&val))[i]));122#else123#define DEFINE_AND_SAVE_ORIGINS(val)124#endif125 126#ifdef ORIGIN_TRACKING127#define SAVE_ORIGINS(val) \128 for (int i = 0; i < sizeof(val); ++i) \129 val##_o[i] = dfsan_get_origin((long)(((char *)(&val))[i]));130#else131#define SAVE_ORIGINS(val)132#endif133 134#ifdef ORIGIN_TRACKING135#define ASSERT_SAVED_ORIGINS(val) \136 for (int i = 0; i < sizeof(val); ++i) \137 ASSERT_ORIGIN(((char *)(&val))[i], val##_o[i]);138#else139#define ASSERT_SAVED_ORIGINS(val)140#endif141 142#ifdef ORIGIN_TRACKING143#define DEFINE_AND_SAVE_N_ORIGINS(val, n) \144 dfsan_origin val##_o[n]; \145 for (int i = 0; i < n; ++i) \146 val##_o[i] = dfsan_get_origin((long)(val[i]));147#else148#define DEFINE_AND_SAVE_N_ORIGINS(val, n)149#endif150 151#ifdef ORIGIN_TRACKING152#define ASSERT_SAVED_N_ORIGINS(val, n) \153 for (int i = 0; i < n; ++i) \154 ASSERT_ORIGIN(val[i], val##_o[i]);155#else156#define ASSERT_SAVED_N_ORIGINS(val, n)157#endif158 159#if !defined(__GLIBC_PREREQ)160# define __GLIBC_PREREQ(a, b) 0161#endif162 163void test_stat() {164 int i = 1;165 dfsan_set_label(i_label, &i, sizeof(i));166 167 struct stat s;168 s.st_dev = i;169 DEFINE_AND_SAVE_ORIGINS(s)170 int ret = stat("/", &s);171 assert(0 == ret);172 ASSERT_ZERO_LABEL(ret);173 ASSERT_ZERO_LABEL(s.st_dev);174 ASSERT_SAVED_ORIGINS(s)175 176 s.st_dev = i;177 SAVE_ORIGINS(s)178 ret = stat("/nonexistent_581cb021aba7", &s);179 assert(-1 == ret);180 ASSERT_ZERO_LABEL(ret);181 ASSERT_LABEL(s.st_dev, i_label);182 ASSERT_SAVED_ORIGINS(s)183}184 185void test_fstat() {186 int i = 1;187 dfsan_set_label(i_label, &i, sizeof(i));188 189 struct stat s;190 int fd = open("/dev/zero", O_RDONLY);191 s.st_dev = i;192 DEFINE_AND_SAVE_ORIGINS(s)193 int rv = fstat(fd, &s);194 assert(0 == rv);195 ASSERT_ZERO_LABEL(rv);196 ASSERT_ZERO_LABEL(s.st_dev);197 ASSERT_SAVED_ORIGINS(s)198}199 200void test_memcmp() {201 char str1[] = "str1", str2[] = "str2";202 dfsan_set_label(i_label, &str1[3], 1);203 dfsan_set_label(j_label, &str2[3], 1);204 205 int rv = memcmp(str1, str2, sizeof(str1));206 assert(rv < 0);207#ifdef STRICT_DATA_DEPENDENCIES208 ASSERT_ZERO_LABEL(rv);209#else210 ASSERT_LABEL(rv, i_j_label);211 ASSERT_EQ_ORIGIN(rv, str1[3]);212#endif213 214 rv = memcmp(str1, str2, sizeof(str1) - 2);215 assert(rv == 0);216 ASSERT_ZERO_LABEL(rv);217}218 219void test_bcmp() {220 char str1[] = "str1", str2[] = "str2";221 dfsan_set_label(i_label, &str1[3], 1);222 dfsan_set_label(j_label, &str2[3], 1);223 224 int rv = bcmp(str1, str2, sizeof(str1));225 assert(rv != 0);226#ifdef STRICT_DATA_DEPENDENCIES227 ASSERT_ZERO_LABEL(rv);228#else229 ASSERT_LABEL(rv, i_j_label);230 ASSERT_EQ_ORIGIN(rv, str1[3]);231#endif232 233 rv = bcmp(str1, str2, sizeof(str1) - 2);234 assert(rv == 0);235 ASSERT_ZERO_LABEL(rv);236}237 238void test_memcpy() {239 char str1[] = "str1";240 char str2[sizeof(str1)];241 dfsan_set_label(i_label, &str1[3], 1);242 243 DEFINE_AND_SAVE_ORIGINS(str1)244 245 char *ptr2 = str2;246 dfsan_set_label(j_label, &ptr2, sizeof(ptr2));247 248 void *r = memcpy(ptr2, str1, sizeof(str1));249 ASSERT_LABEL(r, j_label);250 ASSERT_EQ_ORIGIN(r, ptr2);251 assert(0 == memcmp(str2, str1, sizeof(str1)));252 ASSERT_ZERO_LABEL(str2[0]);253 ASSERT_LABEL(str2[3], i_label);254 255 for (int i = 0; i < sizeof(str2); ++i) {256 if (!dfsan_get_label(str2[i]))257 continue;258 ASSERT_INIT_ORIGIN(&(str2[i]), str1_o[i]);259 }260}261 262void test_memmove() {263 char str[] = "str1xx";264 dfsan_set_label(i_label, &str[3], 1);265 266 DEFINE_AND_SAVE_ORIGINS(str)267 268 char *ptr = str + 2;269 dfsan_set_label(j_label, &ptr, sizeof(ptr));270 271 void *r = memmove(ptr, str, 4);272 ASSERT_LABEL(r, j_label);273 ASSERT_EQ_ORIGIN(r, ptr);274 assert(0 == memcmp(str + 2, "str1", 4));275 ASSERT_ZERO_LABEL(str[4]);276 ASSERT_LABEL(str[5], i_label);277 278 for (int i = 0; i < 4; ++i) {279 if (!dfsan_get_label(ptr[i]))280 continue;281 ASSERT_INIT_ORIGIN(&(ptr[i]), str_o[i]);282 }283}284 285void test_memset() {286 char buf[8];287 int j = 'a';288 char *ptr = buf;289 dfsan_set_label(j_label, &j, sizeof(j));290 dfsan_set_label(k_label, &ptr, sizeof(ptr));291 void *ret = memset(ptr, j, sizeof(buf));292 ASSERT_LABEL(ret, k_label);293 ASSERT_EQ_ORIGIN(ret, ptr);294 for (int i = 0; i < 8; ++i) {295 ASSERT_LABEL(buf[i], j_label);296 ASSERT_EQ_ORIGIN(buf[i], j);297 assert(buf[i] == 'a');298 }299}300 301void test_strcmp() {302 char str1[] = "str1", str2[] = "str2";303 dfsan_set_label(i_label, &str1[3], 1);304 dfsan_set_label(j_label, &str2[3], 1);305 306 int rv = strcmp(str1, str2);307 assert(rv < 0);308#ifdef STRICT_DATA_DEPENDENCIES309 ASSERT_ZERO_LABEL(rv);310#else311 ASSERT_LABEL(rv, i_j_label);312 ASSERT_EQ_ORIGIN(rv, str1[3]);313#endif314 315 rv = strcmp(str1, str1);316 assert(rv == 0);317#ifdef STRICT_DATA_DEPENDENCIES318 ASSERT_ZERO_LABEL(rv);319 ASSERT_ZERO_ORIGIN(rv);320#else321 ASSERT_LABEL(rv, i_label);322 ASSERT_EQ_ORIGIN(rv, str1[3]);323#endif324}325 326void test_strcat() {327 char src[] = "world";328 int volatile x = 0; // buffer to ensure src and dst do not share origins329 (void)x;330 char dst[] = "hello \0 ";331 int volatile y = 0; // buffer to ensure dst and p do not share origins332 (void)y;333 char *p = dst;334 dfsan_set_label(k_label, &p, sizeof(p));335 dfsan_set_label(i_label, src, sizeof(src));336 dfsan_set_label(j_label, dst, sizeof(dst));337 dfsan_origin dst_o = dfsan_get_origin((long)dst[0]);338 (void)dst_o;339 char *ret = strcat(p, src);340 341 ASSERT_LABEL(ret, k_label);342 ASSERT_EQ_ORIGIN(ret, p);343 assert(ret == dst);344 assert(strcmp(src, dst + 6) == 0);345 // Origins are assigned for every 4 contiguous 4-aligned bytes. After346 // appending src to dst, origins of src can overwrite origins of dst if their347 // application adddresses are within [start_aligned_down, end_aligned_up).348 // Other origins are not changed.349 char *start_aligned_down = (char *)(((size_t)(dst + 6)) & ~3UL);350 char *end_aligned_up = (char *)(((size_t)(dst + 11 + 4)) & ~3UL);351 for (int i = 0; i < 12; ++i) {352 if (dst + i < start_aligned_down || dst + i >= end_aligned_up) {353 ASSERT_INIT_ORIGIN(&dst[i], dst_o);354 } else {355 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&dst[i], src[0]);356 }357 }358 for (int i = 0; i < 6; ++i) {359 ASSERT_LABEL(dst[i], j_label);360 }361 for (int i = 6; i < strlen(dst); ++i) {362 ASSERT_LABEL(dst[i], i_label);363 assert(dfsan_get_label(dst[i]) == dfsan_get_label(src[i - 6]));364 }365 ASSERT_LABEL(dst[11], j_label);366}367 368void test_strncat(int n) {369 char src[] = "world";370 int volatile x = 0; // buffer to ensure src and dst do not share origins371 (void)x;372 char dst[] = "hello \0 ";373 int volatile y = 0; // buffer to ensure dst and p do not share origins374 (void)y;375 char *p = dst;376 dfsan_set_label(k_label, &p, sizeof(p));377 dfsan_set_label(i_label, src, sizeof(src));378 dfsan_set_label(j_label, dst, sizeof(dst));379 dfsan_origin dst_o = dfsan_get_origin((long)dst[0]);380 (void)dst_o;381 char *ret = strncat(p, src, n);382 383 ASSERT_LABEL(ret, k_label);384 ASSERT_EQ_ORIGIN(ret, p);385 assert(ret == dst);386 assert(strncmp(src, dst + 6, n) == 0);387 // Origins are assigned for every 4 contiguous 4-aligned bytes. After388 // appending src to dst, origins of src can overwrite origins of dst if their389 // application adddresses are within [start_aligned_down, end_aligned_up).390 // Other origins are not changed.391 int pad = n % 4;392 if (pad)393 pad = 4 - pad;394 395 char *start_aligned_down = (char *)(((size_t)(dst + 6)) & ~3UL);396 char *end_aligned_up = (char *)(((size_t)(dst + 6 + n + pad)) & ~3UL);397 398 for (int i = 0; i < 12; ++i) {399 if (dst + i < start_aligned_down || dst + i >= end_aligned_up) {400 ASSERT_INIT_ORIGIN(&dst[i], dst_o);401 } else {402 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&dst[i], src[0]);403 }404 }405 for (int i = 0; i < 6; ++i) {406 ASSERT_LABEL(dst[i], j_label);407 }408 for (int i = 6; i < 6 + n; ++i) {409 ASSERT_LABEL(dst[i], i_label);410 assert(dfsan_get_label(dst[i]) == dfsan_get_label(src[i - 6]));411 }412 for (int i = 6 + n; i < strlen(dst); ++i) {413 ASSERT_LABEL(dst[i], j_label);414 }415 ASSERT_LABEL(dst[11], j_label);416}417 418void test_strlen() {419 char str1[] = "str1";420 dfsan_set_label(i_label, &str1[3], 1);421 422 int rv = strlen(str1);423 assert(rv == 4);424#ifdef STRICT_DATA_DEPENDENCIES425 ASSERT_ZERO_LABEL(rv);426#else427 ASSERT_LABEL(rv, i_label);428 ASSERT_EQ_ORIGIN(rv, str1[3]);429#endif430}431 432void test_strnlen() {433 char str1[] = "str1";434 dfsan_set_label(i_label, &str1[3], 1);435 436 int maxlen = 4;437 dfsan_set_label(j_label, &maxlen, sizeof(maxlen));438 439 int rv = strnlen(str1, maxlen);440 assert(rv == 4);441#ifdef STRICT_DATA_DEPENDENCIES442 ASSERT_ZERO_LABEL(rv);443#else444 ASSERT_LABEL(rv, dfsan_union(i_label, j_label));445 ASSERT_EQ_ORIGIN(rv, str1[3]);446#endif447 448 maxlen = 2;449 dfsan_set_label(j_label, &maxlen, sizeof(maxlen));450 rv = strnlen(str1, maxlen);451 assert(rv == 2);452#ifdef STRICT_DATA_DEPENDENCIES453 ASSERT_ZERO_LABEL(rv);454#else455 ASSERT_LABEL(rv, j_label);456 ASSERT_EQ_ORIGIN(rv, maxlen);457#endif458}459 460void test_strdup() {461 char str1[] = "str1";462 dfsan_set_label(i_label, &str1[3], 1);463 DEFINE_AND_SAVE_ORIGINS(str1)464 465 char *strd = strdup(str1);466 ASSERT_ZERO_LABEL(strd);467 ASSERT_ZERO_LABEL(strd[0]);468 ASSERT_LABEL(strd[3], i_label);469 470 for (int i = 0; i < strlen(strd); ++i) {471 if (!dfsan_get_label(strd[i]))472 continue;473 ASSERT_INIT_ORIGIN(&(strd[i]), str1_o[i]);474 }475 476 free(strd);477}478 479void test_strncpy() {480 char str1[] = "str1";481 char str2[sizeof(str1)];482 dfsan_set_label(i_label, &str1[3], 1);483 484 char *strd = strncpy(str2, str1, 5);485 assert(strd == str2);486 assert(strcmp(str1, str2) == 0);487 ASSERT_ZERO_LABEL(strd);488 ASSERT_ZERO_LABEL(strd[0]);489 ASSERT_ZERO_LABEL(strd[1]);490 ASSERT_ZERO_LABEL(strd[2]);491 ASSERT_LABEL(strd[3], i_label);492 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&(strd[3]), str1[3]);493 494 char *p2 = str2;495 dfsan_set_label(j_label, &p2, sizeof(p2));496 strd = strncpy(p2, str1, 3);497 assert(strd == str2);498 assert(strncmp(str1, str2, 3) == 0);499 ASSERT_LABEL(strd, j_label);500 ASSERT_EQ_ORIGIN(strd, p2);501 // When -dfsan-combine-pointer-labels-on-load is on, strd's label propagates502 // to strd[i]'s label. When ORIGIN_TRACKING is defined,503 // -dfsan-combine-pointer-labels-on-load is always off, otherwise the flag504 // is on by default.505#if defined(ORIGIN_TRACKING)506 ASSERT_ZERO_LABEL(strd[0]);507 ASSERT_ZERO_LABEL(strd[1]);508 ASSERT_ZERO_LABEL(strd[2]);509#else510 ASSERT_LABEL(strd[0], j_label);511 ASSERT_LABEL(strd[1], j_label);512 ASSERT_LABEL(strd[2], j_label);513#endif514}515 516void test_strncmp() {517 char str1[] = "str1", str2[] = "str2";518 dfsan_set_label(i_label, &str1[3], 1);519 dfsan_set_label(j_label, &str2[3], 1);520 521 int rv = strncmp(str1, str2, sizeof(str1));522 assert(rv < 0);523#ifdef STRICT_DATA_DEPENDENCIES524 ASSERT_ZERO_LABEL(rv);525#else526 ASSERT_LABEL(rv, dfsan_union(i_label, j_label));527 ASSERT_EQ_ORIGIN(rv, str1[3]);528#endif529 530 rv = strncmp(str1, str2, 0);531 assert(rv == 0);532 ASSERT_ZERO_LABEL(rv);533 534 rv = strncmp(str1, str2, 3);535 assert(rv == 0);536 ASSERT_ZERO_LABEL(rv);537 538 rv = strncmp(str1, str1, 4);539 assert(rv == 0);540#ifdef STRICT_DATA_DEPENDENCIES541 ASSERT_ZERO_LABEL(rv);542#else543 ASSERT_LABEL(rv, i_label);544 ASSERT_EQ_ORIGIN(rv, str1[3]);545#endif546}547 548void test_strcasecmp() {549 char str1[] = "str1", str2[] = "str2", str3[] = "Str1";550 dfsan_set_label(i_label, &str1[3], 1);551 dfsan_set_label(j_label, &str2[3], 1);552 dfsan_set_label(j_label, &str3[2], 1);553 554 int rv = strcasecmp(str1, str2);555 assert(rv < 0);556#ifdef STRICT_DATA_DEPENDENCIES557 ASSERT_ZERO_LABEL(rv);558#else559 ASSERT_LABEL(rv, dfsan_union(i_label, j_label));560 ASSERT_EQ_ORIGIN(rv, str1[3]);561#endif562 563 rv = strcasecmp(str1, str3);564 assert(rv == 0);565#ifdef STRICT_DATA_DEPENDENCIES566 ASSERT_ZERO_LABEL(rv);567#else568 ASSERT_LABEL(rv, dfsan_union(i_label, j_label));569 ASSERT_EQ_ORIGIN(rv, str1[3]);570#endif571 572 char s1[] = "AbZ";573 char s2[] = "aBy";574 dfsan_set_label(i_label, &s1[2], 1);575 dfsan_set_label(j_label, &s2[2], 1);576 577 rv = strcasecmp(s1, s2);578 assert(rv > 0); // 'Z' > 'y'579#ifdef STRICT_DATA_DEPENDENCIES580 ASSERT_ZERO_LABEL(rv);581#else582 ASSERT_LABEL(rv, dfsan_union(i_label, j_label));583 ASSERT_EQ_ORIGIN(rv, s1[2]);584#endif585}586 587void test_strncasecmp() {588 char str1[] = "Str1", str2[] = "str2";589 dfsan_set_label(i_label, &str1[3], 1);590 dfsan_set_label(j_label, &str2[3], 1);591 592 int rv = strncasecmp(str1, str2, sizeof(str1));593 assert(rv < 0);594#ifdef STRICT_DATA_DEPENDENCIES595 ASSERT_ZERO_LABEL(rv);596#else597 ASSERT_LABEL(rv, dfsan_union(i_label, j_label));598 ASSERT_EQ_ORIGIN(rv, str1[3]);599#endif600 601 rv = strncasecmp(str1, str2, 3);602 assert(rv == 0);603 ASSERT_ZERO_LABEL(rv);604 605 char s1[] = "AbZ";606 char s2[] = "aBy";607 dfsan_set_label(i_label, &s1[2], 1);608 dfsan_set_label(j_label, &s2[2], 1);609 610 rv = strncasecmp(s1, s2, 0);611 assert(rv == 0); // Compare zero chars.612 ASSERT_ZERO_LABEL(rv);613 614 rv = strncasecmp(s1, s2, 1);615 assert(rv == 0); // 'A' == 'a'616 ASSERT_ZERO_LABEL(rv);617 618 rv = strncasecmp(s1, s2, 2);619 assert(rv == 0); // 'b' == 'B'620 ASSERT_ZERO_LABEL(rv);621 622 rv = strncasecmp(s1, s2, 3);623 assert(rv > 0); // 'Z' > 'y'624#ifdef STRICT_DATA_DEPENDENCIES625 ASSERT_ZERO_LABEL(rv);626#else627 ASSERT_LABEL(rv, dfsan_union(i_label, j_label));628 ASSERT_EQ_ORIGIN(rv, s1[2]);629#endif630}631 632void test_strchr() {633 char str1[] = "str1";634 dfsan_set_label(i_label, &str1[3], 1);635 636 char *p1 = str1;637 char c = 'r';638 dfsan_set_label(k_label, &c, sizeof(c));639 640 char *crv = strchr(p1, c);641 assert(crv == &str1[2]);642#ifdef STRICT_DATA_DEPENDENCIES643 ASSERT_ZERO_LABEL(crv);644#else645 ASSERT_LABEL(crv, k_label);646 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv, c);647#endif648 649 dfsan_set_label(j_label, &p1, sizeof(p1));650 crv = strchr(p1, 'r');651 assert(crv == &str1[2]);652 ASSERT_LABEL(crv, j_label);653 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv, p1);654 655 crv = strchr(p1, '1');656 assert(crv == &str1[3]);657#ifdef STRICT_DATA_DEPENDENCIES658 ASSERT_LABEL(crv, j_label);659 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv, p1);660#else661 ASSERT_LABEL(crv, i_j_label);662 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv, str1[3]);663#endif664 665 crv = strchr(p1, 'x');666 assert(!crv);667#ifdef STRICT_DATA_DEPENDENCIES668 ASSERT_LABEL(crv, j_label);669 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv, p1);670#else671 ASSERT_LABEL(crv, i_j_label);672 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv, str1[3]);673#endif674 675 // `man strchr` says:676 // The terminating null byte is considered part of the string, so that if c677 // is specified as '\0', these functions return a pointer to the terminator.678 crv = strchr(p1, '\0');679 assert(crv == &str1[4]);680#ifdef STRICT_DATA_DEPENDENCIES681 ASSERT_LABEL(crv, j_label);682 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv, p1);683#else684 ASSERT_LABEL(crv, i_j_label);685 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv, str1[3]);686#endif687}688 689void test_recvmmsg() {690 int sockfds[2];691 int ret = socketpair(AF_UNIX, SOCK_DGRAM, 0, sockfds);692 assert(ret != -1);693 694 // Setup messages to send.695 struct mmsghdr smmsg[2] = {};696 char sbuf0[] = "abcdefghijkl";697 struct iovec siov0[2] = {{&sbuf0[0], 4}, {&sbuf0[4], 4}};698 smmsg[0].msg_hdr.msg_iov = siov0;699 smmsg[0].msg_hdr.msg_iovlen = 2;700 char sbuf1[] = "1234567890";701 struct iovec siov1[1] = {{&sbuf1[0], 7}};702 smmsg[1].msg_hdr.msg_iov = siov1;703 smmsg[1].msg_hdr.msg_iovlen = 1;704 705 // Send messages.706 int sent_msgs = sendmmsg(sockfds[0], smmsg, 2, 0);707 assert(sent_msgs == 2);708 709 // Setup receive buffers.710 struct mmsghdr rmmsg[2] = {};711 char rbuf0[128];712 struct iovec riov0[2] = {{&rbuf0[0], 4}, {&rbuf0[4], 4}};713 rmmsg[0].msg_hdr.msg_iov = riov0;714 rmmsg[0].msg_hdr.msg_iovlen = 2;715 char rbuf1[128];716 struct iovec riov1[1] = {{&rbuf1[0], 16}};717 rmmsg[1].msg_hdr.msg_iov = riov1;718 rmmsg[1].msg_hdr.msg_iovlen = 1;719 struct timespec timeout = {1, 1};720 dfsan_set_label(i_label, rbuf0, sizeof(rbuf0));721 dfsan_set_label(i_label, rbuf1, sizeof(rbuf1));722 dfsan_set_label(i_label, &rmmsg[0].msg_len, sizeof(rmmsg[0].msg_len));723 dfsan_set_label(i_label, &rmmsg[1].msg_len, sizeof(rmmsg[1].msg_len));724 dfsan_set_label(i_label, &timeout, sizeof(timeout));725 726 dfsan_origin msg_len0_o = dfsan_get_origin((long)(rmmsg[0].msg_len));727 dfsan_origin msg_len1_o = dfsan_get_origin((long)(rmmsg[1].msg_len));728#ifndef ORIGIN_TRACKING729 (void)msg_len0_o;730 (void)msg_len1_o;731#endif732 733 // Receive messages and check labels.734 int received_msgs = recvmmsg(sockfds[1], rmmsg, 2, 0, &timeout);735 assert(received_msgs == sent_msgs);736 assert(rmmsg[0].msg_len == smmsg[0].msg_len);737 assert(rmmsg[1].msg_len == smmsg[1].msg_len);738 assert(memcmp(sbuf0, rbuf0, 8) == 0);739 assert(memcmp(sbuf1, rbuf1, 7) == 0);740 ASSERT_ZERO_LABEL(received_msgs);741 ASSERT_ZERO_LABEL(rmmsg[0].msg_len);742 ASSERT_ZERO_LABEL(rmmsg[1].msg_len);743 ASSERT_READ_ZERO_LABEL(&rbuf0[0], 8);744 ASSERT_READ_LABEL(&rbuf0[8], 1, i_label);745 ASSERT_READ_ZERO_LABEL(&rbuf1[0], 7);746 ASSERT_READ_LABEL(&rbuf1[7], 1, i_label);747 ASSERT_LABEL(timeout.tv_sec, i_label);748 ASSERT_LABEL(timeout.tv_nsec, i_label);749 750 ASSERT_ORIGIN((long)(rmmsg[0].msg_len), msg_len0_o);751 ASSERT_ORIGIN((long)(rmmsg[1].msg_len), msg_len1_o);752 753 close(sockfds[0]);754 close(sockfds[1]);755}756 757void test_recvmsg() {758 int sockfds[2];759 int ret = socketpair(AF_UNIX, SOCK_DGRAM, 0, sockfds);760 assert(ret != -1);761 762 char sbuf[] = "abcdefghijkl";763 struct iovec siovs[2] = {{&sbuf[0], 4}, {&sbuf[4], 4}};764 struct msghdr smsg = {};765 smsg.msg_iov = siovs;766 smsg.msg_iovlen = 2;767 768 ssize_t sent = sendmsg(sockfds[0], &smsg, 0);769 assert(sent > 0);770 771 {772 char rpbuf[2];773 struct iovec peek_iov;774 peek_iov.iov_base = rpbuf;775 peek_iov.iov_len = 2;776 777 struct msghdr peek_header = {};778 peek_header.msg_iov = &peek_iov;779 peek_header.msg_iovlen = 1;780 781 dfsan_set_label(i_label, rpbuf, sizeof(rpbuf));782 dfsan_set_label(i_label, &peek_header, sizeof(peek_header));783 784 DEFINE_AND_SAVE_ORIGINS(peek_header)785 786 ssize_t received = recvmsg(sockfds[1], &peek_header, MSG_PEEK | MSG_TRUNC);787 assert(received == sent);788 assert(memcmp(sbuf, rpbuf, 2) == 0);789 ASSERT_ZERO_LABEL(received);790 ASSERT_READ_ZERO_LABEL(&peek_header, sizeof(peek_header));791 ASSERT_READ_ZERO_LABEL(&rpbuf[0], 0);792 793 ASSERT_SAVED_ORIGINS(peek_header)794 }795 796 {797 char rbuf[128];798 struct iovec riovs[2] = {{&rbuf[0], 4}, {&rbuf[4], 4}};799 struct msghdr rmsg = {};800 rmsg.msg_iov = riovs;801 rmsg.msg_iovlen = 2;802 803 dfsan_set_label(i_label, rbuf, sizeof(rbuf));804 dfsan_set_label(i_label, &rmsg, sizeof(rmsg));805 806 DEFINE_AND_SAVE_ORIGINS(rmsg)807 808 ssize_t received = recvmsg(sockfds[1], &rmsg, 0);809 assert(received == sent);810 assert(memcmp(sbuf, rbuf, 8) == 0);811 ASSERT_ZERO_LABEL(received);812 ASSERT_READ_ZERO_LABEL(&rmsg, sizeof(rmsg));813 ASSERT_READ_ZERO_LABEL(&rbuf[0], 8);814 ASSERT_READ_LABEL(&rbuf[8], 1, i_label);815 816 ASSERT_SAVED_ORIGINS(rmsg)817 }818 819 close(sockfds[0]);820 close(sockfds[1]);821}822 823void test_read() {824 char buf[16];825 dfsan_set_label(i_label, buf, 1);826 dfsan_set_label(j_label, buf + 15, 1);827 828 DEFINE_AND_SAVE_ORIGINS(buf)829 ASSERT_LABEL(buf[0], i_label);830 ASSERT_LABEL(buf[15], j_label);831 832 int fd = open("/dev/zero", O_RDONLY);833 int rv = read(fd, buf, sizeof(buf));834 assert(rv == sizeof(buf));835 ASSERT_ZERO_LABEL(rv);836 ASSERT_ZERO_LABEL(buf[0]);837 ASSERT_ZERO_LABEL(buf[15]);838 ASSERT_SAVED_ORIGINS(buf)839 close(fd);840}841 842void test_pread() {843 char buf[16];844 dfsan_set_label(i_label, buf, 1);845 dfsan_set_label(j_label, buf + 15, 1);846 847 DEFINE_AND_SAVE_ORIGINS(buf)848 ASSERT_LABEL(buf[0], i_label);849 ASSERT_LABEL(buf[15], j_label);850 851 int fd = open("/bin/sh", O_RDONLY);852 int rv = pread(fd, buf, sizeof(buf), 0);853 assert(rv == sizeof(buf));854 ASSERT_ZERO_LABEL(rv);855 ASSERT_ZERO_LABEL(buf[0]);856 ASSERT_ZERO_LABEL(buf[15]);857 ASSERT_SAVED_ORIGINS(buf)858 close(fd);859}860 861void test_dlopen() {862 void *map = dlopen(NULL, RTLD_NOW);863 assert(map);864 ASSERT_ZERO_LABEL(map);865 dlclose(map);866 map = dlopen("/nonexistent", RTLD_NOW);867 assert(!map);868 ASSERT_ZERO_LABEL(map);869}870 871void test_clock_gettime() {872 struct timespec tp;873 dfsan_set_label(j_label, ((char *)&tp) + 3, 1);874 dfsan_origin origin = dfsan_get_origin((long)(((char *)&tp)[3]));875#ifndef ORIGIN_TRACKING876 (void)origin;877#endif878 int t = clock_gettime(CLOCK_REALTIME, &tp);879 assert(t == 0);880 ASSERT_ZERO_LABEL(t);881 ASSERT_ZERO_LABEL(((char *)&tp)[3]);882 ASSERT_ORIGIN(((char *)&tp)[3], origin);883}884 885void test_ctime_r() {886 char *buf = (char*) malloc(64);887 time_t t = 0;888 889 DEFINE_AND_SAVE_ORIGINS(buf)890 dfsan_origin t_o = dfsan_get_origin((long)t);891 892 char *ret = ctime_r(&t, buf);893 ASSERT_ZERO_LABEL(ret);894 assert(buf == ret);895 ASSERT_READ_ZERO_LABEL(buf, strlen(buf) + 1);896 ASSERT_SAVED_ORIGINS(buf)897 898 dfsan_set_label(i_label, &t, sizeof(t));899 t_o = dfsan_get_origin((long)t);900 ret = ctime_r(&t, buf);901 ASSERT_ZERO_LABEL(ret);902 ASSERT_READ_LABEL(buf, strlen(buf) + 1, i_label);903 for (int i = 0; i < strlen(buf) + 1; ++i)904 ASSERT_ORIGIN(buf[i], t_o);905 906 t = 0;907 dfsan_set_label(j_label, &buf, sizeof(&buf));908 dfsan_origin buf_ptr_o = dfsan_get_origin((long)buf);909#ifndef ORIGIN_TRACKING910 (void)buf_ptr_o;911#endif912 ret = ctime_r(&t, buf);913 ASSERT_LABEL(ret, j_label);914 ASSERT_ORIGIN(ret, buf_ptr_o);915 ASSERT_READ_ZERO_LABEL(buf, strlen(buf) + 1);916 for (int i = 0; i < strlen(buf) + 1; ++i)917 ASSERT_ORIGIN(buf[i], t_o);918}919 920static int write_callback_count = 0;921static int last_fd;922static const unsigned char *last_buf;923static size_t last_count;924 925void write_callback(int fd, const void *buf, size_t count) {926 write_callback_count++;927 928 last_fd = fd;929 last_buf = (const unsigned char*) buf;930 last_count = count;931}932 933void test_dfsan_set_write_callback() {934 char a_buf[] = "Sample chars";935 int a_buf_len = strlen(a_buf);936 937 int fd = open("/dev/null", O_WRONLY);938 939 dfsan_set_write_callback(write_callback);940 941 write_callback_count = 0;942 943 DEFINE_AND_SAVE_ORIGINS(a_buf)944 945 // Callback should be invoked on every call to write().946 int res = write(fd, a_buf, a_buf_len);947 assert(write_callback_count == 1);948 ASSERT_READ_ZERO_LABEL(&res, sizeof(res));949 ASSERT_READ_ZERO_LABEL(&last_fd, sizeof(last_fd));950 ASSERT_READ_ZERO_LABEL(last_buf, sizeof(last_buf));951 952 for (int i = 0; i < a_buf_len; ++i)953 ASSERT_ORIGIN(last_buf[i], a_buf_o[i]);954 955 ASSERT_ZERO_ORIGINS(&last_count, sizeof(last_count));956 last_fd = 0;957 last_buf = 0;958 last_count = 0;959 960 char b_buf[] = "Other chars";961 int b_buf_len = strlen(b_buf);962 // Create a separate variable so we can taint the pointer.963 // We would always get a shadow of 0 for b_buf because it is a constant.964 const unsigned char *buf = (const unsigned char *)b_buf;965 966 // Add a label to write() arguments. Check that the labels are readable from967 // the values passed to the callback.968 dfsan_set_label(i_label, &fd, sizeof(fd));969 dfsan_set_label(j_label, &buf, sizeof(buf)); // ptr970 dfsan_set_label(k_label, &(b_buf[3]), 1); // content971 dfsan_set_label(m_label, &b_buf_len, sizeof(b_buf_len));972 973 dfsan_origin fd_o = dfsan_get_origin((long)fd);974 dfsan_origin b_buf3_o = dfsan_get_origin((long)(b_buf[3]));975 dfsan_origin b_buf_len_o = dfsan_get_origin((long)b_buf_len);976#ifndef ORIGIN_TRACKING977 (void)fd_o;978 (void)b_buf3_o;979 (void)b_buf_len_o;980#endif981 DEFINE_AND_SAVE_ORIGINS(b_buf)982 983 res = write(fd, buf, b_buf_len);984 assert(write_callback_count == 2);985 assert(last_fd == fd);986 assert(last_buf == (const unsigned char *)b_buf);987 assert(last_count == b_buf_len);988 989 ASSERT_READ_ZERO_LABEL(&res, sizeof(res));990 ASSERT_READ_LABEL(&last_fd, sizeof(last_fd), i_label);991 ASSERT_READ_LABEL(&last_buf, sizeof(&last_buf), j_label); // ptr992 ASSERT_READ_LABEL(last_buf, last_count, k_label); // content993 ASSERT_READ_LABEL(&last_buf[3], sizeof(last_buf[3]), k_label); // content994 ASSERT_READ_LABEL(&last_count, sizeof(last_count), m_label);995 ASSERT_ZERO_ORIGINS(&res, sizeof(res));996 ASSERT_INIT_ORIGINS(&last_fd, sizeof(last_fd), fd_o);997 ASSERT_INIT_ORIGINS(&last_buf[3], sizeof(last_buf[3]), b_buf3_o);998 999 // Origins are assigned for every 4 contiguous 4-aligned bytes. After1000 // appending src to dst, origins of src can overwrite origins of dst if their1001 // application adddresses are within an aligned range. Other origins are not1002 // changed.1003 for (int i = 0; i < b_buf_len; ++i) {1004 size_t i_addr = size_t(&last_buf[i]);1005 if (((size_t(&last_buf[3]) & ~3UL) > i_addr) ||1006 (((size_t(&last_buf[3]) + 4) & ~3UL) <= i_addr))1007 ASSERT_ORIGIN(last_buf[i], b_buf_o[i]);1008 }1009 1010 ASSERT_INIT_ORIGINS(&last_count, sizeof(last_count), b_buf_len_o);1011 1012 dfsan_set_write_callback(NULL);1013}1014 1015void test_fgets() {1016 char *buf = (char*) malloc(128);1017 FILE *f = fopen("/etc/passwd", "r");1018 dfsan_set_label(j_label, buf, 1);1019 DEFINE_AND_SAVE_N_ORIGINS(buf, 128)1020 1021 char *ret = fgets(buf, sizeof(buf), f);1022 assert(ret == buf);1023 ASSERT_ZERO_LABEL(ret);1024 ASSERT_EQ_ORIGIN(ret, buf);1025 ASSERT_READ_ZERO_LABEL(buf, 128);1026 ASSERT_SAVED_N_ORIGINS(buf, 128)1027 1028 dfsan_set_label(j_label, &buf, sizeof(&buf));1029 ret = fgets(buf, sizeof(buf), f);1030 ASSERT_LABEL(ret, j_label);1031 ASSERT_EQ_ORIGIN(ret, buf);1032 ASSERT_SAVED_N_ORIGINS(buf, 128)1033 1034 fclose(f);1035 free(buf);1036}1037 1038void test_getcwd() {1039 char buf[1024];1040 char *ptr = buf;1041 dfsan_set_label(i_label, buf + 2, 2);1042 DEFINE_AND_SAVE_ORIGINS(buf)1043 1044 char* ret = getcwd(buf, sizeof(buf));1045 assert(ret == buf);1046 assert(ret[0] == '/');1047 ASSERT_ZERO_LABEL(ret);1048 ASSERT_EQ_ORIGIN(ret, buf);1049 ASSERT_READ_ZERO_LABEL(buf + 2, 2);1050 ASSERT_SAVED_ORIGINS(buf)1051 1052 dfsan_set_label(i_label, &ptr, sizeof(ptr));1053 ret = getcwd(ptr, sizeof(buf));1054 ASSERT_LABEL(ret, i_label);1055 ASSERT_EQ_ORIGIN(ret, ptr);1056 ASSERT_SAVED_ORIGINS(buf)1057}1058 1059void test_get_current_dir_name() {1060 char* ret = get_current_dir_name();1061 assert(ret);1062 assert(ret[0] == '/');1063 ASSERT_READ_ZERO_LABEL(ret, strlen(ret) + 1);1064 ASSERT_ZERO_LABEL(ret);1065}1066 1067void test_getentropy() {1068 char buf[64];1069 dfsan_set_label(i_label, buf + 2, 2);1070 DEFINE_AND_SAVE_ORIGINS(buf)1071#if __GLIBC_PREREQ(2, 25)1072 // glibc >= 2.25 has getentropy()1073 int ret = getentropy(buf, sizeof(buf));1074 ASSERT_ZERO_LABEL(ret);1075 if (ret == 0) {1076 ASSERT_READ_ZERO_LABEL(buf + 2, 2);1077 ASSERT_SAVED_ORIGINS(buf)1078 }1079#endif1080}1081 1082void test_gethostname() {1083 char buf[1024];1084 dfsan_set_label(i_label, buf + 2, 2);1085 DEFINE_AND_SAVE_ORIGINS(buf)1086 int ret = gethostname(buf, sizeof(buf));1087 assert(ret == 0);1088 ASSERT_ZERO_LABEL(ret);1089 ASSERT_READ_ZERO_LABEL(buf + 2, 2);1090 ASSERT_SAVED_ORIGINS(buf)1091}1092 1093void test_getrlimit() {1094 struct rlimit rlim;1095 dfsan_set_label(i_label, &rlim, sizeof(rlim));1096 DEFINE_AND_SAVE_ORIGINS(rlim);1097 int ret = getrlimit(RLIMIT_CPU, &rlim);1098 assert(ret == 0);1099 ASSERT_ZERO_LABEL(ret);1100 ASSERT_READ_ZERO_LABEL(&rlim, sizeof(rlim));1101 ASSERT_SAVED_ORIGINS(rlim)1102}1103 1104void test_getrusage() {1105 struct rusage usage;1106 dfsan_set_label(i_label, &usage, sizeof(usage));1107 DEFINE_AND_SAVE_ORIGINS(usage);1108 int ret = getrusage(RUSAGE_SELF, &usage);1109 assert(ret == 0);1110 ASSERT_ZERO_LABEL(ret);1111 ASSERT_READ_ZERO_LABEL(&usage, sizeof(usage));1112 ASSERT_SAVED_ORIGINS(usage)1113}1114 1115void test_strcpy() {1116 char src[] = "hello world";1117 char dst[sizeof(src) + 2];1118 char *p_dst = dst;1119 dfsan_set_label(0, src, sizeof(src));1120 dfsan_set_label(0, dst, sizeof(dst));1121 dfsan_set_label(k_label, &p_dst, sizeof(p_dst));1122 dfsan_set_label(i_label, src + 2, 1);1123 dfsan_set_label(j_label, src + 3, 1);1124 dfsan_set_label(j_label, dst + 4, 1);1125 dfsan_set_label(i_label, dst + 12, 1);1126 char *ret = strcpy(p_dst, src);1127 assert(ret == dst);1128 assert(strcmp(src, dst) == 0);1129 ASSERT_LABEL(ret, k_label);1130 ASSERT_EQ_ORIGIN(ret, p_dst);1131 for (int i = 0; i < strlen(src) + 1; ++i) {1132 assert(dfsan_get_label(dst[i]) == dfsan_get_label(src[i]));1133 if (dfsan_get_label(dst[i]))1134 assert(dfsan_get_init_origin(&dst[i]) == dfsan_get_origin(src[i]));1135 }1136 // Note: if strlen(src) + 1 were used instead to compute the first untouched1137 // byte of dest, the label would be I|J. This is because strlen() might1138 // return a non-zero label, and because by default pointer labels are not1139 // ignored on loads.1140 ASSERT_LABEL(dst[12], i_label);1141}1142 1143void test_strtol() {1144 char non_number_buf[] = "ab ";1145 char *endptr = NULL;1146 long int ret = strtol(non_number_buf, &endptr, 10);1147 assert(ret == 0);1148 assert(endptr == non_number_buf);1149 ASSERT_ZERO_LABEL(ret);1150 1151 char buf[] = "1234578910";1152 int base = 10;1153 dfsan_set_label(k_label, &base, sizeof(base));1154 ret = strtol(buf, &endptr, base);1155 assert(ret == 1234578910);1156 assert(endptr == buf + 10);1157 ASSERT_LABEL(ret, k_label);1158 ASSERT_EQ_ORIGIN(ret, base);1159 1160 dfsan_set_label(i_label, buf + 1, 1);1161 dfsan_set_label(j_label, buf + 10, 1);1162 ret = strtol(buf, &endptr, 10);1163 assert(ret == 1234578910);1164 assert(endptr == buf + 10);1165 ASSERT_LABEL(ret, i_j_label);1166 ASSERT_EQ_ORIGIN(ret, buf[1]);1167}1168 1169void test_strtoll() {1170 char non_number_buf[] = "ab ";1171 char *endptr = NULL;1172 long long int ret = strtoll(non_number_buf, &endptr, 10);1173 assert(ret == 0);1174 assert(endptr == non_number_buf);1175 ASSERT_ZERO_LABEL(ret);1176 1177 char buf[] = "1234578910 ";1178 int base = 10;1179 dfsan_set_label(k_label, &base, sizeof(base));1180 ret = strtoll(buf, &endptr, base);1181 assert(ret == 1234578910);1182 assert(endptr == buf + 10);1183 ASSERT_LABEL(ret, k_label);1184 ASSERT_EQ_ORIGIN(ret, base);1185 1186 dfsan_set_label(i_label, buf + 1, 1);1187 dfsan_set_label(j_label, buf + 2, 1);1188 ret = strtoll(buf, &endptr, 10);1189 assert(ret == 1234578910);1190 assert(endptr == buf + 10);1191 ASSERT_LABEL(ret, i_j_label);1192 ASSERT_EQ_ORIGIN(ret, buf[1]);1193}1194 1195void test_strtoul() {1196 char non_number_buf[] = "xy ";1197 char *endptr = NULL;1198 long unsigned int ret = strtoul(non_number_buf, &endptr, 16);1199 assert(ret == 0);1200 assert(endptr == non_number_buf);1201 ASSERT_ZERO_LABEL(ret);1202 1203 char buf[] = "ffffffffffffaa";1204 int base = 16;1205 dfsan_set_label(k_label, &base, sizeof(base));1206 ret = strtoul(buf, &endptr, base);1207 assert(ret == 72057594037927850);1208 assert(endptr == buf + 14);1209 ASSERT_LABEL(ret, k_label);1210 ASSERT_EQ_ORIGIN(ret, base);1211 1212 dfsan_set_label(i_label, buf + 1, 1);1213 dfsan_set_label(j_label, buf + 2, 1);1214 ret = strtoul(buf, &endptr, 16);1215 assert(ret == 72057594037927850);1216 assert(endptr == buf + 14);1217 ASSERT_LABEL(ret, i_j_label);1218 ASSERT_EQ_ORIGIN(ret, buf[1]);1219}1220 1221void test_strtoull() {1222 char non_number_buf[] = "xy ";1223 char *endptr = NULL;1224 long long unsigned int ret = strtoull(non_number_buf, &endptr, 16);1225 assert(ret == 0);1226 assert(endptr == non_number_buf);1227 ASSERT_ZERO_LABEL(ret);1228 1229 char buf[] = "ffffffffffffffaa";1230 int base = 16;1231 dfsan_set_label(k_label, &base, sizeof(base));1232 ret = strtoull(buf, &endptr, base);1233 assert(ret == 0xffffffffffffffaa);1234 assert(endptr == buf + 16);1235 ASSERT_LABEL(ret, k_label);1236 ASSERT_EQ_ORIGIN(ret, base);1237 1238 dfsan_set_label(i_label, buf + 1, 1);1239 dfsan_set_label(j_label, buf + 2, 1);1240 ret = strtoull(buf, &endptr, 16);1241 assert(ret == 0xffffffffffffffaa);1242 assert(endptr == buf + 16);1243 ASSERT_LABEL(ret, i_j_label);1244 ASSERT_EQ_ORIGIN(ret, buf[1]);1245}1246 1247void test_strtod() {1248 char non_number_buf[] = "ab ";1249 char *endptr = NULL;1250 double ret = strtod(non_number_buf, &endptr);1251 assert(ret == 0);1252 assert(endptr == non_number_buf);1253 ASSERT_ZERO_LABEL(ret);1254 1255 char buf[] = "12345.76 foo";1256 dfsan_set_label(i_label, buf + 1, 1);1257 dfsan_set_label(j_label, buf + 6, 1);1258 ret = strtod(buf, &endptr);1259 assert(ret == 12345.76);1260 assert(endptr == buf + 8);1261 ASSERT_LABEL(ret, i_j_label);1262 ASSERT_EQ_ORIGIN(ret, buf[1]);1263}1264 1265void test_time() {1266 time_t t = 0;1267 dfsan_set_label(i_label, &t, 1);1268 DEFINE_AND_SAVE_ORIGINS(t)1269 time_t ret = time(&t);1270 assert(ret == t);1271 assert(ret > 0);1272 ASSERT_ZERO_LABEL(ret);1273 ASSERT_ZERO_LABEL(t);1274 ASSERT_SAVED_ORIGINS(t)1275}1276 1277void test_inet_pton() {1278 char addr4[] = "127.0.0.1";1279 dfsan_set_label(i_label, addr4 + 3, 1);1280 struct in_addr in4;1281 int ret4 = inet_pton(AF_INET, addr4, &in4);1282 assert(ret4 == 1);1283 ASSERT_ZERO_LABEL(ret4);1284 ASSERT_READ_LABEL(&in4, sizeof(in4), i_label);1285 ASSERT_ORIGINS(&in4, sizeof(in4), dfsan_get_origin((long)(addr4[3])))1286 assert(in4.s_addr == htonl(0x7f000001));1287 1288 char addr6[] = "::1";1289 dfsan_set_label(j_label, addr6 + 3, 1);1290 struct in6_addr in6;1291 int ret6 = inet_pton(AF_INET6, addr6, &in6);1292 assert(ret6 == 1);1293 ASSERT_ZERO_LABEL(ret6);1294 ASSERT_READ_LABEL(((char *) &in6) + sizeof(in6) - 1, 1, j_label);1295 ASSERT_ORIGINS(&in6, sizeof(in6), dfsan_get_origin((long)(addr6[3])))1296}1297 1298void test_localtime_r() {1299 time_t t0 = 1384800998;1300 struct tm t1;1301 dfsan_set_label(i_label, &t0, sizeof(t0));1302 dfsan_origin t0_o = dfsan_get_origin((long)t0);1303 struct tm *pt1 = &t1;1304 dfsan_set_label(j_label, &pt1, sizeof(pt1));1305 dfsan_origin pt1_o = dfsan_get_origin((long)pt1);1306 1307#ifndef ORIGIN_TRACKING1308 (void)t0_o;1309 (void)pt1_o;1310#endif1311 1312 struct tm *ret = localtime_r(&t0, pt1);1313 assert(ret == &t1);1314 assert(t1.tm_min == 56);1315 ASSERT_LABEL(ret, j_label);1316 ASSERT_INIT_ORIGIN(&ret, pt1_o);1317 ASSERT_READ_LABEL(&ret, sizeof(ret), j_label);1318 ASSERT_LABEL(t1.tm_mon, i_label);1319 ASSERT_ORIGIN(t1.tm_mon, t0_o);1320}1321 1322void test_getpwuid_r() {1323 struct passwd pwd;1324 char buf[1024];1325 struct passwd *result;1326 1327 dfsan_set_label(i_label, &pwd, 4);1328 DEFINE_AND_SAVE_ORIGINS(pwd)1329 DEFINE_AND_SAVE_ORIGINS(buf)1330 int ret = getpwuid_r(0, &pwd, buf, sizeof(buf), &result);1331 assert(ret == 0);1332 assert(strcmp(pwd.pw_name, "root") == 0);1333 assert(result == &pwd);1334 ASSERT_ZERO_LABEL(ret);1335 ASSERT_READ_ZERO_LABEL(&pwd, 4);1336 ASSERT_SAVED_ORIGINS(pwd)1337 ASSERT_SAVED_ORIGINS(buf)1338}1339 1340void test_epoll_wait() {1341 // Set up a pipe to monitor with epoll.1342 int pipe_fds[2];1343 int ret = pipe(pipe_fds);1344 assert(ret != -1);1345 1346 // Configure epoll to monitor the pipe.1347 int epfd = epoll_create1(0);1348 assert(epfd != -1);1349 struct epoll_event event;1350 event.events = EPOLLIN;1351 event.data.fd = pipe_fds[0];1352 ret = epoll_ctl(epfd, EPOLL_CTL_ADD, pipe_fds[0], &event);1353 assert(ret != -1);1354 1355 // Test epoll_wait when no events have occurred.1356 event = {};1357 dfsan_set_label(i_label, &event, sizeof(event));1358 DEFINE_AND_SAVE_ORIGINS(event)1359 ret = epoll_wait(epfd, &event, /*maxevents=*/1, /*timeout=*/0);1360 assert(ret == 0);1361 assert(event.events == 0);1362 assert(event.data.fd == 0);1363 ASSERT_ZERO_LABEL(ret);1364 ASSERT_READ_LABEL(&event, sizeof(event), i_label);1365 ASSERT_SAVED_ORIGINS(event)1366 1367 // Test epoll_wait when an event occurs.1368 write(pipe_fds[1], "x", 1);1369 ret = epoll_wait(epfd, &event, /*maxevents=*/1, /*timeout=*/0);1370 assert(ret == 1);1371 assert(event.events == EPOLLIN);1372 assert(event.data.fd == pipe_fds[0]);1373 ASSERT_ZERO_LABEL(ret);1374 ASSERT_READ_ZERO_LABEL(&event, sizeof(event));1375 ASSERT_SAVED_ORIGINS(event)1376 1377 // Clean up.1378 close(epfd);1379 close(pipe_fds[0]);1380 close(pipe_fds[1]);1381}1382 1383void test_poll() {1384 struct pollfd fd;1385 fd.fd = 0;1386 fd.events = POLLIN;1387 dfsan_set_label(i_label, &fd.revents, sizeof(fd.revents));1388 DEFINE_AND_SAVE_ORIGINS(fd)1389 int ret = poll(&fd, 1, 1);1390 ASSERT_ZERO_LABEL(ret);1391 ASSERT_ZERO_LABEL(fd.revents);1392 ASSERT_SAVED_ORIGINS(fd)1393 assert(ret >= 0);1394}1395 1396void test_select() {1397 struct timeval t;1398 fd_set fds;1399 t.tv_sec = 2;1400 FD_SET(0, &fds);1401 dfsan_set_label(i_label, &fds, sizeof(fds));1402 dfsan_set_label(j_label, &t, sizeof(t));1403 DEFINE_AND_SAVE_ORIGINS(fds)1404 DEFINE_AND_SAVE_ORIGINS(t)1405 int ret = select(1, &fds, NULL, NULL, &t);1406 assert(ret >= 0);1407 ASSERT_ZERO_LABEL(ret);1408 ASSERT_ZERO_LABEL(t.tv_sec);1409 ASSERT_READ_ZERO_LABEL(&fds, sizeof(fds));1410 ASSERT_SAVED_ORIGINS(fds)1411 ASSERT_SAVED_ORIGINS(t)1412}1413 1414void test_sched_getaffinity() {1415 cpu_set_t mask;1416 dfsan_set_label(j_label, &mask, 1);1417 DEFINE_AND_SAVE_ORIGINS(mask)1418 int ret = sched_getaffinity(0, sizeof(mask), &mask);1419 assert(ret == 0);1420 ASSERT_ZERO_LABEL(ret);1421 ASSERT_READ_ZERO_LABEL(&mask, sizeof(mask));1422 ASSERT_SAVED_ORIGINS(mask)1423}1424 1425void test_sigemptyset() {1426 sigset_t set;1427 dfsan_set_label(j_label, &set, 1);1428 DEFINE_AND_SAVE_ORIGINS(set)1429 int ret = sigemptyset(&set);1430 assert(ret == 0);1431 ASSERT_ZERO_LABEL(ret);1432 ASSERT_READ_ZERO_LABEL(&set, sizeof(set));1433 ASSERT_SAVED_ORIGINS(set)1434}1435 1436static void SignalHandler(int signo) {}1437 1438static void SignalAction(int signo, siginfo_t *si, void *uc) {}1439 1440void test_sigaction() {1441 struct sigaction newact_with_sigaction = {};1442 newact_with_sigaction.sa_flags = SA_SIGINFO;1443 newact_with_sigaction.sa_sigaction = SignalAction;1444 1445 // Set sigaction to be SignalAction, save the last one into origin_act1446 struct sigaction origin_act;1447 dfsan_set_label(j_label, &origin_act, 1);1448 DEFINE_AND_SAVE_ORIGINS(origin_act)1449 int ret = sigaction(SIGUSR1, &newact_with_sigaction, &origin_act);1450 assert(ret == 0);1451 ASSERT_ZERO_LABEL(ret);1452 ASSERT_READ_ZERO_LABEL(&origin_act, sizeof(origin_act));1453 ASSERT_SAVED_ORIGINS(origin_act)1454 1455 struct sigaction newact_with_sighandler = {};1456 newact_with_sighandler.sa_handler = SignalHandler;1457 1458 // Set sigaction to be SignalHandler, check the last one is SignalAction1459 struct sigaction oldact;1460 assert(0 == sigaction(SIGUSR1, &newact_with_sighandler, &oldact));1461 assert(oldact.sa_sigaction == SignalAction);1462 assert(oldact.sa_flags & SA_SIGINFO);1463 1464 // Set SIG_IGN or SIG_DFL, and check the previous one is expected.1465 newact_with_sighandler.sa_handler = SIG_IGN;1466 assert(0 == sigaction(SIGUSR1, &newact_with_sighandler, &oldact));1467 assert(oldact.sa_handler == SignalHandler);1468 assert((oldact.sa_flags & SA_SIGINFO) == 0);1469 1470 newact_with_sighandler.sa_handler = SIG_DFL;1471 assert(0 == sigaction(SIGUSR1, &newact_with_sighandler, &oldact));1472 assert(oldact.sa_handler == SIG_IGN);1473 assert((oldact.sa_flags & SA_SIGINFO) == 0);1474 1475 // Restore sigaction to the orginal setting, check the last one is SignalHandler1476 assert(0 == sigaction(SIGUSR1, &origin_act, &oldact));1477 assert(oldact.sa_handler == SIG_DFL);1478 assert((oldact.sa_flags & SA_SIGINFO) == 0);1479}1480 1481void test_signal() {1482 // Set signal to be SignalHandler, save the previous one into1483 // old_signal_handler.1484 sighandler_t old_signal_handler = signal(SIGHUP, SignalHandler);1485 ASSERT_ZERO_LABEL(old_signal_handler);1486 1487 // Set SIG_IGN or SIG_DFL, and check the previous one is expected.1488 assert(SignalHandler == signal(SIGHUP, SIG_DFL));1489 assert(SIG_DFL == signal(SIGHUP, SIG_IGN));1490 1491 // Restore signal to old_signal_handler.1492 assert(SIG_IGN == signal(SIGHUP, old_signal_handler));1493}1494 1495void test_sigaltstack() {1496 stack_t old_altstack = {};1497 dfsan_set_label(j_label, &old_altstack, sizeof(old_altstack));1498 DEFINE_AND_SAVE_ORIGINS(old_altstack)1499 int ret = sigaltstack(NULL, &old_altstack);1500 assert(ret == 0);1501 ASSERT_ZERO_LABEL(ret);1502 ASSERT_READ_ZERO_LABEL(&old_altstack, sizeof(old_altstack));1503 ASSERT_SAVED_ORIGINS(old_altstack)1504}1505 1506void test_gettimeofday() {1507 struct timeval tv;1508 struct timezone tz;1509 dfsan_set_label(i_label, &tv, sizeof(tv));1510 dfsan_set_label(j_label, &tz, sizeof(tz));1511 DEFINE_AND_SAVE_ORIGINS(tv)1512 DEFINE_AND_SAVE_ORIGINS(tz)1513 int ret = gettimeofday(&tv, &tz);1514 assert(ret == 0);1515 ASSERT_READ_ZERO_LABEL(&tv, sizeof(tv));1516 ASSERT_READ_ZERO_LABEL(&tz, sizeof(tz));1517 ASSERT_SAVED_ORIGINS(tv)1518 ASSERT_SAVED_ORIGINS(tz)1519}1520 1521void *pthread_create_test_cb(void *p) {1522 assert(p == (void *)1);1523 ASSERT_ZERO_LABEL(p);1524 return (void *)2;1525}1526 1527void test_pthread_create() {1528 pthread_t pt;1529 int create_ret = pthread_create(&pt, 0, pthread_create_test_cb, (void *)1);1530 assert(create_ret == 0);1531 ASSERT_ZERO_LABEL(create_ret);1532 void *cbrv;1533 dfsan_set_label(i_label, &cbrv, sizeof(cbrv));1534 DEFINE_AND_SAVE_ORIGINS(cbrv)1535 int joint_ret = pthread_join(pt, &cbrv);1536 assert(joint_ret == 0);1537 assert(cbrv == (void *)2);1538 ASSERT_ZERO_LABEL(joint_ret);1539 ASSERT_ZERO_LABEL(cbrv);1540 ASSERT_SAVED_ORIGINS(cbrv);1541}1542 1543// Tested by test_pthread_create(). This empty function is here to appease the1544// check-wrappers script.1545void test_pthread_join() {}1546 1547int dl_iterate_phdr_test_cb(struct dl_phdr_info *info, size_t size,1548 void *data) {1549 assert(data == (void *)3);1550 ASSERT_ZERO_LABEL(info);1551 ASSERT_ZERO_LABEL(size);1552 ASSERT_ZERO_LABEL(data);1553 return 0;1554}1555 1556void test_dl_iterate_phdr() {1557 dl_iterate_phdr(dl_iterate_phdr_test_cb, (void *)3);1558}1559 1560// On glibc < 2.27, this symbol is not available. Mark it weak so we can skip1561// testing in this case.1562__attribute__((weak)) extern "C" void _dl_get_tls_static_info(size_t *sizep,1563 size_t *alignp);1564 1565void test__dl_get_tls_static_info() {1566 if (!_dl_get_tls_static_info)1567 return;1568 size_t sizep = 0, alignp = 0;1569 dfsan_set_label(i_label, &sizep, sizeof(sizep));1570 dfsan_set_label(i_label, &alignp, sizeof(alignp));1571 dfsan_origin sizep_o = dfsan_get_origin(sizep);1572 dfsan_origin alignp_o = dfsan_get_origin(alignp);1573#ifndef ORIGIN_TRACKING1574 (void)sizep_o;1575 (void)alignp_o;1576#endif1577 _dl_get_tls_static_info(&sizep, &alignp);1578 ASSERT_ZERO_LABEL(sizep);1579 ASSERT_ZERO_LABEL(alignp);1580 ASSERT_ORIGIN(sizep, sizep_o);1581 ASSERT_ORIGIN(alignp, alignp_o);1582}1583 1584void test_strrchr() {1585 char str1[] = "str1str1";1586 1587 char *p = str1;1588 dfsan_set_label(j_label, &p, sizeof(p));1589 1590 char *rv = strrchr(p, 'r');1591 assert(rv == &str1[6]);1592 ASSERT_LABEL(rv, j_label);1593 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, p);1594 1595 char c = 'r';1596 dfsan_set_label(k_label, &c, sizeof(c));1597 rv = strrchr(str1, c);1598 assert(rv == &str1[6]);1599#ifdef STRICT_DATA_DEPENDENCIES1600 ASSERT_ZERO_LABEL(rv);1601#else1602 ASSERT_LABEL(rv, k_label);1603 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, c);1604#endif1605 1606 dfsan_set_label(i_label, &str1[7], 1);1607 1608 rv = strrchr(str1, 'r');1609 assert(rv == &str1[6]);1610#ifdef STRICT_DATA_DEPENDENCIES1611 ASSERT_ZERO_LABEL(rv);1612#else1613 ASSERT_LABEL(rv, i_label);1614 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, str1[7]);1615#endif1616}1617 1618void test_strstr() {1619 char str1[] = "str1str1";1620 1621 char *p1 = str1;1622 dfsan_set_label(k_label, &p1, sizeof(p1));1623 char *rv = strstr(p1, "1s");1624 assert(rv == &str1[3]);1625 ASSERT_LABEL(rv, k_label);1626 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, p1);1627 1628 char str2[] = "1s";1629 char *p2 = str2;1630 dfsan_set_label(m_label, &p2, sizeof(p2));1631 rv = strstr(str1, p2);1632 assert(rv == &str1[3]);1633#ifdef STRICT_DATA_DEPENDENCIES1634 ASSERT_ZERO_LABEL(rv);1635#else1636 ASSERT_LABEL(rv, m_label);1637 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, p2);1638#endif1639 1640 dfsan_set_label(n_label, &str2[0], 1);1641 rv = strstr(str1, str2);1642 assert(rv == &str1[3]);1643#ifdef STRICT_DATA_DEPENDENCIES1644 ASSERT_ZERO_LABEL(rv);1645#else1646 ASSERT_LABEL(rv, n_label);1647 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, str2[0]);1648#endif1649 1650 dfsan_set_label(i_label, &str1[3], 1);1651 dfsan_set_label(j_label, &str1[5], 1);1652 1653 rv = strstr(str1, "1s");1654 assert(rv == &str1[3]);1655#ifdef STRICT_DATA_DEPENDENCIES1656 ASSERT_ZERO_LABEL(rv);1657#else1658 ASSERT_LABEL(rv, i_label);1659 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, str1[3]);1660#endif1661 1662 rv = strstr(str1, "2s");1663 assert(rv == NULL);1664#ifdef STRICT_DATA_DEPENDENCIES1665 ASSERT_ZERO_LABEL(rv);1666#else1667 ASSERT_LABEL(rv, i_j_label);1668 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, str1[3]);1669#endif1670}1671 1672void test_strpbrk() {1673 char s[] = "abcdefg";1674 char accept[] = "123fd";1675 1676 char *p_s = s;1677 char *p_accept = accept;1678 1679 dfsan_set_label(n_label, &p_accept, sizeof(p_accept));1680 1681 char *rv = strpbrk(p_s, p_accept);1682 assert(rv == &s[3]);1683#ifdef STRICT_DATA_DEPENDENCIES1684 ASSERT_ZERO_LABEL(rv);1685#else1686 ASSERT_LABEL(rv, n_label);1687 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, p_accept);1688#endif1689 1690 dfsan_set_label(m_label, &p_s, sizeof(p_s));1691 1692 rv = strpbrk(p_s, p_accept);1693 assert(rv == &s[3]);1694#ifdef STRICT_DATA_DEPENDENCIES1695 ASSERT_LABEL(rv, m_label);1696 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, p_s);1697#else1698 ASSERT_LABEL(rv, dfsan_union(m_label, n_label));1699 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, p_s);1700#endif1701 1702 dfsan_set_label(i_label, &s[5], 1);1703 dfsan_set_label(j_label, &accept[1], 1);1704 1705 rv = strpbrk(s, accept);1706 assert(rv == &s[3]);1707#ifdef STRICT_DATA_DEPENDENCIES1708 ASSERT_ZERO_LABEL(rv);1709#else1710 ASSERT_LABEL(rv, j_label);1711 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, accept[1]);1712#endif1713 1714 char *ps = s;1715 dfsan_set_label(j_label, &ps, sizeof(ps));1716 1717 rv = strpbrk(ps, "123gf");1718 assert(rv == &s[5]);1719#ifdef STRICT_DATA_DEPENDENCIES1720 ASSERT_LABEL(rv, j_label);1721#else1722 ASSERT_LABEL(rv, i_j_label);1723 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, s[5]);1724#endif1725 1726 rv = strpbrk(ps, "123");1727 assert(rv == NULL);1728#ifdef STRICT_DATA_DEPENDENCIES1729 ASSERT_ZERO_LABEL(rv);1730#else1731 ASSERT_LABEL(rv, i_j_label);1732 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, s[5]);1733#endif1734}1735 1736void test_strsep() {1737 char *s = strdup("Hello world/");1738 char *delim = strdup(" /");1739 1740 char *p_s = s;1741 char *base = s;1742 char *p_delim = delim;1743 1744 // taint delim bytes1745 dfsan_set_label(i_label, p_delim, strlen(p_delim));1746 // taint delim pointer1747 dfsan_set_label(j_label, &p_delim, sizeof(p_delim));1748 // taint the string data bytes1749 dfsan_set_label(k_label, s, 5);1750 // taint the string pointer1751 dfsan_set_label(m_label, &p_s, sizeof(p_s));1752 1753 char *rv = strsep(&p_s, p_delim);1754 assert(rv == &base[0]);1755#ifdef STRICT_DATA_DEPENDENCIES1756 ASSERT_LABEL(rv, m_label);1757 ASSERT_READ_LABEL(rv, strlen(rv), k_label);1758#else1759 ASSERT_LABEL(rv, dfsan_union(dfsan_union(i_label, j_label),1760 dfsan_union(k_label, m_label)));1761 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, p_s);1762#endif1763 1764 // taint the remaining string's pointer1765 char **pp_s = &p_s;1766 char **pp_s_base = pp_s;1767 dfsan_set_label(n_label, pp_s, sizeof(pp_s));1768 1769 rv = strsep(pp_s, p_delim);1770 1771 assert(rv == &base[6]);1772#ifdef STRICT_DATA_DEPENDENCIES1773 ASSERT_LABEL(rv, n_label);1774 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, *pp_s);1775#else1776 ASSERT_LABEL(rv, dfsan_union(dfsan_union(i_label, j_label), n_label));1777 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, *pp_s);1778#endif1779}1780 1781void test_memchr() {1782 char str1[] = "str1";1783 dfsan_set_label(i_label, &str1[3], 1);1784 dfsan_set_label(j_label, &str1[4], 1);1785 1786 char *crv = (char *) memchr(str1, 'r', sizeof(str1));1787 assert(crv == &str1[2]);1788 ASSERT_ZERO_LABEL(crv);1789 1790 char c = 'r';1791 dfsan_set_label(k_label, &c, sizeof(c));1792 crv = (char *)memchr(str1, c, sizeof(str1));1793 assert(crv == &str1[2]);1794#ifdef STRICT_DATA_DEPENDENCIES1795 ASSERT_ZERO_LABEL(crv);1796#else1797 ASSERT_LABEL(crv, k_label);1798 ASSERT_EQ_ORIGIN(crv, c);1799#endif1800 1801 char *ptr = str1;1802 dfsan_set_label(k_label, &ptr, sizeof(ptr));1803 crv = (char *)memchr(ptr, 'r', sizeof(str1));1804 assert(crv == &str1[2]);1805 ASSERT_LABEL(crv, k_label);1806 ASSERT_EQ_ORIGIN(crv, ptr);1807 1808 crv = (char *) memchr(str1, '1', sizeof(str1));1809 assert(crv == &str1[3]);1810#ifdef STRICT_DATA_DEPENDENCIES1811 ASSERT_ZERO_LABEL(crv);1812#else1813 ASSERT_LABEL(crv, i_label);1814 ASSERT_EQ_ORIGIN(crv, str1[3]);1815#endif1816 1817 crv = (char *) memchr(str1, 'x', sizeof(str1));1818 assert(!crv);1819#ifdef STRICT_DATA_DEPENDENCIES1820 ASSERT_ZERO_LABEL(crv);1821#else1822 ASSERT_LABEL(crv, i_j_label);1823 ASSERT_EQ_ORIGIN(crv, str1[3]);1824#endif1825}1826 1827void alarm_handler(int unused) {1828 ;1829}1830 1831void test_nanosleep() {1832 struct timespec req, rem;1833 req.tv_sec = 1;1834 req.tv_nsec = 0;1835 dfsan_set_label(i_label, &rem, sizeof(rem));1836 DEFINE_AND_SAVE_ORIGINS(rem)1837 1838 // non interrupted1839 int rv = nanosleep(&req, &rem);1840 assert(rv == 0);1841 ASSERT_ZERO_LABEL(rv);1842 ASSERT_READ_LABEL(&rem, 1, i_label);1843 ASSERT_SAVED_ORIGINS(rem)1844 1845 // interrupted by an alarm1846 signal(SIGALRM, alarm_handler);1847 req.tv_sec = 3;1848 alarm(1);1849 rv = nanosleep(&req, &rem);1850 assert(rv == -1);1851 ASSERT_ZERO_LABEL(rv);1852 ASSERT_READ_ZERO_LABEL(&rem, sizeof(rem));1853 ASSERT_SAVED_ORIGINS(rem)1854}1855 1856void test_socketpair() {1857 int fd[2];1858 dfsan_origin fd_o[2];1859 1860 dfsan_set_label(i_label, fd, sizeof(fd));1861 fd_o[0] = dfsan_get_origin((long)(fd[0]));1862 fd_o[1] = dfsan_get_origin((long)(fd[1]));1863 int rv = socketpair(PF_LOCAL, SOCK_STREAM, 0, fd);1864 assert(rv == 0);1865 ASSERT_ZERO_LABEL(rv);1866 ASSERT_READ_ZERO_LABEL(fd, sizeof(fd));1867 ASSERT_ORIGIN(fd[0], fd_o[0]);1868 ASSERT_ORIGIN(fd[1], fd_o[1]);1869}1870 1871void test_getpeername() {1872 int sockfds[2];1873 int ret = socketpair(AF_UNIX, SOCK_DGRAM, 0, sockfds);1874 assert(ret != -1);1875 1876 struct sockaddr addr = {};1877 socklen_t addrlen = sizeof(addr);1878 dfsan_set_label(i_label, &addr, addrlen);1879 dfsan_set_label(i_label, &addrlen, sizeof(addrlen));1880 DEFINE_AND_SAVE_ORIGINS(addr)1881 DEFINE_AND_SAVE_ORIGINS(addrlen)1882 1883 ret = getpeername(sockfds[0], &addr, &addrlen);1884 assert(ret != -1);1885 ASSERT_ZERO_LABEL(ret);1886 ASSERT_ZERO_LABEL(addrlen);1887 assert(addrlen < sizeof(addr));1888 ASSERT_READ_ZERO_LABEL(&addr, addrlen);1889 ASSERT_READ_LABEL(((char *)&addr) + addrlen, 1, i_label);1890 ASSERT_SAVED_ORIGINS(addr)1891 ASSERT_SAVED_ORIGINS(addrlen)1892 1893 close(sockfds[0]);1894 close(sockfds[1]);1895}1896 1897void test_getsockname() {1898 int sockfd = socket(AF_UNIX, SOCK_DGRAM, 0);1899 assert(sockfd != -1);1900 1901 struct sockaddr addr = {};1902 socklen_t addrlen = sizeof(addr);1903 dfsan_set_label(i_label, &addr, addrlen);1904 dfsan_set_label(i_label, &addrlen, sizeof(addrlen));1905 DEFINE_AND_SAVE_ORIGINS(addr)1906 DEFINE_AND_SAVE_ORIGINS(addrlen)1907 int ret = getsockname(sockfd, &addr, &addrlen);1908 assert(ret != -1);1909 ASSERT_ZERO_LABEL(ret);1910 ASSERT_ZERO_LABEL(addrlen);1911 assert(addrlen < sizeof(addr));1912 ASSERT_READ_ZERO_LABEL(&addr, addrlen);1913 ASSERT_READ_LABEL(((char *)&addr) + addrlen, 1, i_label);1914 ASSERT_SAVED_ORIGINS(addr)1915 ASSERT_SAVED_ORIGINS(addrlen)1916 1917 close(sockfd);1918}1919 1920void test_getsockopt() {1921 int sockfd = socket(AF_UNIX, SOCK_DGRAM, 0);1922 assert(sockfd != -1);1923 1924 int optval[2] = {-1, -1};1925 socklen_t optlen = sizeof(optval);1926 dfsan_set_label(i_label, &optval, sizeof(optval));1927 dfsan_set_label(i_label, &optlen, sizeof(optlen));1928 DEFINE_AND_SAVE_ORIGINS(optval)1929 DEFINE_AND_SAVE_ORIGINS(optlen)1930 int ret = getsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &optval, &optlen);1931 assert(ret != -1);1932 assert(optlen == sizeof(int));1933 assert(optval[0] == 0);1934 assert(optval[1] == -1);1935 ASSERT_ZERO_LABEL(ret);1936 ASSERT_ZERO_LABEL(optlen);1937 ASSERT_ZERO_LABEL(optval[0]);1938 ASSERT_LABEL(optval[1], i_label);1939 ASSERT_SAVED_ORIGINS(optval)1940 ASSERT_SAVED_ORIGINS(optlen)1941 1942 close(sockfd);1943}1944 1945void test_write() {1946 int fd = open("/dev/null", O_WRONLY);1947 1948 char buf[] = "a string";1949 int len = strlen(buf);1950 1951 // The result of a write always unlabeled.1952 int res = write(fd, buf, len);1953 assert(res > 0);1954 ASSERT_ZERO_LABEL(res);1955 1956 // Label all arguments to write().1957 dfsan_set_label(i_label, &(buf[3]), 1);1958 dfsan_set_label(j_label, &fd, sizeof(fd));1959 dfsan_set_label(k_label, &len, sizeof(len));1960 1961 // The value returned by write() should have no label.1962 res = write(fd, buf, len);1963 ASSERT_ZERO_LABEL(res);1964 1965 close(fd);1966}1967 1968template <class T>1969void test_sprintf_chunk(const char* expected, const char* format, T arg) {1970 char buf[512];1971 memset(buf, 'a', sizeof(buf));1972 1973 char padded_expected[512];1974 strcpy(padded_expected, "foo ");1975 strcat(padded_expected, expected);1976 strcat(padded_expected, " bar");1977 1978 char padded_format[512];1979 strcpy(padded_format, "foo ");1980 strcat(padded_format, format);1981 strcat(padded_format, " bar");1982 1983 // Non labelled arg.1984 assert(sprintf(buf, padded_format, arg) == strlen(padded_expected));1985 assert(strcmp(buf, padded_expected) == 0);1986 ASSERT_READ_LABEL(buf, strlen(padded_expected), 0);1987 memset(buf, 'a', sizeof(buf));1988 1989 // Labelled arg.1990 dfsan_set_label(i_label, &arg, sizeof(arg));1991 dfsan_origin a_o = dfsan_get_origin((long)(arg));1992#ifndef ORIGIN_TRACKING1993 (void)a_o;1994#endif1995 assert(sprintf(buf, padded_format, arg) == strlen(padded_expected));1996 assert(strcmp(buf, padded_expected) == 0);1997 ASSERT_READ_LABEL(buf, 4, 0);1998 ASSERT_READ_LABEL(buf + 4, strlen(padded_expected) - 8, i_label);1999 ASSERT_INIT_ORIGINS(buf + 4, strlen(padded_expected) - 8, a_o);2000 ASSERT_READ_LABEL(buf + (strlen(padded_expected) - 4), 4, 0);2001}2002 2003void test_sprintf() {2004 char buf[2048];2005 memset(buf, 'a', sizeof(buf));2006 2007 // Test formatting (no conversion specifier).2008 assert(sprintf(buf, "Hello world!") == 12);2009 assert(strcmp(buf, "Hello world!") == 0);2010 ASSERT_READ_LABEL(buf, sizeof(buf), 0);2011 2012 // Test for extra arguments.2013 assert(sprintf(buf, "Hello world!", 42, "hello") == 12);2014 assert(strcmp(buf, "Hello world!") == 0);2015 ASSERT_READ_LABEL(buf, sizeof(buf), 0);2016 2017 // Test formatting & label propagation (multiple conversion specifiers): %s,2018 // %d, %n, %f, and %%.2019 const char* s = "world";2020 int m = 8;2021 int d = 27;2022 dfsan_set_label(k_label, (void *) (s + 1), 2);2023 dfsan_origin s_o = dfsan_get_origin((long)(s[1]));2024 dfsan_set_label(i_label, &m, sizeof(m));2025 dfsan_origin m_o = dfsan_get_origin((long)m);2026 dfsan_set_label(j_label, &d, sizeof(d));2027 dfsan_origin d_o = dfsan_get_origin((long)d);2028#ifndef ORIGIN_TRACKING2029 (void)s_o;2030 (void)m_o;2031 (void)d_o;2032#endif2033 int n;2034 int r = sprintf(buf, "hello %s, %-d/%d/%d %f %% %n%d", s, 2014, m, d,2035 12345.6781234, &n, 1000);2036 assert(r == 42);2037 assert(strcmp(buf, "hello world, 2014/8/27 12345.678123 % 1000") == 0);2038 ASSERT_READ_LABEL(buf, 7, 0);2039 ASSERT_READ_LABEL(buf + 7, 2, k_label);2040 ASSERT_INIT_ORIGINS(buf + 7, 2, s_o);2041 ASSERT_READ_LABEL(buf + 9, 9, 0);2042 ASSERT_READ_LABEL(buf + 18, 1, i_label);2043 ASSERT_INIT_ORIGINS(buf + 18, 1, m_o);2044 ASSERT_READ_LABEL(buf + 19, 1, 0);2045 ASSERT_READ_LABEL(buf + 20, 2, j_label);2046 ASSERT_INIT_ORIGINS(buf + 20, 2, d_o);2047 ASSERT_READ_LABEL(buf + 22, 15, 0);2048 ASSERT_LABEL(r, 0);2049 assert(n == 38);2050 2051 // Test formatting & label propagation (single conversion specifier, with2052 // additional length and precision modifiers).2053 test_sprintf_chunk("-559038737", "%d", 0xdeadbeef);2054 test_sprintf_chunk("3735928559", "%u", 0xdeadbeef);2055 test_sprintf_chunk("12345", "%i", 12345);2056 test_sprintf_chunk("751", "%o", 0751);2057 test_sprintf_chunk("babe", "%x", 0xbabe);2058 test_sprintf_chunk("0000BABE", "%.8X", 0xbabe);2059 test_sprintf_chunk("-17", "%hhd", 0xdeadbeef);2060 test_sprintf_chunk("-16657", "%hd", 0xdeadbeef);2061 test_sprintf_chunk("deadbeefdeadbeef", "%lx", 0xdeadbeefdeadbeef);2062 test_sprintf_chunk("0xdeadbeefdeadbeef", "%p",2063 (void *) 0xdeadbeefdeadbeef);2064 test_sprintf_chunk("18446744073709551615", "%ju", (intmax_t) -1);2065 test_sprintf_chunk("18446744073709551615", "%zu", (size_t) -1);2066 test_sprintf_chunk("18446744073709551615", "%tu", (size_t) -1);2067 2068 test_sprintf_chunk("0x1.f9acffa7eb6bfp-4", "%a", 0.123456);2069 test_sprintf_chunk("0X1.F9ACFFA7EB6BFP-4", "%A", 0.123456);2070 test_sprintf_chunk("0.12346", "%.5f", 0.123456);2071 test_sprintf_chunk("0.123456", "%g", 0.123456);2072 test_sprintf_chunk("1.234560e-01", "%e", 0.123456);2073 test_sprintf_chunk("1.234560E-01", "%E", 0.123456);2074 test_sprintf_chunk("0.1234567891234560", "%.16Lf",2075 (long double) 0.123456789123456);2076 2077 test_sprintf_chunk("z", "%c", 'z');2078 2079 // %n, %s, %d, %f, and %% already tested2080 2081 // Test formatting with width passed as an argument.2082 r = sprintf(buf, "hi %*d my %*s friend %.*f", 3, 1, 6, "dear", 4, 3.14159265359);2083 assert(r == 30);2084 assert(strcmp(buf, "hi 1 my dear friend 3.1416") == 0);2085}2086 2087void test_snprintf() {2088 char buf[2048];2089 memset(buf, 'a', sizeof(buf));2090 dfsan_set_label(0, buf, sizeof(buf));2091 const char* s = "world";2092 int y = 2014;2093 int m = 8;2094 int d = 27;2095 dfsan_set_label(k_label, (void *) (s + 1), 2);2096 dfsan_origin s_o = dfsan_get_origin((long)(s[1]));2097 dfsan_set_label(i_label, &y, sizeof(y));2098 dfsan_origin y_o = dfsan_get_origin((long)y);2099 dfsan_set_label(j_label, &m, sizeof(m));2100 dfsan_origin m_o = dfsan_get_origin((long)m);2101#ifndef ORIGIN_TRACKING2102 (void)s_o;2103 (void)y_o;2104 (void)m_o;2105#endif2106 int r = snprintf(buf, 19, "hello %s, %-d/ %d/%d %f", s, y, m, d,2107 12345.6781234);2108 // The return value is the number of bytes that would have been written to2109 // the final string if enough space had been available.2110 assert(r == 38);2111 assert(memcmp(buf, "hello world, 2014/", 19) == 0);2112 ASSERT_READ_LABEL(buf, 7, 0);2113 ASSERT_READ_LABEL(buf + 7, 2, k_label);2114 ASSERT_INIT_ORIGINS(buf + 7, 2, s_o);2115 ASSERT_READ_LABEL(buf + 9, 4, 0);2116 ASSERT_READ_LABEL(buf + 13, 4, i_label);2117 ASSERT_INIT_ORIGINS(buf + 13, 4, y_o);2118 ASSERT_READ_LABEL(buf + 17, 2, 0);2119 ASSERT_LABEL(r, 0);2120}2121 2122template <class T>2123void test_sscanf_chunk(T expected, const char *format, char *input,2124 int items_num) {2125 char padded_input[512];2126 strcpy(padded_input, "foo ");2127 strcat(padded_input, input);2128 strcpy(padded_input, "@");2129 strcat(padded_input, input);2130 strcat(padded_input, " bar");2131 2132 char padded_format[512];2133 strcpy(padded_format, "foo ");2134 // Swap the first '%' for '%*' so this input is skipped.2135 strcpy(padded_format, "%*");2136 strcat(padded_format, format + 1);2137 strcpy(padded_format, "@");2138 strcat(padded_format, format);2139 strcat(padded_format, " bar");2140 2141 char *s = padded_input + 4;2142 T arg;2143 memset(&arg, 0, sizeof(arg));2144 dfsan_set_label(i_label, (void *)(padded_input), strlen(padded_input));2145 dfsan_set_label(j_label, (void *)(padded_format), strlen(padded_format));2146 dfsan_origin a_o = dfsan_get_origin((long)(*s));2147#ifndef ORIGIN_TRACKING2148 (void)a_o;2149#else2150 assert(a_o != 0);2151#endif2152 int rv = sscanf(padded_input, padded_format, &arg);2153 assert(rv == items_num);2154 assert(arg == expected);2155 ASSERT_READ_LABEL(&arg, sizeof(arg), i_label);2156 ASSERT_INIT_ORIGINS(&arg, 1, a_o);2157}2158 2159void test_sscanf() {2160 char buf[2048];2161 char buf_out[2048];2162 memset(buf, 'a', sizeof(buf));2163 memset(buf_out, 'a', sizeof(buf_out));2164 2165 // Test formatting2166 strcpy(buf, "Hello world!");2167 assert(sscanf(buf, "%s", buf_out) == 1);2168 assert(strcmp(buf, "Hello world!") == 0);2169 assert(strcmp(buf_out, "Hello") == 0);2170 ASSERT_READ_LABEL(buf, sizeof(buf), 0);2171 ASSERT_READ_LABEL(buf_out, sizeof(buf_out), 0);2172 2173 // Test for extra arguments.2174 assert(sscanf(buf, "%s", buf_out, 42, "hello") == 1);2175 assert(strcmp(buf, "Hello world!") == 0);2176 assert(strcmp(buf_out, "Hello") == 0);2177 ASSERT_READ_LABEL(buf, sizeof(buf), 0);2178 ASSERT_READ_LABEL(buf_out, sizeof(buf_out), 0);2179 2180 // Test formatting & label propagation (multiple conversion specifiers): %s,2181 // %d, %n, %f, and %%.2182 int n;2183 strcpy(buf, "hello world, 42 2014/8/31 12345.678123 % 1000");2184 char *s = buf + 6; //starts with world2185 int y = 0;2186 int m = 0;2187 int d = 0;2188 float fval;2189 int val = 0;2190 dfsan_set_label(k_label, (void *)(s + 1), 2); // buf[7]-b[9]2191 dfsan_origin s_o = dfsan_get_origin((long)(s[1]));2192 assert(s[10] == '2');2193 dfsan_set_label(i_label, (void *)(s + 10), 4); // 20142194 dfsan_origin y_o = dfsan_get_origin((long)s[10]); // buf[16]2195 assert(s[17] == '3');2196 dfsan_set_label(j_label, (void *)(s + 17), 2); // 312197 dfsan_origin d_o = dfsan_get_origin((long)s[17]); // buf[23]2198 assert(s[20] == '1');2199 dfsan_set_label(m_label, (void *)(s + 20), 5); // 123452200 dfsan_origin f_o = dfsan_get_origin((long)s[20]); //buf[26]2201 2202#ifndef ORIGIN_TRACKING2203 (void)s_o;2204 (void)y_o;2205 (void)d_o;2206 (void)f_o;2207#else2208 assert(s_o != 0);2209 assert(y_o != 0);2210 assert(d_o != 0);2211 assert(f_o != 0);2212#endif2213 int r = sscanf(buf, "hello %s %*d %d/%d/%d %f %% %n%d", buf_out, &y, &m, &d,2214 &fval, &n, &val);2215 assert(r == 6);2216 assert(strcmp(buf_out, "world,") == 0);2217 assert(y == 2014);2218 assert(m == 8);2219 assert(d == 31);2220 assert(fval > 12300.0f);2221 assert(fval < 12400.0f);2222 ASSERT_READ_LABEL(buf_out, 1, 0);2223 ASSERT_READ_LABEL(buf_out + 1, 2, k_label);2224 ASSERT_INIT_ORIGINS(buf_out + 1, 2, s_o);2225 ASSERT_READ_LABEL(&y, sizeof(y), i_label);2226 ASSERT_INIT_ORIGINS(&y, sizeof(y), y_o);2227 ASSERT_READ_LABEL(&d, sizeof(d), j_label);2228 ASSERT_INIT_ORIGINS(&d, sizeof(d), d_o);2229 ASSERT_READ_LABEL(&fval, sizeof(fval), m_label);2230 ASSERT_INIT_ORIGINS(&fval, sizeof(fval), f_o);2231 ASSERT_READ_LABEL(&val, 4, 0);2232 ASSERT_LABEL(r, 0);2233 assert(n == 41);2234 assert(val == 1000);2235 2236 // Test formatting & label propagation (single conversion specifier, with2237 // additional length and precision modifiers).2238 char input_buf[512];2239 char *input_ptr = input_buf;2240 strcpy(input_buf, "-559038737");2241 test_sscanf_chunk(-559038737, "%d", input_ptr, 1);2242 strcpy(input_buf, "3735928559");2243 test_sscanf_chunk(3735928559, "%u", input_ptr, 1);2244 strcpy(input_buf, "12345");2245 test_sscanf_chunk(12345, "%i", input_ptr, 1);2246 strcpy(input_buf, "0751");2247 test_sscanf_chunk(489, "%o", input_ptr, 1);2248 strcpy(input_buf, "0xbabe");2249 test_sscanf_chunk(47806, "%x", input_ptr, 1);2250 strcpy(input_buf, "0x0000BABE");2251 test_sscanf_chunk(47806, "%10X", input_ptr, 1);2252 strcpy(input_buf, "3735928559");2253 test_sscanf_chunk((char)-17, "%hhd", input_ptr, 1);2254 strcpy(input_buf, "3735928559");2255 test_sscanf_chunk((short)-16657, "%hd", input_ptr, 1);2256 strcpy(input_buf, "0xdeadbeefdeadbeef");2257 test_sscanf_chunk(0xdeadbeefdeadbeefL, "%lx", input_buf, 1);2258 test_sscanf_chunk((void *)0xdeadbeefdeadbeefL, "%p", input_buf, 1);2259 2260 intmax_t _x = (intmax_t)-1;2261 char _buf[256];2262 memset(_buf, 0, sizeof(_buf));2263 sprintf(_buf, "%ju", _x);2264 test_sscanf_chunk((intmax_t)18446744073709551615, "%ju", _buf, 1);2265 memset(_buf, 0, sizeof(_buf));2266 size_t _y = (size_t)-1;2267 sprintf(_buf, "%zu", _y);2268 test_sscanf_chunk((size_t)18446744073709551615, "%zu", _buf, 1);2269 memset(_buf, 0, sizeof(_buf));2270 ptrdiff_t _z = (size_t)-1;2271 sprintf(_buf, "%tu", _z);2272 test_sscanf_chunk((ptrdiff_t)18446744073709551615, "%tu", _buf, 1);2273 2274 strcpy(input_buf, "0.123456");2275 test_sscanf_chunk((float)0.123456, "%8f", input_ptr, 1);2276 test_sscanf_chunk((float)0.123456, "%g", input_ptr, 1);2277 test_sscanf_chunk((float)1.234560e-01, "%e", input_ptr, 1);2278 test_sscanf_chunk((char)'z', "%c", "z", 1);2279 2280 // %n, %s, %d, %f, and %% already tested2281}2282 2283// Tested by a separate source file. This empty function is here to appease the2284// check-wrappers script.2285void test_fork() {}2286 2287int main(void) {2288 i_label = 1;2289 j_label = 2;2290 k_label = 4;2291 m_label = 8;2292 n_label = 16;2293 i_j_label = dfsan_union(i_label, j_label);2294 assert(i_j_label != i_label);2295 assert(i_j_label != j_label);2296 assert(i_j_label != k_label);2297 2298 test__dl_get_tls_static_info();2299 test_bcmp();2300 test_clock_gettime();2301 test_ctime_r();2302 test_dfsan_set_write_callback();2303 test_dl_iterate_phdr();2304 test_dlopen();2305 test_epoll_wait();2306 test_fgets();2307 test_fork();2308 test_fstat();2309 test_get_current_dir_name();2310 test_getcwd();2311 test_getentropy();2312 test_gethostname();2313 test_getpeername();2314 test_getpwuid_r();2315 test_getrlimit();2316 test_getrusage();2317 test_getsockname();2318 test_getsockopt();2319 test_gettimeofday();2320 test_inet_pton();2321 test_localtime_r();2322 test_memchr();2323 test_memcmp();2324 test_memcpy();2325 test_memmove();2326 test_memset();2327 test_nanosleep();2328 test_poll();2329 test_pread();2330 test_pthread_create();2331 test_pthread_join();2332 test_read();2333 test_recvmmsg();2334 test_recvmsg();2335 test_sched_getaffinity();2336 test_select();2337 test_sigaction();2338 test_signal();2339 test_sigaltstack();2340 test_sigemptyset();2341 test_snprintf();2342 test_sscanf();2343 test_socketpair();2344 test_sprintf();2345 test_stat();2346 test_strcasecmp();2347 test_strchr();2348 test_strcmp();2349 test_strcat();2350 test_strncat(5);2351 test_strncat(2);2352 test_strcpy();2353 test_strdup();2354 test_strlen();2355 test_strnlen();2356 test_strncasecmp();2357 test_strncmp();2358 test_strncpy();2359 test_strpbrk();2360 test_strsep();2361 test_strrchr();2362 test_strstr();2363 test_strtod();2364 test_strtol();2365 test_strtoll();2366 test_strtoul();2367 test_strtoull();2368 test_time();2369 test_write();2370}2371