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