1 /*- 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright (c) 2021 Edward Tomasz Napierala <trasz@FreeBSD.org> 5 * Copyright (c) 2018 Chuck Tuffli 6 * Copyright (c) 2017 Dell EMC 7 * Copyright (c) 2000 David O'Brien 8 * Copyright (c) 1995-1996 Søren Schmidt 9 * Copyright (c) 1996 Peter Wemm 10 * All rights reserved. 11 * 12 * This software was developed by the University of Cambridge Computer 13 * Laboratory as part of the CHERI for Hypervisors and Operating Systems 14 * (CHaOS) project, funded by EPSRC grant EP/V000292/1. 15 * 16 * Redistribution and use in source and binary forms, with or without 17 * modification, are permitted provided that the following conditions 18 * are met: 19 * 1. Redistributions of source code must retain the above copyright 20 * notice, this list of conditions and the following disclaimer 21 * in this position and unchanged. 22 * 2. Redistributions in binary form must reproduce the above copyright 23 * notice, this list of conditions and the following disclaimer in the 24 * documentation and/or other materials provided with the distribution. 25 * 3. The name of the author may not be used to endorse or promote products 26 * derived from this software without specific prior written permission 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 29 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 30 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 31 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 32 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 33 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 34 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 35 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 36 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 37 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38 */ 39 40 #include <sys/param.h> 41 #include <sys/exec.h> 42 #include <sys/imgact.h> 43 #include <sys/imgact_elf.h> 44 #include <sys/lock.h> 45 #include <sys/malloc.h> 46 #include <sys/mutex.h> 47 #include <sys/proc.h> 48 #include <sys/procfs.h> 49 #include <sys/reg.h> 50 #include <sys/sbuf.h> 51 #include <sys/sysent.h> 52 53 #include <vm/vm.h> 54 #include <vm/pmap.h> 55 #include <vm/vm_map.h> 56 57 #include <machine/elf.h> 58 59 #ifdef COMPAT_LINUX32 60 #define linux_pt_regset linux_pt_regset32 61 #define bsd_to_linux_regset bsd_to_linux_regset32 62 #include <machine/../linux32/linux.h> 63 #else 64 #include <machine/../linux/linux.h> 65 #endif 66 #include <compat/linux/linux_elf.h> 67 #include <compat/linux/linux_mib.h> 68 #include <compat/linux/linux_misc.h> 69 70 struct l_elf_siginfo { 71 l_int si_signo; 72 l_int si_code; 73 l_int si_errno; 74 }; 75 76 typedef struct linux_pt_regset l_elf_gregset_t; 77 78 struct linux_elf_prstatus { 79 struct l_elf_siginfo pr_info; 80 l_short pr_cursig; 81 l_ulong pr_sigpend; 82 l_ulong pr_sighold; 83 l_pid_t pr_pid; 84 l_pid_t pr_ppid; 85 l_pid_t pr_pgrp; 86 l_pid_t pr_sid; 87 l_timeval pr_utime; 88 l_timeval pr_stime; 89 l_timeval pr_cutime; 90 l_timeval pr_cstime; 91 l_elf_gregset_t pr_reg; 92 l_int pr_fpvalid; 93 }; 94 95 #define LINUX_NT_AUXV 6 96 97 static void __linuxN(note_fpregset)(void *, struct sbuf *, size_t *); 98 static void __linuxN(note_prpsinfo)(void *, struct sbuf *, size_t *); 99 static void __linuxN(note_prstatus)(void *, struct sbuf *, size_t *); 100 static void __linuxN(note_threadmd)(void *, struct sbuf *, size_t *); 101 static void __linuxN(note_nt_auxv)(void *, struct sbuf *, size_t *); 102 103 void 104 __linuxN(prepare_notes)(struct thread *td, struct note_info_list *list, 105 size_t *sizep) 106 { 107 struct proc *p; 108 struct thread *thr; 109 size_t size; 110 111 p = td->td_proc; 112 size = 0; 113 114 /* 115 * To have the debugger select the right thread (LWP) as the initial 116 * thread, we dump the state of the thread passed to us in td first. 117 * This is the thread that causes the core dump and thus likely to 118 * be the right thread one wants to have selected in the debugger. 119 */ 120 thr = td; 121 while (thr != NULL) { 122 size += __elfN(register_note)(td, list, 123 NT_PRSTATUS, __linuxN(note_prstatus), thr); 124 size += __elfN(register_note)(td, list, 125 NT_PRPSINFO, __linuxN(note_prpsinfo), p); 126 size += __elfN(register_note)(td, list, 127 LINUX_NT_AUXV, __linuxN(note_nt_auxv), p); 128 size += __elfN(register_note)(td, list, 129 NT_FPREGSET, __linuxN(note_fpregset), thr); 130 size += __elfN(register_note)(td, list, 131 -1, __linuxN(note_threadmd), thr); 132 133 thr = thr == td ? TAILQ_FIRST(&p->p_threads) : 134 TAILQ_NEXT(thr, td_plist); 135 if (thr == td) 136 thr = TAILQ_NEXT(thr, td_plist); 137 } 138 139 *sizep = size; 140 } 141 142 typedef struct linux_elf_prstatus linux_elf_prstatus_t; 143 #ifdef COMPAT_LINUX32 144 typedef struct prpsinfo32 linux_elf_prpsinfo_t; 145 typedef struct fpreg32 linux_elf_prfpregset_t; 146 #else 147 typedef prpsinfo_t linux_elf_prpsinfo_t; 148 typedef prfpregset_t linux_elf_prfpregset_t; 149 #endif 150 151 static void 152 __linuxN(note_prpsinfo)(void *arg, struct sbuf *sb, size_t *sizep) 153 { 154 struct sbuf sbarg; 155 size_t len; 156 char *cp, *end; 157 struct proc *p; 158 linux_elf_prpsinfo_t *psinfo; 159 int error; 160 161 p = arg; 162 if (sb != NULL) { 163 KASSERT(*sizep == sizeof(*psinfo), ("invalid size")); 164 psinfo = malloc(sizeof(*psinfo), M_TEMP, M_ZERO | M_WAITOK); 165 psinfo->pr_version = PRPSINFO_VERSION; 166 psinfo->pr_psinfosz = sizeof(linux_elf_prpsinfo_t); 167 strlcpy(psinfo->pr_fname, p->p_comm, sizeof(psinfo->pr_fname)); 168 PROC_LOCK(p); 169 if (p->p_args != NULL) { 170 len = sizeof(psinfo->pr_psargs) - 1; 171 if (len > p->p_args->ar_length) 172 len = p->p_args->ar_length; 173 memcpy(psinfo->pr_psargs, p->p_args->ar_args, len); 174 PROC_UNLOCK(p); 175 error = 0; 176 } else { 177 _PHOLD(p); 178 PROC_UNLOCK(p); 179 sbuf_new(&sbarg, psinfo->pr_psargs, 180 sizeof(psinfo->pr_psargs), SBUF_FIXEDLEN); 181 error = proc_getargv(curthread, p, &sbarg); 182 PRELE(p); 183 if (sbuf_finish(&sbarg) == 0) { 184 len = sbuf_len(&sbarg) - 1; 185 if (len > 0) 186 len--; 187 } else { 188 len = sizeof(psinfo->pr_psargs) - 1; 189 } 190 sbuf_delete(&sbarg); 191 } 192 if (error != 0 || len == 0 || (ssize_t)len == -1) 193 strlcpy(psinfo->pr_psargs, p->p_comm, 194 sizeof(psinfo->pr_psargs)); 195 else { 196 KASSERT(len < sizeof(psinfo->pr_psargs), 197 ("len is too long: %zu vs %zu", len, 198 sizeof(psinfo->pr_psargs))); 199 cp = psinfo->pr_psargs; 200 end = cp + len - 1; 201 for (;;) { 202 cp = memchr(cp, '\0', end - cp); 203 if (cp == NULL) 204 break; 205 *cp = ' '; 206 } 207 } 208 psinfo->pr_pid = p->p_pid; 209 sbuf_bcat(sb, psinfo, sizeof(*psinfo)); 210 free(psinfo, M_TEMP); 211 } 212 *sizep = sizeof(*psinfo); 213 } 214 215 static void 216 __linuxN(note_prstatus)(void *arg, struct sbuf *sb, size_t *sizep) 217 { 218 struct thread *td; 219 linux_elf_prstatus_t *status; 220 #ifdef COMPAT_LINUX32 221 struct reg32 pr_reg; 222 #else 223 struct reg pr_reg; 224 #endif 225 226 td = arg; 227 if (sb != NULL) { 228 KASSERT(*sizep == sizeof(*status), ("invalid size")); 229 status = malloc(sizeof(*status), M_TEMP, M_ZERO | M_WAITOK); 230 231 /* 232 * XXX: Some fields missing. 233 */ 234 status->pr_cursig = td->td_proc->p_sig; 235 status->pr_pid = td->td_tid; 236 237 #ifdef COMPAT_LINUX32 238 fill_regs32(td, &pr_reg); 239 #else 240 fill_regs(td, &pr_reg); 241 #endif 242 bsd_to_linux_regset(&pr_reg, &status->pr_reg); 243 sbuf_bcat(sb, status, sizeof(*status)); 244 free(status, M_TEMP); 245 } 246 *sizep = sizeof(*status); 247 } 248 249 static void 250 __linuxN(note_fpregset)(void *arg, struct sbuf *sb, size_t *sizep) 251 { 252 struct thread *td; 253 linux_elf_prfpregset_t *fpregset; 254 255 td = arg; 256 if (sb != NULL) { 257 KASSERT(*sizep == sizeof(*fpregset), ("invalid size")); 258 fpregset = malloc(sizeof(*fpregset), M_TEMP, M_ZERO | M_WAITOK); 259 #ifdef COMPAT_LINUX32 260 fill_fpregs32(td, fpregset); 261 #else 262 fill_fpregs(td, fpregset); 263 #endif 264 sbuf_bcat(sb, fpregset, sizeof(*fpregset)); 265 free(fpregset, M_TEMP); 266 } 267 *sizep = sizeof(*fpregset); 268 } 269 270 /* 271 * Allow for MD specific notes, as well as any MD 272 * specific preparations for writing MI notes. 273 */ 274 static void 275 __linuxN(note_threadmd)(void *arg, struct sbuf *sb, size_t *sizep) 276 { 277 struct thread *td; 278 void *buf; 279 size_t size; 280 281 td = arg; 282 size = *sizep; 283 if (size != 0 && sb != NULL) 284 buf = malloc(size, M_TEMP, M_ZERO | M_WAITOK); 285 else 286 buf = NULL; 287 size = 0; 288 __elfN(dump_thread)(td, buf, &size); 289 KASSERT(sb == NULL || *sizep == size, ("invalid size")); 290 if (size != 0 && sb != NULL) 291 sbuf_bcat(sb, buf, size); 292 free(buf, M_TEMP); 293 *sizep = size; 294 } 295 296 static void 297 __linuxN(note_nt_auxv)(void *arg, struct sbuf *sb, size_t *sizep) 298 { 299 struct proc *p; 300 size_t size; 301 302 p = arg; 303 if (sb == NULL) { 304 size = 0; 305 sb = sbuf_new(NULL, NULL, LINUX_AT_COUNT * sizeof(Elf_Auxinfo), 306 SBUF_FIXEDLEN); 307 sbuf_set_drain(sb, sbuf_count_drain, &size); 308 PHOLD(p); 309 proc_getauxv(curthread, p, sb); 310 PRELE(p); 311 sbuf_finish(sb); 312 sbuf_delete(sb); 313 *sizep = size; 314 } else { 315 PHOLD(p); 316 proc_getauxv(curthread, p, sb); 317 PRELE(p); 318 } 319 } 320 321 /* 322 * Copy strings out to the new process address space, constructing new arg 323 * and env vector tables. Return a pointer to the base so that it can be used 324 * as the initial stack pointer. 325 */ 326 int 327 __linuxN(copyout_strings)(struct image_params *imgp, uintptr_t *stack_base) 328 { 329 char canary[LINUX_AT_RANDOM_LEN]; 330 char **vectp; 331 char *stringp; 332 uintptr_t destp, ustringp; 333 struct ps_strings *arginfo; 334 struct proc *p; 335 size_t execpath_len; 336 int argc, envc; 337 int error; 338 339 p = imgp->proc; 340 destp = PROC_PS_STRINGS(p); 341 arginfo = imgp->ps_strings = (void *)destp; 342 343 /* 344 * Copy the image path for the rtld. 345 */ 346 if (imgp->execpath != NULL && imgp->auxargs != NULL) { 347 execpath_len = strlen(imgp->execpath) + 1; 348 destp -= execpath_len; 349 destp = rounddown2(destp, sizeof(void *)); 350 imgp->execpathp = (void *)destp; 351 error = copyout(imgp->execpath, imgp->execpathp, execpath_len); 352 if (error != 0) 353 return (error); 354 } 355 356 /* 357 * Prepare the canary for SSP. 358 */ 359 arc4rand(canary, sizeof(canary), 0); 360 destp -= sizeof(canary); 361 imgp->canary = (void *)destp; 362 error = copyout(canary, imgp->canary, sizeof(canary)); 363 if (error != 0) 364 return (error); 365 imgp->canarylen = sizeof(canary); 366 367 /* 368 * Allocate room for the argument and environment strings. 369 */ 370 destp -= ARG_MAX - imgp->args->stringspace; 371 destp = rounddown2(destp, sizeof(void *)); 372 ustringp = destp; 373 374 if (imgp->auxargs) { 375 /* 376 * Allocate room on the stack for the ELF auxargs 377 * array. It has up to LINUX_AT_COUNT entries. 378 */ 379 destp -= LINUX_AT_COUNT * sizeof(Elf_Auxinfo); 380 destp = rounddown2(destp, sizeof(void *)); 381 } 382 383 vectp = (char **)destp; 384 385 /* 386 * Allocate room for the argv[] and env vectors including the 387 * terminating NULL pointers. 388 */ 389 vectp -= imgp->args->argc + 1 + imgp->args->envc + 1; 390 391 /* 392 * Starting with 2.24, glibc depends on a 16-byte stack alignment. 393 */ 394 vectp = (char **)((((uintptr_t)vectp + 8) & ~0xF) - 8); 395 396 /* 397 * vectp also becomes our initial stack base 398 */ 399 *stack_base = (uintptr_t)vectp; 400 401 stringp = imgp->args->begin_argv; 402 argc = imgp->args->argc; 403 envc = imgp->args->envc; 404 405 /* 406 * Copy out strings - arguments and environment. 407 */ 408 error = copyout(stringp, (void *)ustringp, 409 ARG_MAX - imgp->args->stringspace); 410 if (error != 0) 411 return (error); 412 413 /* 414 * Fill in "ps_strings" struct for ps, w, etc. 415 */ 416 imgp->argv = vectp; 417 if (suword(&arginfo->ps_argvstr, (long)(intptr_t)vectp) != 0 || 418 suword32(&arginfo->ps_nargvstr, argc) != 0) 419 return (EFAULT); 420 421 /* 422 * Fill in argument portion of vector table. 423 */ 424 for (; argc > 0; --argc) { 425 if (suword(vectp++, ustringp) != 0) 426 return (EFAULT); 427 while (*stringp++ != 0) 428 ustringp++; 429 ustringp++; 430 } 431 432 /* a null vector table pointer separates the argp's from the envp's */ 433 if (suword(vectp++, 0) != 0) 434 return (EFAULT); 435 436 imgp->envv = vectp; 437 if (suword(&arginfo->ps_envstr, (long)(intptr_t)vectp) != 0 || 438 suword32(&arginfo->ps_nenvstr, envc) != 0) 439 return (EFAULT); 440 441 /* 442 * Fill in environment portion of vector table. 443 */ 444 for (; envc > 0; --envc) { 445 if (suword(vectp++, ustringp) != 0) 446 return (EFAULT); 447 while (*stringp++ != 0) 448 ustringp++; 449 ustringp++; 450 } 451 452 /* end of vector table is a null pointer */ 453 if (suword(vectp, 0) != 0) 454 return (EFAULT); 455 456 if (imgp->auxargs) { 457 vectp++; 458 error = imgp->sysent->sv_copyout_auxargs(imgp, 459 (uintptr_t)vectp); 460 if (error != 0) 461 return (error); 462 } 463 464 return (0); 465 } 466 467 bool 468 linux_trans_osrel(const Elf_Note *note, int32_t *osrel) 469 { 470 const Elf32_Word *desc; 471 uintptr_t p; 472 473 p = (uintptr_t)(note + 1); 474 p += roundup2(note->n_namesz, sizeof(Elf32_Addr)); 475 476 desc = (const Elf32_Word *)p; 477 if (desc[0] != GNU_ABI_LINUX) 478 return (false); 479 /* 480 * For Linux we encode osrel using the Linux convention of 481 * (version << 16) | (major << 8) | (minor) 482 * See macro in linux_mib.h 483 */ 484 *osrel = LINUX_KERNVER(desc[1], desc[2], desc[3]); 485 486 return (true); 487 } 488 489 int 490 __linuxN(copyout_auxargs)(struct image_params *imgp, uintptr_t base) 491 { 492 struct thread *td = curthread; 493 Elf_Auxargs *args; 494 Elf_Auxinfo *aarray, *pos; 495 struct proc *p; 496 int error, issetugid; 497 498 p = imgp->proc; 499 issetugid = p->p_flag & P_SUGID ? 1 : 0; 500 args = imgp->auxargs; 501 aarray = pos = malloc(LINUX_AT_COUNT * sizeof(*pos), M_TEMP, 502 M_WAITOK | M_ZERO); 503 504 __linuxN(arch_copyout_auxargs)(imgp, &pos); 505 /* 506 * Do not export AT_CLKTCK when emulating Linux kernel prior to 2.4.0, 507 * as it has appeared in the 2.4.0-rc7 first time. 508 * Being exported, AT_CLKTCK is returned by sysconf(_SC_CLK_TCK), 509 * glibc falls back to the hard-coded CLK_TCK value when aux entry 510 * is not present. 511 * Also see linux_times() implementation. 512 */ 513 if (linux_kernver(td) >= LINUX_KERNVER(2,4,0)) 514 AUXARGS_ENTRY(pos, LINUX_AT_CLKTCK, stclohz); 515 AUXARGS_ENTRY(pos, AT_PAGESZ, args->pagesz); 516 AUXARGS_ENTRY(pos, AT_PHDR, args->phdr); 517 AUXARGS_ENTRY(pos, AT_PHENT, args->phent); 518 AUXARGS_ENTRY(pos, AT_PHNUM, args->phnum); 519 AUXARGS_ENTRY(pos, AT_BASE, args->base); 520 AUXARGS_ENTRY(pos, AT_FLAGS, args->flags); 521 AUXARGS_ENTRY(pos, AT_ENTRY, args->entry); 522 AUXARGS_ENTRY(pos, AT_UID, imgp->proc->p_ucred->cr_ruid); 523 AUXARGS_ENTRY(pos, AT_EUID, imgp->proc->p_ucred->cr_svuid); 524 AUXARGS_ENTRY(pos, AT_GID, imgp->proc->p_ucred->cr_rgid); 525 AUXARGS_ENTRY(pos, AT_EGID, imgp->proc->p_ucred->cr_svgid); 526 AUXARGS_ENTRY(pos, LINUX_AT_SECURE, issetugid); 527 if (linux_kernver(td) >= LINUX_KERNVER(2,6,30)) 528 AUXARGS_ENTRY_PTR(pos, LINUX_AT_RANDOM, imgp->canary); 529 if (linux_kernver(td) >= LINUX_KERNVER(2,6,26) && imgp->execpathp != 0) 530 AUXARGS_ENTRY(pos, LINUX_AT_EXECFN, PTROUT(imgp->execpathp)); 531 if (args->execfd != -1) 532 AUXARGS_ENTRY(pos, AT_EXECFD, args->execfd); 533 if (linux_kernver(td) >= LINUX_KERNVER(5,13,0)) 534 AUXARGS_ENTRY(pos, LINUX_AT_MINSIGSTKSZ, 535 imgp->sysent->sv_minsigstksz); 536 AUXARGS_ENTRY(pos, AT_NULL, 0); 537 538 free(imgp->auxargs, M_TEMP); 539 imgp->auxargs = NULL; 540 KASSERT(pos - aarray <= LINUX_AT_COUNT, ("Too many auxargs")); 541 542 error = copyout(aarray, PTRIN(base), sizeof(*aarray) * LINUX_AT_COUNT); 543 free(aarray, M_TEMP); 544 return (error); 545 } 546