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 /* Enable event */ 328 self->enable_fd = open(enable_file, O_RDWR); 329 ASSERT_NE(-1, write(self->enable_fd, "1", sizeof("1"))) 330 331 /* Event should now be enabled */ 332 ASSERT_NE(1 << reg.enable_bit, self->check); 333 334 /* Write should make it out to ftrace buffers */ 335 before = trace_bytes(); 336 ASSERT_NE(-1, writev(self->data_fd, (const struct iovec *)io, 3)); 337 after = trace_bytes(); 338 ASSERT_GT(after, before); 339 340 /* Negative index should fail with EINVAL */ 341 reg.write_index = -1; 342 ASSERT_EQ(-1, writev(self->data_fd, (const struct iovec *)io, 3)); 343 ASSERT_EQ(EINVAL, errno); 344 } 345 346 TEST_F(user, write_empty_events) { 347 struct user_reg reg = {0}; 348 struct iovec io[1]; 349 int before = 0, after = 0; 350 351 reg.size = sizeof(reg); 352 reg.name_args = (__u64)"__test_event"; 353 reg.enable_bit = 31; 354 reg.enable_addr = (__u64)&self->check; 355 reg.enable_size = sizeof(self->check); 356 357 io[0].iov_base = ®.write_index; 358 io[0].iov_len = sizeof(reg.write_index); 359 360 /* Register should work */ 361 ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSREG, ®)); 362 ASSERT_EQ(0, reg.write_index); 363 ASSERT_EQ(0, self->check); 364 365 /* Enable event */ 366 self->enable_fd = open(enable_file, O_RDWR); 367 ASSERT_NE(-1, write(self->enable_fd, "1", sizeof("1"))) 368 369 /* Event should now be enabled */ 370 ASSERT_EQ(1 << reg.enable_bit, self->check); 371 372 /* Write should make it out to ftrace buffers */ 373 before = trace_bytes(); 374 ASSERT_NE(-1, writev(self->data_fd, (const struct iovec *)io, 1)); 375 after = trace_bytes(); 376 ASSERT_GT(after, before); 377 } 378 379 TEST_F(user, write_fault) { 380 struct user_reg reg = {0}; 381 struct iovec io[2]; 382 int l = sizeof(__u64); 383 void *anon; 384 385 reg.size = sizeof(reg); 386 reg.name_args = (__u64)"__test_event u64 anon"; 387 reg.enable_bit = 31; 388 reg.enable_addr = (__u64)&self->check; 389 reg.enable_size = sizeof(self->check); 390 391 anon = mmap(NULL, l, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 392 ASSERT_NE(MAP_FAILED, anon); 393 394 io[0].iov_base = ®.write_index; 395 io[0].iov_len = sizeof(reg.write_index); 396 io[1].iov_base = anon; 397 io[1].iov_len = l; 398 399 /* Register should work */ 400 ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSREG, ®)); 401 ASSERT_EQ(0, reg.write_index); 402 403 /* Write should work normally */ 404 ASSERT_NE(-1, writev(self->data_fd, (const struct iovec *)io, 2)); 405 406 /* Faulted data should zero fill and work */ 407 ASSERT_EQ(0, madvise(anon, l, MADV_DONTNEED)); 408 ASSERT_NE(-1, writev(self->data_fd, (const struct iovec *)io, 2)); 409 ASSERT_EQ(0, munmap(anon, l)); 410 } 411 412 TEST_F(user, write_validator) { 413 struct user_reg reg = {0}; 414 struct iovec io[3]; 415 int loc, bytes; 416 char data[8]; 417 int before = 0, after = 0; 418 419 reg.size = sizeof(reg); 420 reg.name_args = (__u64)"__test_event __rel_loc char[] data"; 421 reg.enable_bit = 31; 422 reg.enable_addr = (__u64)&self->check; 423 reg.enable_size = sizeof(self->check); 424 425 /* Register should work */ 426 ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSREG, ®)); 427 ASSERT_EQ(0, reg.write_index); 428 ASSERT_EQ(0, self->check); 429 430 io[0].iov_base = ®.write_index; 431 io[0].iov_len = sizeof(reg.write_index); 432 io[1].iov_base = &loc; 433 io[1].iov_len = sizeof(loc); 434 io[2].iov_base = data; 435 bytes = snprintf(data, sizeof(data), "Test") + 1; 436 io[2].iov_len = bytes; 437 438 /* Undersized write should fail */ 439 ASSERT_EQ(-1, writev(self->data_fd, (const struct iovec *)io, 1)); 440 ASSERT_EQ(EINVAL, errno); 441 442 /* Enable event */ 443 self->enable_fd = open(enable_file, O_RDWR); 444 ASSERT_NE(-1, write(self->enable_fd, "1", sizeof("1"))) 445 446 /* Event should now be enabled */ 447 ASSERT_EQ(1 << reg.enable_bit, self->check); 448 449 /* Full in-bounds write should work */ 450 before = trace_bytes(); 451 loc = DYN_LOC(0, bytes); 452 ASSERT_NE(-1, writev(self->data_fd, (const struct iovec *)io, 3)); 453 after = trace_bytes(); 454 ASSERT_GT(after, before); 455 456 /* Out of bounds write should fault (offset way out) */ 457 loc = DYN_LOC(1024, bytes); 458 ASSERT_EQ(-1, writev(self->data_fd, (const struct iovec *)io, 3)); 459 ASSERT_EQ(EFAULT, errno); 460 461 /* Out of bounds write should fault (offset 1 byte out) */ 462 loc = DYN_LOC(1, bytes); 463 ASSERT_EQ(-1, writev(self->data_fd, (const struct iovec *)io, 3)); 464 ASSERT_EQ(EFAULT, errno); 465 466 /* Out of bounds write should fault (size way out) */ 467 loc = DYN_LOC(0, bytes + 1024); 468 ASSERT_EQ(-1, writev(self->data_fd, (const struct iovec *)io, 3)); 469 ASSERT_EQ(EFAULT, errno); 470 471 /* Out of bounds write should fault (size 1 byte out) */ 472 loc = DYN_LOC(0, bytes + 1); 473 ASSERT_EQ(-1, writev(self->data_fd, (const struct iovec *)io, 3)); 474 ASSERT_EQ(EFAULT, errno); 475 476 /* Non-Null should fault */ 477 memset(data, 'A', sizeof(data)); 478 loc = DYN_LOC(0, bytes); 479 ASSERT_EQ(-1, writev(self->data_fd, (const struct iovec *)io, 3)); 480 ASSERT_EQ(EFAULT, errno); 481 } 482 483 TEST_F(user, print_fmt) { 484 int ret; 485 486 ret = check_print_fmt("__test_event __rel_loc char[] data", 487 "print fmt: \"data=%s\", __get_rel_str(data)", 488 &self->check); 489 ASSERT_EQ(0, ret); 490 491 ret = check_print_fmt("__test_event __data_loc char[] data", 492 "print fmt: \"data=%s\", __get_str(data)", 493 &self->check); 494 ASSERT_EQ(0, ret); 495 496 ret = check_print_fmt("__test_event s64 data", 497 "print fmt: \"data=%lld\", REC->data", 498 &self->check); 499 ASSERT_EQ(0, ret); 500 501 ret = check_print_fmt("__test_event u64 data", 502 "print fmt: \"data=%llu\", REC->data", 503 &self->check); 504 ASSERT_EQ(0, ret); 505 506 ret = check_print_fmt("__test_event s32 data", 507 "print fmt: \"data=%d\", REC->data", 508 &self->check); 509 ASSERT_EQ(0, ret); 510 511 ret = check_print_fmt("__test_event u32 data", 512 "print fmt: \"data=%u\", REC->data", 513 &self->check); 514 ASSERT_EQ(0, ret); 515 516 ret = check_print_fmt("__test_event int data", 517 "print fmt: \"data=%d\", REC->data", 518 &self->check); 519 ASSERT_EQ(0, ret); 520 521 ret = check_print_fmt("__test_event unsigned int data", 522 "print fmt: \"data=%u\", REC->data", 523 &self->check); 524 ASSERT_EQ(0, ret); 525 526 ret = check_print_fmt("__test_event s16 data", 527 "print fmt: \"data=%d\", REC->data", 528 &self->check); 529 ASSERT_EQ(0, ret); 530 531 ret = check_print_fmt("__test_event u16 data", 532 "print fmt: \"data=%u\", REC->data", 533 &self->check); 534 ASSERT_EQ(0, ret); 535 536 ret = check_print_fmt("__test_event short data", 537 "print fmt: \"data=%d\", REC->data", 538 &self->check); 539 ASSERT_EQ(0, ret); 540 541 ret = check_print_fmt("__test_event unsigned short data", 542 "print fmt: \"data=%u\", REC->data", 543 &self->check); 544 ASSERT_EQ(0, ret); 545 546 ret = check_print_fmt("__test_event s8 data", 547 "print fmt: \"data=%d\", REC->data", 548 &self->check); 549 ASSERT_EQ(0, ret); 550 551 ret = check_print_fmt("__test_event u8 data", 552 "print fmt: \"data=%u\", REC->data", 553 &self->check); 554 ASSERT_EQ(0, ret); 555 556 ret = check_print_fmt("__test_event char data", 557 "print fmt: \"data=%d\", REC->data", 558 &self->check); 559 ASSERT_EQ(0, ret); 560 561 ret = check_print_fmt("__test_event unsigned char data", 562 "print fmt: \"data=%u\", REC->data", 563 &self->check); 564 ASSERT_EQ(0, ret); 565 566 ret = check_print_fmt("__test_event char[4] data", 567 "print fmt: \"data=%s\", REC->data", 568 &self->check); 569 ASSERT_EQ(0, ret); 570 } 571 572 int main(int argc, char **argv) 573 { 574 return test_harness_run(argc, argv); 575 } 576