1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 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_kill: 196 case LINUX_SYS_linux_tkill: 197 case LINUX_SYS_linux_rt_sigqueueinfo: 198 print_number(ip, narg, c); 199 putchar(','); 200 print_linux_signal(*ip); 201 ip++; 202 narg--; 203 break; 204 case LINUX_SYS_linux_tgkill: 205 case LINUX_SYS_linux_rt_tgsigqueueinfo: 206 print_number(ip, narg, c); 207 print_number(ip, narg, c); 208 putchar(','); 209 print_linux_signal(*ip); 210 ip++; 211 narg--; 212 break; 213 #ifdef LINUX_SYS_linux_open 214 case LINUX_SYS_linux_open: 215 #endif 216 case LINUX_SYS_linux_openat: 217 print_number(ip, narg, c); 218 putchar(','); 219 print_mask_arg(sysdecode_linux_open_flags, ip[0]); 220 if ((ip[0] & LINUX_O_CREAT) == LINUX_O_CREAT) { 221 putchar(','); 222 decode_filemode(ip[1]); 223 } 224 ip += 2; 225 narg -= 2; 226 break; 227 case LINUX_SYS_linux_rt_sigaction: 228 putchar('('); 229 print_linux_signal(*ip); 230 ip++; 231 narg--; 232 c = ','; 233 break; 234 case LINUX_SYS_linux_ftruncate: 235 case LINUX_SYS_linux_truncate: 236 print_number(ip, narg, c); 237 print_number64(first, ip, narg, c); 238 break; 239 case LINUX_SYS_linux_getitimer: 240 case LINUX_SYS_linux_setitimer: 241 putchar('('); 242 print_integer_arg(sysdecode_itimer, *ip); 243 ip++; 244 narg--; 245 c = ','; 246 break; 247 case LINUX_SYS_linux_rt_sigprocmask: 248 #ifdef LINUX_SYS_linux_sigprocmask 249 case LINUX_SYS_linux_sigprocmask: 250 #endif 251 putchar('('); 252 print_integer_arg(sysdecode_linux_sigprocmask_how, *ip); 253 ip++; 254 narg--; 255 c = ','; 256 break; 257 } 258 switch (ktr->ktr_code) { 259 case LINUX_SYS_linux_fchownat: 260 case LINUX_SYS_linux_faccessat: 261 case LINUX_SYS_linux_fchmodat: 262 #ifdef LINUX_SYS_linux_newfstatat 263 case LINUX_SYS_linux_newfstatat: 264 #endif 265 #ifdef LINUX_SYS_linux_fstatat64 266 case LINUX_SYS_linux_fstatat64: 267 #endif 268 case LINUX_SYS_linux_linkat: 269 case LINUX_SYS_linux_unlinkat: 270 case LINUX_SYS_linux_utimensat: 271 putchar(','); 272 print_mask_arg0(sysdecode_linux_atflags, *ip); 273 ip++; 274 narg--; 275 break; 276 } 277 *resc = c; 278 *resip = ip; 279 *resnarg = narg; 280 } 281 282 #if defined(__amd64__) 283 void 284 ktrsyscall_linux32(struct ktr_syscall *ktr, register_t **resip, 285 int *resnarg, char *resc) 286 { 287 int narg = ktr->ktr_narg; 288 register_t *ip, *first; 289 int quad_align, quad_slots; 290 char c; 291 292 ip = first = &ktr->ktr_args[0]; 293 c = *resc; 294 quad_align = 0; 295 quad_slots = 2; 296 switch (ktr->ktr_code) { 297 case LINUX32_SYS_linux_faccessat: 298 case LINUX32_SYS_linux_fchmodat: 299 case LINUX32_SYS_linux_fchownat: 300 case LINUX32_SYS_linux_fstatat64: 301 case LINUX32_SYS_linux_futimesat: 302 case LINUX32_SYS_linux_linkat: 303 case LINUX32_SYS_linux_mkdirat: 304 case LINUX32_SYS_linux_mknodat: 305 case LINUX32_SYS_linux_openat: 306 case LINUX32_SYS_linux_readlinkat: 307 case LINUX32_SYS_linux_renameat: 308 case LINUX32_SYS_linux_unlinkat: 309 case LINUX32_SYS_linux_utimensat: 310 putchar('('); 311 print_integer_arg_valid(sysdecode_atfd, *ip); 312 c = ','; 313 ip++; 314 narg--; 315 break; 316 } 317 switch (ktr->ktr_code) { 318 case LINUX32_SYS_linux_access: 319 case LINUX32_SYS_linux_faccessat: 320 print_number(ip, narg, c); 321 putchar(','); 322 print_mask_arg(sysdecode_access_mode, *ip); 323 ip++; 324 narg--; 325 break; 326 case LINUX32_SYS_linux_chmod: 327 case LINUX32_SYS_fchmod: 328 case LINUX32_SYS_linux_fchmodat: 329 print_number(ip, narg, c); 330 putchar(','); 331 decode_filemode(*ip); 332 ip++; 333 narg--; 334 break; 335 case LINUX32_SYS_linux_mknodat: 336 print_number(ip, narg, c); 337 putchar(','); 338 decode_filemode(*ip); 339 ip++; 340 narg--; 341 break; 342 case LINUX32_SYS_linux_mkdir: 343 case LINUX32_SYS_linux_mkdirat: 344 print_number(ip, narg, c); 345 putchar(','); 346 decode_filemode(*ip); 347 ip++; 348 narg--; 349 break; 350 case LINUX32_SYS_linux_linkat: 351 case LINUX32_SYS_linux_renameat: 352 case LINUX32_SYS_linux_symlinkat: 353 print_number(ip, narg, c); 354 putchar(','); 355 print_integer_arg_valid(sysdecode_atfd, *ip); 356 ip++; 357 narg--; 358 print_number(ip, narg, c); 359 break; 360 case LINUX32_SYS_linux_fchownat: 361 print_number(ip, narg, c); 362 print_number(ip, narg, c); 363 print_number(ip, narg, c); 364 break; 365 case LINUX32_SYS_linux_fstatat64: 366 case LINUX32_SYS_linux_utimensat: 367 print_number(ip, narg, c); 368 print_number(ip, narg, c); 369 break; 370 case LINUX32_SYS_linux_unlinkat: 371 print_number(ip, narg, c); 372 break; 373 case LINUX32_SYS_linux_clock_gettime: 374 case LINUX32_SYS_linux_clock_settime: 375 case LINUX32_SYS_linux_clock_getres: 376 case LINUX32_SYS_linux_timer_create: 377 case LINUX32_SYS_linux_clock_gettime64: 378 case LINUX32_SYS_linux_clock_settime64: 379 case LINUX32_SYS_linux_clock_getres_time64: 380 putchar('('); 381 sysdecode_linux_clockid(stdout, *ip); 382 c = ','; 383 ip++; 384 narg--; 385 break; 386 case LINUX32_SYS_linux_clock_nanosleep: 387 putchar('('); 388 sysdecode_linux_clockid(stdout, *ip); 389 putchar(','); 390 ip++; 391 narg--; 392 print_mask_arg0(sysdecode_linux_clock_flags, *ip); 393 c = ','; 394 ip++; 395 narg--; 396 break; 397 case LINUX32_SYS_linux_kill: 398 case LINUX32_SYS_linux_tkill: 399 case LINUX32_SYS_linux_rt_sigqueueinfo: 400 print_number(ip, narg, c); 401 putchar(','); 402 print_linux_signal(*ip); 403 ip++; 404 narg--; 405 break; 406 case LINUX32_SYS_linux_tgkill: 407 case LINUX32_SYS_linux_rt_tgsigqueueinfo: 408 print_number(ip, narg, c); 409 print_number(ip, narg, c); 410 putchar(','); 411 print_linux_signal(*ip); 412 ip++; 413 narg--; 414 break; 415 case LINUX32_SYS_linux_open: 416 case LINUX32_SYS_linux_openat: 417 print_number(ip, narg, c); 418 putchar(','); 419 print_mask_arg(sysdecode_linux_open_flags, ip[0]); 420 if ((ip[0] & LINUX_O_CREAT) == LINUX_O_CREAT) { 421 putchar(','); 422 decode_filemode(ip[1]); 423 } 424 ip += 2; 425 narg -= 2; 426 break; 427 case LINUX32_SYS_linux_signal: 428 case LINUX32_SYS_linux_sigaction: 429 case LINUX32_SYS_linux_rt_sigaction: 430 putchar('('); 431 print_linux_signal(*ip); 432 ip++; 433 narg--; 434 c = ','; 435 break; 436 case LINUX32_SYS_linux_ftruncate: 437 case LINUX32_SYS_linux_truncate: 438 print_number(ip, narg, c); 439 print_number64(first, ip, narg, c); 440 break; 441 case LINUX32_SYS_linux_getitimer: 442 case LINUX32_SYS_linux_setitimer: 443 putchar('('); 444 print_integer_arg(sysdecode_itimer, *ip); 445 ip++; 446 narg--; 447 c = ','; 448 break; 449 case LINUX32_SYS_linux_rt_sigprocmask: 450 case LINUX32_SYS_linux_sigprocmask: 451 putchar('('); 452 print_integer_arg(sysdecode_linux_sigprocmask_how, *ip); 453 ip++; 454 narg--; 455 c = ','; 456 break; 457 } 458 switch (ktr->ktr_code) { 459 case LINUX32_SYS_linux_fchownat: 460 case LINUX32_SYS_linux_faccessat: 461 case LINUX32_SYS_linux_fchmodat: 462 case LINUX32_SYS_linux_fstatat64: 463 case LINUX32_SYS_linux_linkat: 464 case LINUX32_SYS_linux_unlinkat: 465 case LINUX32_SYS_linux_utimensat: 466 putchar(','); 467 print_mask_arg0(sysdecode_linux_atflags, *ip); 468 ip++; 469 narg--; 470 break; 471 } 472 *resc = c; 473 *resip = ip; 474 *resnarg = narg; 475 } 476 #endif /* __amd64__ */ 477 478 static void 479 ktrsigset(const char *name, const l_sigset_t *mask, size_t sz) 480 { 481 unsigned long i, c; 482 483 printf("%s [ ", name); 484 c = 0; 485 for (i = 1; i <= sz * CHAR_BIT; i++) { 486 if (!LINUX_SIGISMEMBER(*mask, i)) 487 continue; 488 if (c != 0) 489 printf(", "); 490 printf("%s", sysdecode_linux_signal(i)); 491 c++; 492 } 493 if (c == 0) 494 printf("empty ]\n"); 495 else 496 printf(" ]\n"); 497 } 498 499 bool 500 ktrstruct_linux(const char *name, const char *data, size_t datalen) 501 { 502 l_sigset_t mask; 503 504 if (strcmp(name, "l_sigset_t") == 0) { 505 /* Old Linux sigset_t is one word size. */ 506 if (datalen < sizeof(int) || datalen > sizeof(l_sigset_t)) 507 return (false); 508 memcpy(&mask, data, datalen); 509 ktrsigset(name, &mask, datalen); 510 } else 511 return (false); 512 513 return (true); 514 } 515