1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2022 Dmitry Chagin <dchagin@FreeBSD.org> 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28 #include <sys/param.h> 29 #include <sys/uio.h> 30 #include <sys/ktrace.h> 31 #include <err.h> 32 #include <errno.h> 33 #include <stddef.h> 34 #include <stdlib.h> 35 #include <string.h> 36 #include <sysdecode.h> 37 38 #include "kdump.h" 39 40 #ifdef __amd64__ 41 #include <amd64/linux/linux.h> 42 #include <amd64/linux32/linux32_syscall.h> 43 #elif __aarch64__ 44 #include <arm64/linux/linux.h> 45 #elif __i386__ 46 #include <i386/linux/linux.h> 47 #endif 48 49 #include <compat/linux/linux.h> 50 #include <compat/linux/linux_file.h> 51 52 static void 53 print_linux_signal(int signo) 54 { 55 const char *signame; 56 57 signame = sysdecode_linux_signal(signo); 58 if (signame != NULL) 59 printf("%s", signame); 60 else 61 printf("SIG %d", signo); 62 } 63 64 void 65 ktrsyscall_linux(struct ktr_syscall *ktr, register_t **resip, 66 int *resnarg, char *resc) 67 { 68 int narg = ktr->ktr_narg; 69 register_t *ip, *first; 70 int quad_align, quad_slots; 71 char c; 72 73 ip = first = &ktr->ktr_args[0]; 74 c = *resc; 75 quad_align = 0; 76 quad_slots = 1; 77 switch (ktr->ktr_code) { 78 case LINUX_SYS_linux_faccessat: 79 case LINUX_SYS_linux_fchmodat: 80 case LINUX_SYS_linux_fchownat: 81 #ifdef LINUX_SYS_linux_newfstatat 82 case LINUX_SYS_linux_newfstatat: 83 #endif 84 #ifdef LINUX_SYS_linux_fstatat64 85 case LINUX_SYS_linux_fstatat64: 86 #endif 87 #ifdef LINUX_SYS_linux_futimesat 88 case LINUX_SYS_linux_futimesat: 89 #endif 90 case LINUX_SYS_linux_linkat: 91 case LINUX_SYS_linux_mkdirat: 92 case LINUX_SYS_linux_mknodat: 93 case LINUX_SYS_linux_openat: 94 case LINUX_SYS_linux_readlinkat: 95 case LINUX_SYS_linux_renameat: 96 case LINUX_SYS_linux_unlinkat: 97 case LINUX_SYS_linux_utimensat: 98 putchar('('); 99 print_integer_arg_valid(sysdecode_atfd, *ip); 100 c = ','; 101 ip++; 102 narg--; 103 break; 104 } 105 switch (ktr->ktr_code) { 106 #ifdef LINUX_SYS_linux_access 107 case LINUX_SYS_linux_access: 108 #endif 109 case LINUX_SYS_linux_faccessat: 110 print_number(ip, narg, c); 111 putchar(','); 112 print_mask_arg(sysdecode_access_mode, *ip); 113 ip++; 114 narg--; 115 break; 116 #ifdef LINUX_SYS_linux_chmod 117 case LINUX_SYS_linux_chmod: 118 #endif 119 case LINUX_SYS_linux_fchmodat: 120 print_number(ip, narg, c); 121 putchar(','); 122 decode_filemode(*ip); 123 ip++; 124 narg--; 125 break; 126 case LINUX_SYS_linux_mknodat: 127 print_number(ip, narg, c); 128 putchar(','); 129 decode_filemode(*ip); 130 ip++; 131 narg--; 132 break; 133 #ifdef LINUX_SYS_linux_mkdir 134 case LINUX_SYS_linux_mkdir: 135 #endif 136 case LINUX_SYS_linux_mkdirat: 137 print_number(ip, narg, c); 138 putchar(','); 139 decode_filemode(*ip); 140 ip++; 141 narg--; 142 break; 143 case LINUX_SYS_linux_linkat: 144 case LINUX_SYS_linux_renameat: 145 case LINUX_SYS_linux_symlinkat: 146 print_number(ip, narg, c); 147 putchar(','); 148 print_integer_arg_valid(sysdecode_atfd, *ip); 149 ip++; 150 narg--; 151 print_number(ip, narg, c); 152 break; 153 case LINUX_SYS_linux_fchownat: 154 print_number(ip, narg, c); 155 print_number(ip, narg, c); 156 print_number(ip, narg, c); 157 break; 158 #ifdef LINUX_SYS_linux_newfstatat 159 case LINUX_SYS_linux_newfstatat: 160 #endif 161 #ifdef LINUX_SYS_linux_fstatat64 162 case LINUX_SYS_linux_fstatat64: 163 #endif 164 case LINUX_SYS_linux_utimensat: 165 print_number(ip, narg, c); 166 print_number(ip, narg, c); 167 break; 168 case LINUX_SYS_linux_unlinkat: 169 print_number(ip, narg, c); 170 break; 171 case LINUX_SYS_linux_clock_gettime: 172 case LINUX_SYS_linux_clock_settime: 173 case LINUX_SYS_linux_clock_getres: 174 case LINUX_SYS_linux_timer_create: 175 putchar('('); 176 sysdecode_linux_clockid(stdout, *ip); 177 c = ','; 178 ip++; 179 narg--; 180 break; 181 case LINUX_SYS_linux_clock_nanosleep: 182 putchar('('); 183 sysdecode_linux_clockid(stdout, *ip); 184 putchar(','); 185 ip++; 186 narg--; 187 print_mask_arg0(sysdecode_linux_clock_flags, *ip); 188 c = ','; 189 ip++; 190 narg--; 191 break; 192 case LINUX_SYS_linux_clone: 193 putchar('('); 194 print_mask_arg(sysdecode_linux_clone_flags, *ip); 195 ip++; 196 narg--; 197 c = ','; 198 break; 199 case LINUX_SYS_linux_kill: 200 case LINUX_SYS_linux_tkill: 201 case LINUX_SYS_linux_rt_sigqueueinfo: 202 print_decimal_number(ip, narg, c); 203 putchar(','); 204 print_linux_signal(*ip); 205 ip++; 206 narg--; 207 break; 208 case LINUX_SYS_linux_tgkill: 209 case LINUX_SYS_linux_rt_tgsigqueueinfo: 210 print_decimal_number(ip, narg, c); 211 print_decimal_number(ip, narg, c); 212 putchar(','); 213 print_linux_signal(*ip); 214 ip++; 215 narg--; 216 break; 217 #ifdef LINUX_SYS_linux_open 218 case LINUX_SYS_linux_open: 219 #endif 220 case LINUX_SYS_linux_openat: 221 print_number(ip, narg, c); 222 putchar(','); 223 print_mask_arg(sysdecode_linux_open_flags, ip[0]); 224 if ((ip[0] & LINUX_O_CREAT) == LINUX_O_CREAT) { 225 putchar(','); 226 decode_filemode(ip[1]); 227 } 228 ip += 2; 229 narg -= 2; 230 break; 231 case LINUX_SYS_linux_rt_sigaction: 232 putchar('('); 233 print_linux_signal(*ip); 234 ip++; 235 narg--; 236 c = ','; 237 break; 238 case LINUX_SYS_linux_ftruncate: 239 case LINUX_SYS_linux_truncate: 240 print_number(ip, narg, c); 241 print_number64(first, ip, narg, c); 242 break; 243 case LINUX_SYS_linux_getitimer: 244 case LINUX_SYS_linux_setitimer: 245 putchar('('); 246 print_integer_arg(sysdecode_itimer, *ip); 247 ip++; 248 narg--; 249 c = ','; 250 break; 251 case LINUX_SYS_linux_rt_sigprocmask: 252 #ifdef LINUX_SYS_linux_sigprocmask 253 case LINUX_SYS_linux_sigprocmask: 254 #endif 255 putchar('('); 256 print_integer_arg(sysdecode_linux_sigprocmask_how, *ip); 257 ip++; 258 narg--; 259 c = ','; 260 break; 261 } 262 switch (ktr->ktr_code) { 263 case LINUX_SYS_linux_fchownat: 264 case LINUX_SYS_linux_faccessat: 265 case LINUX_SYS_linux_fchmodat: 266 #ifdef LINUX_SYS_linux_newfstatat 267 case LINUX_SYS_linux_newfstatat: 268 #endif 269 #ifdef LINUX_SYS_linux_fstatat64 270 case LINUX_SYS_linux_fstatat64: 271 #endif 272 case LINUX_SYS_linux_linkat: 273 case LINUX_SYS_linux_unlinkat: 274 case LINUX_SYS_linux_utimensat: 275 putchar(','); 276 print_mask_arg0(sysdecode_linux_atflags, *ip); 277 ip++; 278 narg--; 279 break; 280 } 281 *resc = c; 282 *resip = ip; 283 *resnarg = narg; 284 } 285 286 #if defined(__amd64__) 287 void 288 ktrsyscall_linux32(struct ktr_syscall *ktr, register_t **resip, 289 int *resnarg, char *resc) 290 { 291 int narg = ktr->ktr_narg; 292 register_t *ip, *first; 293 int quad_align, quad_slots; 294 char c; 295 296 ip = first = &ktr->ktr_args[0]; 297 c = *resc; 298 quad_align = 0; 299 quad_slots = 2; 300 switch (ktr->ktr_code) { 301 case LINUX32_SYS_linux_faccessat: 302 case LINUX32_SYS_linux_fchmodat: 303 case LINUX32_SYS_linux_fchownat: 304 case LINUX32_SYS_linux_fstatat64: 305 case LINUX32_SYS_linux_futimesat: 306 case LINUX32_SYS_linux_linkat: 307 case LINUX32_SYS_linux_mkdirat: 308 case LINUX32_SYS_linux_mknodat: 309 case LINUX32_SYS_linux_openat: 310 case LINUX32_SYS_linux_readlinkat: 311 case LINUX32_SYS_linux_renameat: 312 case LINUX32_SYS_linux_unlinkat: 313 case LINUX32_SYS_linux_utimensat: 314 putchar('('); 315 print_integer_arg_valid(sysdecode_atfd, *ip); 316 c = ','; 317 ip++; 318 narg--; 319 break; 320 } 321 switch (ktr->ktr_code) { 322 case LINUX32_SYS_linux_access: 323 case LINUX32_SYS_linux_faccessat: 324 print_number(ip, narg, c); 325 putchar(','); 326 print_mask_arg(sysdecode_access_mode, *ip); 327 ip++; 328 narg--; 329 break; 330 case LINUX32_SYS_linux_chmod: 331 case LINUX32_SYS_fchmod: 332 case LINUX32_SYS_linux_fchmodat: 333 print_number(ip, narg, c); 334 putchar(','); 335 decode_filemode(*ip); 336 ip++; 337 narg--; 338 break; 339 case LINUX32_SYS_linux_mknodat: 340 print_number(ip, narg, c); 341 putchar(','); 342 decode_filemode(*ip); 343 ip++; 344 narg--; 345 break; 346 case LINUX32_SYS_linux_mkdir: 347 case LINUX32_SYS_linux_mkdirat: 348 print_number(ip, narg, c); 349 putchar(','); 350 decode_filemode(*ip); 351 ip++; 352 narg--; 353 break; 354 case LINUX32_SYS_linux_linkat: 355 case LINUX32_SYS_linux_renameat: 356 case LINUX32_SYS_linux_symlinkat: 357 print_number(ip, narg, c); 358 putchar(','); 359 print_integer_arg_valid(sysdecode_atfd, *ip); 360 ip++; 361 narg--; 362 print_number(ip, narg, c); 363 break; 364 case LINUX32_SYS_linux_fchownat: 365 print_number(ip, narg, c); 366 print_number(ip, narg, c); 367 print_number(ip, narg, c); 368 break; 369 case LINUX32_SYS_linux_fstatat64: 370 case LINUX32_SYS_linux_utimensat: 371 print_number(ip, narg, c); 372 print_number(ip, narg, c); 373 break; 374 case LINUX32_SYS_linux_unlinkat: 375 print_number(ip, narg, c); 376 break; 377 case LINUX32_SYS_linux_clock_gettime: 378 case LINUX32_SYS_linux_clock_settime: 379 case LINUX32_SYS_linux_clock_getres: 380 case LINUX32_SYS_linux_timer_create: 381 case LINUX32_SYS_linux_clock_gettime64: 382 case LINUX32_SYS_linux_clock_settime64: 383 case LINUX32_SYS_linux_clock_getres_time64: 384 putchar('('); 385 sysdecode_linux_clockid(stdout, *ip); 386 c = ','; 387 ip++; 388 narg--; 389 break; 390 case LINUX32_SYS_linux_clock_nanosleep: 391 putchar('('); 392 sysdecode_linux_clockid(stdout, *ip); 393 putchar(','); 394 ip++; 395 narg--; 396 print_mask_arg0(sysdecode_linux_clock_flags, *ip); 397 c = ','; 398 ip++; 399 narg--; 400 break; 401 case LINUX32_SYS_linux_clone: 402 putchar('('); 403 print_mask_arg(sysdecode_linux_clone_flags, *ip); 404 ip++; 405 narg--; 406 c = ','; 407 break; 408 case LINUX32_SYS_linux_kill: 409 case LINUX32_SYS_linux_tkill: 410 case LINUX32_SYS_linux_rt_sigqueueinfo: 411 print_decimal_number(ip, narg, c); 412 putchar(','); 413 print_linux_signal(*ip); 414 ip++; 415 narg--; 416 break; 417 case LINUX32_SYS_linux_tgkill: 418 case LINUX32_SYS_linux_rt_tgsigqueueinfo: 419 print_decimal_number(ip, narg, c); 420 print_decimal_number(ip, narg, c); 421 putchar(','); 422 print_linux_signal(*ip); 423 ip++; 424 narg--; 425 break; 426 case LINUX32_SYS_linux_open: 427 case LINUX32_SYS_linux_openat: 428 print_number(ip, narg, c); 429 putchar(','); 430 print_mask_arg(sysdecode_linux_open_flags, ip[0]); 431 if ((ip[0] & LINUX_O_CREAT) == LINUX_O_CREAT) { 432 putchar(','); 433 decode_filemode(ip[1]); 434 } 435 ip += 2; 436 narg -= 2; 437 break; 438 case LINUX32_SYS_linux_signal: 439 case LINUX32_SYS_linux_sigaction: 440 case LINUX32_SYS_linux_rt_sigaction: 441 putchar('('); 442 print_linux_signal(*ip); 443 ip++; 444 narg--; 445 c = ','; 446 break; 447 case LINUX32_SYS_linux_ftruncate: 448 case LINUX32_SYS_linux_truncate: 449 print_number(ip, narg, c); 450 print_number64(first, ip, narg, c); 451 break; 452 case LINUX32_SYS_linux_getitimer: 453 case LINUX32_SYS_linux_setitimer: 454 putchar('('); 455 print_integer_arg(sysdecode_itimer, *ip); 456 ip++; 457 narg--; 458 c = ','; 459 break; 460 case LINUX32_SYS_linux_rt_sigprocmask: 461 case LINUX32_SYS_linux_sigprocmask: 462 putchar('('); 463 print_integer_arg(sysdecode_linux_sigprocmask_how, *ip); 464 ip++; 465 narg--; 466 c = ','; 467 break; 468 } 469 switch (ktr->ktr_code) { 470 case LINUX32_SYS_linux_fchownat: 471 case LINUX32_SYS_linux_faccessat: 472 case LINUX32_SYS_linux_fchmodat: 473 case LINUX32_SYS_linux_fstatat64: 474 case LINUX32_SYS_linux_linkat: 475 case LINUX32_SYS_linux_unlinkat: 476 case LINUX32_SYS_linux_utimensat: 477 putchar(','); 478 print_mask_arg0(sysdecode_linux_atflags, *ip); 479 ip++; 480 narg--; 481 break; 482 } 483 *resc = c; 484 *resip = ip; 485 *resnarg = narg; 486 } 487 #endif /* __amd64__ */ 488 489 static void 490 ktrsigset(const char *name, const l_sigset_t *mask, size_t sz) 491 { 492 unsigned long i, c; 493 494 printf("%s [ ", name); 495 c = 0; 496 for (i = 1; i <= sz * CHAR_BIT; i++) { 497 if (!LINUX_SIGISMEMBER(*mask, i)) 498 continue; 499 if (c != 0) 500 printf(", "); 501 printf("%s", sysdecode_linux_signal(i)); 502 c++; 503 } 504 if (c == 0) 505 printf("empty ]\n"); 506 else 507 printf(" ]\n"); 508 } 509 510 bool 511 ktrstruct_linux(const char *name, const char *data, size_t datalen) 512 { 513 l_sigset_t mask; 514 515 if (strcmp(name, "l_sigset_t") == 0) { 516 /* Old Linux sigset_t is one word size. */ 517 if (datalen < sizeof(int) || datalen > sizeof(l_sigset_t)) 518 return (false); 519 memcpy(&mask, data, datalen); 520 ktrsigset(name, &mask, datalen); 521 } else 522 return (false); 523 524 return (true); 525 } 526