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