Print this page
Merge hell test

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/exec/elf/elf.c
          +++ new/usr/src/uts/common/exec/elf/elf.c
↓ open down ↓ 19 lines elided ↑ open up ↑
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
  24   24   */
  25   25  
  26   26  /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
  27   27  /*         All Rights Reserved  */
  28   28  /*
  29   29   * Copyright 2019 Joyent, Inc.
       30 + * Copyright 2021 Oxide Computer Company
  30   31   */
  31   32  
  32   33  #include <sys/types.h>
  33   34  #include <sys/param.h>
  34   35  #include <sys/thread.h>
  35   36  #include <sys/sysmacros.h>
  36   37  #include <sys/signal.h>
  37   38  #include <sys/cred.h>
  38   39  #include <sys/user.h>
  39   40  #include <sys/errno.h>
↓ open down ↓ 47 lines elided ↑ open up ↑
  87   88  static int getelfshdr(vnode_t *, cred_t *, const Ehdr *, uint_t, uint_t,
  88   89      caddr_t *, size_t *, caddr_t *, size_t *);
  89   90  static size_t elfsize(const Ehdr *, uint_t, const caddr_t, uintptr_t *);
  90   91  static int mapelfexec(vnode_t *, Ehdr *, uint_t, caddr_t, Phdr **, Phdr **,
  91   92      Phdr **, Phdr **, Phdr *, caddr_t *, caddr_t *, intptr_t *, uintptr_t *,
  92   93      size_t, size_t *, size_t *);
  93   94  
  94   95  #ifdef _ELF32_COMPAT
  95   96  /* Link against the non-compat instances when compiling the 32-bit version. */
  96   97  extern size_t elf_datasz_max;
       98 +extern size_t elf_zeropg_sz;
  97   99  extern void elf_ctx_resize_scratch(elf_core_ctx_t *, size_t);
  98  100  extern uint_t elf_nphdr_max;
  99  101  extern uint_t elf_nshdr_max;
 100  102  extern size_t elf_shstrtab_max;
 101  103  #else
 102  104  size_t elf_datasz_max = 1 * 1024 * 1024;
      105 +size_t elf_zeropg_sz = 4 * 1024;
 103  106  uint_t elf_nphdr_max = 1000;
 104  107  uint_t elf_nshdr_max = 10000;
 105  108  size_t elf_shstrtab_max = 100 * 1024;
 106  109  #endif
 107  110  
 108  111  
 109  112  
 110  113  typedef enum {
 111  114          STR_CTF,
 112  115          STR_SYMTAB,
↓ open down ↓ 2144 lines elided ↑ open up ↑
2257 2260  
2258 2261  int
2259 2262  elfcore(vnode_t *vp, proc_t *p, cred_t *credp, rlim64_t rlimit, int sig,
2260 2263      core_content_t content)
2261 2264  {
2262 2265          u_offset_t poffset, soffset, doffset;
2263 2266          int error;
2264 2267          uint_t i, nphdrs, nshdrs;
2265 2268          struct seg *seg;
2266 2269          struct as *as = p->p_as;
2267      -        void *bigwad;
     2270 +        void *bigwad, *zeropg = NULL;
2268 2271          size_t bigsize, phdrsz, shdrsz;
2269 2272          Ehdr *ehdr;
2270 2273          Phdr *phdr;
2271 2274          Shdr shdr0;
2272 2275          caddr_t brkbase, stkbase;
2273 2276          size_t brksize, stksize;
2274 2277          boolean_t overflowed = B_FALSE, retried = B_FALSE;
2275 2278          klwp_t *lwp = ttolwp(curthread);
2276 2279          elf_core_ctx_t ctx = {
2277 2280                  .ecc_vp = vp,
↓ open down ↓ 291 lines elided ↑ open up ↑
2569 2572  
2570 2573          for (i = 2; i < nphdrs; i++) {
2571 2574                  prkillinfo_t killinfo;
2572 2575                  sigqueue_t *sq;
2573 2576                  int sig, j;
2574 2577  
2575 2578                  if (phdr[i].p_filesz == 0)
2576 2579                          continue;
2577 2580  
2578 2581                  /*
     2582 +                 * If we hit a region that was mapped PROT_NONE then we cannot
     2583 +                 * continue dumping this normally as the kernel would be unable
     2584 +                 * to read from the page and that would result in us failing to
     2585 +                 * dump the page. As such, any region mapped PROT_NONE, we dump
     2586 +                 * as a zero-filled page such that this is still represented in
     2587 +                 * the map.
     2588 +                 *
2579 2589                   * If dumping out this segment fails, rather than failing
2580 2590                   * the core dump entirely, we reset the size of the mapping
2581 2591                   * to zero to indicate that the data is absent from the core
2582 2592                   * file and or in the PF_SUNW_FAILURE flag to differentiate
2583 2593                   * this from mappings that were excluded due to the core file
2584 2594                   * content settings.
2585 2595                   */
2586      -                if ((error = core_seg(p, vp, phdr[i].p_offset,
2587      -                    (caddr_t)(uintptr_t)phdr[i].p_vaddr, phdr[i].p_filesz,
2588      -                    rlimit, credp)) == 0) {
2589      -                        continue;
     2596 +                if ((phdr[i].p_flags & (PF_R | PF_W | PF_X)) == 0) {
     2597 +                        size_t towrite = phdr[i].p_filesz;
     2598 +                        size_t curoff = 0;
     2599 +
     2600 +                        if (zeropg == NULL) {
     2601 +                                zeropg = kmem_zalloc(elf_zeropg_sz, KM_SLEEP);
     2602 +                        }
     2603 +
     2604 +                        error = 0;
     2605 +                        while (towrite != 0) {
     2606 +                                size_t len = MIN(towrite, elf_zeropg_sz);
     2607 +
     2608 +                                error = core_write(vp, UIO_SYSSPACE,
     2609 +                                    phdr[i].p_offset + curoff, zeropg, len,
     2610 +                                    rlimit, credp);
     2611 +                                if (error != 0)
     2612 +                                        break;
     2613 +
     2614 +                                towrite -= len;
     2615 +                                curoff += len;
     2616 +                        }
     2617 +                } else {
     2618 +                        error = core_seg(p, vp, phdr[i].p_offset,
     2619 +                            (caddr_t)(uintptr_t)phdr[i].p_vaddr,
     2620 +                            phdr[i].p_filesz, rlimit, credp);
2590 2621                  }
     2622 +                if (error == 0)
     2623 +                        continue;
2591 2624  
2592 2625                  if ((sig = lwp->lwp_cursig) == 0) {
2593 2626                          /*
2594 2627                           * We failed due to something other than a signal.
2595 2628                           * Since the space reserved for the segment is now
2596 2629                           * unused, we stash the errno in the first four
2597 2630                           * bytes. This undocumented interface will let us
2598 2631                           * understand the nature of the failure.
2599 2632                           */
2600 2633                          (void) core_write(vp, UIO_SYSSPACE, phdr[i].p_offset,
↓ open down ↓ 175 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX