1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * User Events FTrace Test Program 4 * 5 * Copyright (c) 2021 Beau Belgrave <beaub@linux.microsoft.com> 6 */ 7 8 #include <errno.h> 9 #include <linux/user_events.h> 10 #include <stdio.h> 11 #include <stdlib.h> 12 #include <fcntl.h> 13 #include <sys/ioctl.h> 14 #include <sys/stat.h> 15 #include <sys/uio.h> 16 #include <unistd.h> 17 18 #include "../kselftest_harness.h" 19 20 const char *data_file = "/sys/kernel/tracing/user_events_data"; 21 const char *status_file = "/sys/kernel/tracing/user_events_status"; 22 const char *enable_file = "/sys/kernel/tracing/events/user_events/__test_event/enable"; 23 const char *trace_file = "/sys/kernel/tracing/trace"; 24 const char *fmt_file = "/sys/kernel/tracing/events/user_events/__test_event/format"; 25 26 static int trace_bytes(void) 27 { 28 int fd = open(trace_file, O_RDONLY); 29 char buf[256]; 30 int bytes = 0, got; 31 32 if (fd == -1) 33 return -1; 34 35 while (true) { 36 got = read(fd, buf, sizeof(buf)); 37 38 if (got == -1) 39 return -1; 40 41 if (got == 0) 42 break; 43 44 bytes += got; 45 } 46 47 close(fd); 48 49 return bytes; 50 } 51 52 static int skip_until_empty_line(FILE *fp) 53 { 54 int c, last = 0; 55 56 while (true) { 57 c = getc(fp); 58 59 if (c == EOF) 60 break; 61 62 if (last == '\n' && c == '\n') 63 return 0; 64 65 last = c; 66 } 67 68 return -1; 69 } 70 71 static int get_print_fmt(char *buffer, int len) 72 { 73 FILE *fp = fopen(fmt_file, "r"); 74 char *newline; 75 76 if (!fp) 77 return -1; 78 79 /* Read until empty line (Skip Common) */ 80 if (skip_until_empty_line(fp) < 0) 81 goto err; 82 83 /* Read until empty line (Skip Properties) */ 84 if (skip_until_empty_line(fp) < 0) 85 goto err; 86 87 /* Read in print_fmt: */ 88 if (fgets(buffer, len, fp) == NULL) 89 goto err; 90 91 newline = strchr(buffer, '\n'); 92 93 if (newline) 94 *newline = '\0'; 95 96 fclose(fp); 97 98 return 0; 99 err: 100 fclose(fp); 101 102 return -1; 103 } 104 105 static bool wait_for_delete(void) 106 { 107 int i; 108 109 for (i = 0; i < 1000; ++i) { 110 int fd = open(enable_file, O_RDONLY); 111 112 if (fd == -1) 113 return true; 114 115 close(fd); 116 usleep(1000); 117 } 118 119 return false; 120 } 121 122 static int clear(int *check) 123 { 124 struct user_unreg unreg = {0}; 125 int fd; 126 127 unreg.size = sizeof(unreg); 128 unreg.disable_bit = 31; 129 unreg.disable_addr = (__u64)check; 130 131 fd = open(data_file, O_RDWR); 132 133 if (fd == -1) 134 return -1; 135 136 if (ioctl(fd, DIAG_IOCSUNREG, &unreg) == -1) 137 if (errno != ENOENT) 138 goto fail; 139 140 if (ioctl(fd, DIAG_IOCSDEL, "__test_event") == -1) { 141 if (errno == EBUSY) { 142 if (!wait_for_delete()) 143 goto fail; 144 } else if (errno != ENOENT) 145 goto fail; 146 } 147 148 close(fd); 149 150 return 0; 151 fail: 152 close(fd); 153 154 return -1; 155 } 156 157 static int check_print_fmt(const char *event, const char *expected, int *check) 158 { 159 struct user_reg reg = {0}; 160 char print_fmt[256]; 161 int ret; 162 int fd; 163 164 /* Ensure cleared */ 165 ret = clear(check); 166 167 if (ret != 0) 168 return ret; 169 170 fd = open(data_file, O_RDWR); 171 172 if (fd == -1) 173 return fd; 174 175 reg.size = sizeof(reg); 176 reg.name_args = (__u64)event; 177 reg.enable_bit = 31; 178 reg.enable_addr = (__u64)check; 179 reg.enable_size = sizeof(*check); 180 181 /* Register should work */ 182 ret = ioctl(fd, DIAG_IOCSREG, ®); 183 184 if (ret != 0) { 185 close(fd); 186 printf("Reg failed in fmt\n"); 187 return ret; 188 } 189 190 /* Ensure correct print_fmt */ 191 ret = get_print_fmt(print_fmt, sizeof(print_fmt)); 192 193 close(fd); 194 195 if (ret != 0) 196 return ret; 197 198 return strcmp(print_fmt, expected); 199 } 200 201 FIXTURE(user) { 202 int status_fd; 203 int data_fd; 204 int enable_fd; 205 int check; 206 }; 207 208 FIXTURE_SETUP(user) { 209 self->status_fd = open(status_file, O_RDONLY); 210 ASSERT_NE(-1, self->status_fd); 211 212 self->data_fd = open(data_file, O_RDWR); 213 ASSERT_NE(-1, self->data_fd); 214 215 self->enable_fd = -1; 216 } 217 218 FIXTURE_TEARDOWN(user) { 219 close(self->status_fd); 220 close(self->data_fd); 221 222 if (self->enable_fd != -1) { 223 write(self->enable_fd, "0", sizeof("0")); 224 close(self->enable_fd); 225 } 226 227 if (clear(&self->check) != 0) 228 printf("WARNING: Clear didn't work!\n"); 229 } 230 231 TEST_F(user, register_events) { 232 struct user_reg reg = {0}; 233 struct user_unreg unreg = {0}; 234 235 reg.size = sizeof(reg); 236 reg.name_args = (__u64)"__test_event u32 field1; u32 field2"; 237 reg.enable_bit = 31; 238 reg.enable_addr = (__u64)&self->check; 239 reg.enable_size = sizeof(self->check); 240 241 unreg.size = sizeof(unreg); 242 unreg.disable_bit = 31; 243 unreg.disable_addr = (__u64)&self->check; 244 245 /* Register should work */ 246 ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSREG, ®)); 247 ASSERT_EQ(0, reg.write_index); 248 249 /* Multiple registers to the same addr + bit should fail */ 250 ASSERT_EQ(-1, ioctl(self->data_fd, DIAG_IOCSREG, ®)); 251 ASSERT_EQ(EADDRINUSE, errno); 252 253 /* Multiple registers to same name should result in same index */ 254 reg.enable_bit = 30; 255 ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSREG, ®)); 256 ASSERT_EQ(0, reg.write_index); 257 258 /* Multiple registers to same name but different args should fail */ 259 reg.enable_bit = 29; 260 reg.name_args = (__u64)"__test_event u32 field1;"; 261 ASSERT_EQ(-1, ioctl(self->data_fd, DIAG_IOCSREG, ®)); 262 ASSERT_EQ(EADDRINUSE, errno); 263 264 /* Ensure disabled */ 265 self->enable_fd = open(enable_file, O_RDWR); 266 ASSERT_NE(-1, self->enable_fd); 267 ASSERT_NE(-1, write(self->enable_fd, "0", sizeof("0"))) 268 269 /* Enable event and ensure bits updated in status */ 270 ASSERT_NE(-1, write(self->enable_fd, "1", sizeof("1"))) 271 ASSERT_EQ(1 << reg.enable_bit, self->check); 272 273 /* Disable event and ensure bits updated in status */ 274 ASSERT_NE(-1, write(self->enable_fd, "0", sizeof("0"))) 275 ASSERT_EQ(0, self->check); 276 277 /* File still open should return -EBUSY for delete */ 278 ASSERT_EQ(-1, ioctl(self->data_fd, DIAG_IOCSDEL, "__test_event")); 279 ASSERT_EQ(EBUSY, errno); 280 281 /* Unregister */ 282 ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSUNREG, &unreg)); 283 unreg.disable_bit = 30; 284 ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSUNREG, &unreg)); 285 286 /* Delete should have been auto-done after close and unregister */ 287 close(self->data_fd); 288 289 ASSERT_EQ(true, wait_for_delete()); 290 } 291 292 TEST_F(user, write_events) { 293 struct user_reg reg = {0}; 294 struct iovec io[3]; 295 __u32 field1, field2; 296 int before = 0, after = 0; 297 298 reg.size = sizeof(reg); 299 reg.name_args = (__u64)"__test_event u32 field1; u32 field2"; 300 reg.enable_bit = 31; 301 reg.enable_addr = (__u64)&self->check; 302 reg.enable_size = sizeof(self->check); 303 304 field1 = 1; 305 field2 = 2; 306 307 io[0].iov_base = ®.write_index; 308 io[0].iov_len = sizeof(reg.write_index); 309 io[1].iov_base = &field1; 310 io[1].iov_len = sizeof(field1); 311 io[2].iov_base = &field2; 312 io[2].iov_len = sizeof(field2); 313 314 /* Register should work */ 315 ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSREG, ®)); 316 ASSERT_EQ(0, reg.write_index); 317 ASSERT_EQ(0, self->check); 318 319 /* Write should fail on invalid slot with ENOENT */ 320 io[0].iov_base = &field2; 321 io[0].iov_len = sizeof(field2); 322 ASSERT_EQ(-1, writev(self->data_fd, (const struct iovec *)io, 3)); 323 ASSERT_EQ(ENOENT, errno); 324 io[0].iov_base = ®.write_index; 325 io[0].iov_len = sizeof(reg.write_index); 326 327 /* Write should return -EBADF when event is not enabled */ 328 ASSERT_EQ(-1, writev(self->data_fd, (const struct iovec *)io, 3)); 329 ASSERT_EQ(EBADF, errno); 330 331 /* Enable event */ 332 self->enable_fd = open(enable_file, O_RDWR); 333 ASSERT_NE(-1, write(self->enable_fd, "1", sizeof("1"))) 334 335 /* Event should now be enabled */ 336 ASSERT_NE(1 << reg.enable_bit, self->check); 337 338 /* Write should make it out to ftrace buffers */ 339 before = trace_bytes(); 340 ASSERT_NE(-1, writev(self->data_fd, (const struct iovec *)io, 3)); 341 after = trace_bytes(); 342 ASSERT_GT(after, before); 343 344 /* Negative index should fail with EINVAL */ 345 reg.write_index = -1; 346 ASSERT_EQ(-1, writev(self->data_fd, (const struct iovec *)io, 3)); 347 ASSERT_EQ(EINVAL, errno); 348 } 349 350 TEST_F(user, write_empty_events) { 351 struct user_reg reg = {0}; 352 struct iovec io[1]; 353 int before = 0, after = 0; 354 355 reg.size = sizeof(reg); 356 reg.name_args = (__u64)"__test_event"; 357 reg.enable_bit = 31; 358 reg.enable_addr = (__u64)&self->check; 359 reg.enable_size = sizeof(self->check); 360 361 io[0].iov_base = ®.write_index; 362 io[0].iov_len = sizeof(reg.write_index); 363 364 /* Register should work */ 365 ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSREG, ®)); 366 ASSERT_EQ(0, reg.write_index); 367 ASSERT_EQ(0, self->check); 368 369 /* Enable event */ 370 self->enable_fd = open(enable_file, O_RDWR); 371 ASSERT_NE(-1, write(self->enable_fd, "1", sizeof("1"))) 372 373 /* Event should now be enabled */ 374 ASSERT_EQ(1 << reg.enable_bit, self->check); 375 376 /* Write should make it out to ftrace buffers */ 377 before = trace_bytes(); 378 ASSERT_NE(-1, writev(self->data_fd, (const struct iovec *)io, 1)); 379 after = trace_bytes(); 380 ASSERT_GT(after, before); 381 } 382 383 TEST_F(user, write_fault) { 384 struct user_reg reg = {0}; 385 struct iovec io[2]; 386 int l = sizeof(__u64); 387 void *anon; 388 389 reg.size = sizeof(reg); 390 reg.name_args = (__u64)"__test_event u64 anon"; 391 reg.enable_bit = 31; 392 reg.enable_addr = (__u64)&self->check; 393 reg.enable_size = sizeof(self->check); 394 395 anon = mmap(NULL, l, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 396 ASSERT_NE(MAP_FAILED, anon); 397 398 io[0].iov_base = ®.write_index; 399 io[0].iov_len = sizeof(reg.write_index); 400 io[1].iov_base = anon; 401 io[1].iov_len = l; 402 403 /* Register should work */ 404 ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSREG, ®)); 405 ASSERT_EQ(0, reg.write_index); 406 407 /* Enable event */ 408 self->enable_fd = open(enable_file, O_RDWR); 409 ASSERT_NE(-1, write(self->enable_fd, "1", sizeof("1"))) 410 411 /* Write should work normally */ 412 ASSERT_NE(-1, writev(self->data_fd, (const struct iovec *)io, 2)); 413 414 /* Faulted data should zero fill and work */ 415 ASSERT_EQ(0, madvise(anon, l, MADV_DONTNEED)); 416 ASSERT_NE(-1, writev(self->data_fd, (const struct iovec *)io, 2)); 417 ASSERT_EQ(0, munmap(anon, l)); 418 } 419 420 TEST_F(user, write_validator) { 421 struct user_reg reg = {0}; 422 struct iovec io[3]; 423 int loc, bytes; 424 char data[8]; 425 int before = 0, after = 0; 426 427 reg.size = sizeof(reg); 428 reg.name_args = (__u64)"__test_event __rel_loc char[] data"; 429 reg.enable_bit = 31; 430 reg.enable_addr = (__u64)&self->check; 431 reg.enable_size = sizeof(self->check); 432 433 /* Register should work */ 434 ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSREG, ®)); 435 ASSERT_EQ(0, reg.write_index); 436 ASSERT_EQ(0, self->check); 437 438 io[0].iov_base = ®.write_index; 439 io[0].iov_len = sizeof(reg.write_index); 440 io[1].iov_base = &loc; 441 io[1].iov_len = sizeof(loc); 442 io[2].iov_base = data; 443 bytes = snprintf(data, sizeof(data), "Test") + 1; 444 io[2].iov_len = bytes; 445 446 /* Undersized write should fail */ 447 ASSERT_EQ(-1, writev(self->data_fd, (const struct iovec *)io, 1)); 448 ASSERT_EQ(EINVAL, errno); 449 450 /* Enable event */ 451 self->enable_fd = open(enable_file, O_RDWR); 452 ASSERT_NE(-1, write(self->enable_fd, "1", sizeof("1"))) 453 454 /* Event should now be enabled */ 455 ASSERT_EQ(1 << reg.enable_bit, self->check); 456 457 /* Full in-bounds write should work */ 458 before = trace_bytes(); 459 loc = DYN_LOC(0, bytes); 460 ASSERT_NE(-1, writev(self->data_fd, (const struct iovec *)io, 3)); 461 after = trace_bytes(); 462 ASSERT_GT(after, before); 463 464 /* Out of bounds write should fault (offset way out) */ 465 loc = DYN_LOC(1024, bytes); 466 ASSERT_EQ(-1, writev(self->data_fd, (const struct iovec *)io, 3)); 467 ASSERT_EQ(EFAULT, errno); 468 469 /* Out of bounds write should fault (offset 1 byte out) */ 470 loc = DYN_LOC(1, bytes); 471 ASSERT_EQ(-1, writev(self->data_fd, (const struct iovec *)io, 3)); 472 ASSERT_EQ(EFAULT, errno); 473 474 /* Out of bounds write should fault (size way out) */ 475 loc = DYN_LOC(0, bytes + 1024); 476 ASSERT_EQ(-1, writev(self->data_fd, (const struct iovec *)io, 3)); 477 ASSERT_EQ(EFAULT, errno); 478 479 /* Out of bounds write should fault (size 1 byte out) */ 480 loc = DYN_LOC(0, bytes + 1); 481 ASSERT_EQ(-1, writev(self->data_fd, (const struct iovec *)io, 3)); 482 ASSERT_EQ(EFAULT, errno); 483 484 /* Non-Null should fault */ 485 memset(data, 'A', sizeof(data)); 486 loc = DYN_LOC(0, bytes); 487 ASSERT_EQ(-1, writev(self->data_fd, (const struct iovec *)io, 3)); 488 ASSERT_EQ(EFAULT, errno); 489 } 490 491 TEST_F(user, print_fmt) { 492 int ret; 493 494 ret = check_print_fmt("__test_event __rel_loc char[] data", 495 "print fmt: \"data=%s\", __get_rel_str(data)", 496 &self->check); 497 ASSERT_EQ(0, ret); 498 499 ret = check_print_fmt("__test_event __data_loc char[] data", 500 "print fmt: \"data=%s\", __get_str(data)", 501 &self->check); 502 ASSERT_EQ(0, ret); 503 504 ret = check_print_fmt("__test_event s64 data", 505 "print fmt: \"data=%lld\", REC->data", 506 &self->check); 507 ASSERT_EQ(0, ret); 508 509 ret = check_print_fmt("__test_event u64 data", 510 "print fmt: \"data=%llu\", REC->data", 511 &self->check); 512 ASSERT_EQ(0, ret); 513 514 ret = check_print_fmt("__test_event s32 data", 515 "print fmt: \"data=%d\", REC->data", 516 &self->check); 517 ASSERT_EQ(0, ret); 518 519 ret = check_print_fmt("__test_event u32 data", 520 "print fmt: \"data=%u\", REC->data", 521 &self->check); 522 ASSERT_EQ(0, ret); 523 524 ret = check_print_fmt("__test_event int data", 525 "print fmt: \"data=%d\", REC->data", 526 &self->check); 527 ASSERT_EQ(0, ret); 528 529 ret = check_print_fmt("__test_event unsigned int data", 530 "print fmt: \"data=%u\", REC->data", 531 &self->check); 532 ASSERT_EQ(0, ret); 533 534 ret = check_print_fmt("__test_event s16 data", 535 "print fmt: \"data=%d\", REC->data", 536 &self->check); 537 ASSERT_EQ(0, ret); 538 539 ret = check_print_fmt("__test_event u16 data", 540 "print fmt: \"data=%u\", REC->data", 541 &self->check); 542 ASSERT_EQ(0, ret); 543 544 ret = check_print_fmt("__test_event short data", 545 "print fmt: \"data=%d\", REC->data", 546 &self->check); 547 ASSERT_EQ(0, ret); 548 549 ret = check_print_fmt("__test_event unsigned short data", 550 "print fmt: \"data=%u\", REC->data", 551 &self->check); 552 ASSERT_EQ(0, ret); 553 554 ret = check_print_fmt("__test_event s8 data", 555 "print fmt: \"data=%d\", REC->data", 556 &self->check); 557 ASSERT_EQ(0, ret); 558 559 ret = check_print_fmt("__test_event u8 data", 560 "print fmt: \"data=%u\", REC->data", 561 &self->check); 562 ASSERT_EQ(0, ret); 563 564 ret = check_print_fmt("__test_event char data", 565 "print fmt: \"data=%d\", REC->data", 566 &self->check); 567 ASSERT_EQ(0, ret); 568 569 ret = check_print_fmt("__test_event unsigned char data", 570 "print fmt: \"data=%u\", REC->data", 571 &self->check); 572 ASSERT_EQ(0, ret); 573 574 ret = check_print_fmt("__test_event char[4] data", 575 "print fmt: \"data=%s\", REC->data", 576 &self->check); 577 ASSERT_EQ(0, ret); 578 } 579 580 int main(int argc, char **argv) 581 { 582 return test_harness_run(argc, argv); 583 } 584