Print this page
Merge hell test


  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
  24  */
  25 
  26 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T     */
  27 /*         All Rights Reserved  */
  28 /*
  29  * Copyright 2019 Joyent, Inc.

  30  */
  31 
  32 #include <sys/types.h>
  33 #include <sys/param.h>
  34 #include <sys/thread.h>
  35 #include <sys/sysmacros.h>
  36 #include <sys/signal.h>
  37 #include <sys/cred.h>
  38 #include <sys/user.h>
  39 #include <sys/errno.h>
  40 #include <sys/vnode.h>
  41 #include <sys/mman.h>
  42 #include <sys/kmem.h>
  43 #include <sys/proc.h>
  44 #include <sys/pathname.h>
  45 #include <sys/policy.h>
  46 #include <sys/cmn_err.h>
  47 #include <sys/systm.h>
  48 #include <sys/elf.h>
  49 #include <sys/vmsystm.h>


  77 extern int at_flags;
  78 extern volatile size_t aslr_max_brk_skew;
  79 
  80 #define ORIGIN_STR      "ORIGIN"
  81 #define ORIGIN_STR_SIZE 6
  82 
  83 static int getelfhead(vnode_t *, cred_t *, Ehdr *, uint_t *, uint_t *,
  84     uint_t *);
  85 static int getelfphdr(vnode_t *, cred_t *, const Ehdr *, uint_t, caddr_t *,
  86     size_t *);
  87 static int getelfshdr(vnode_t *, cred_t *, const Ehdr *, uint_t, uint_t,
  88     caddr_t *, size_t *, caddr_t *, size_t *);
  89 static size_t elfsize(const Ehdr *, uint_t, const caddr_t, uintptr_t *);
  90 static int mapelfexec(vnode_t *, Ehdr *, uint_t, caddr_t, Phdr **, Phdr **,
  91     Phdr **, Phdr **, Phdr *, caddr_t *, caddr_t *, intptr_t *, uintptr_t *,
  92     size_t, size_t *, size_t *);
  93 
  94 #ifdef _ELF32_COMPAT
  95 /* Link against the non-compat instances when compiling the 32-bit version. */
  96 extern size_t elf_datasz_max;

  97 extern void elf_ctx_resize_scratch(elf_core_ctx_t *, size_t);
  98 extern uint_t elf_nphdr_max;
  99 extern uint_t elf_nshdr_max;
 100 extern size_t elf_shstrtab_max;
 101 #else
 102 size_t elf_datasz_max = 1 * 1024 * 1024;

 103 uint_t elf_nphdr_max = 1000;
 104 uint_t elf_nshdr_max = 10000;
 105 size_t elf_shstrtab_max = 100 * 1024;
 106 #endif
 107 
 108 
 109 
 110 typedef enum {
 111         STR_CTF,
 112         STR_SYMTAB,
 113         STR_DYNSYM,
 114         STR_STRTAB,
 115         STR_DYNSTR,
 116         STR_SHSTRTAB,
 117         STR_NUM
 118 } shstrtype_t;
 119 
 120 static const char *shstrtab_data[] = {
 121         ".SUNW_ctf",
 122         ".symtab",


2247         shstrtab_dump(&shstrtab, ctx->ecc_buf);
2248 
2249         error = core_write(ctx->ecc_vp, UIO_SYSSPACE, ctx->ecc_doffset,
2250             ctx->ecc_buf, v[idx].sh_size, ctx->ecc_rlimit, ctx->ecc_credp);
2251         if (error == 0) {
2252                 ctx->ecc_doffset += v[idx].sh_size;
2253         }
2254 
2255         return (error);
2256 }
2257 
2258 int
2259 elfcore(vnode_t *vp, proc_t *p, cred_t *credp, rlim64_t rlimit, int sig,
2260     core_content_t content)
2261 {
2262         u_offset_t poffset, soffset, doffset;
2263         int error;
2264         uint_t i, nphdrs, nshdrs;
2265         struct seg *seg;
2266         struct as *as = p->p_as;
2267         void *bigwad;
2268         size_t bigsize, phdrsz, shdrsz;
2269         Ehdr *ehdr;
2270         Phdr *phdr;
2271         Shdr shdr0;
2272         caddr_t brkbase, stkbase;
2273         size_t brksize, stksize;
2274         boolean_t overflowed = B_FALSE, retried = B_FALSE;
2275         klwp_t *lwp = ttolwp(curthread);
2276         elf_core_ctx_t ctx = {
2277                 .ecc_vp = vp,
2278                 .ecc_p = p,
2279                 .ecc_credp = credp,
2280                 .ecc_rlimit = rlimit,
2281                 .ecc_content = content,
2282                 .ecc_doffset = 0,
2283                 .ecc_buf = NULL,
2284                 .ecc_bufsz = 0
2285         };
2286 
2287 top:


2559         }
2560 
2561         if ((error = write_old_elfnotes(p, sig, vp, phdr[0].p_offset, rlimit,
2562             credp)) != 0) {
2563                 goto done;
2564         }
2565         if ((error = write_elfnotes(p, sig, vp, phdr[1].p_offset, rlimit,
2566             credp, content)) != 0) {
2567                 goto done;
2568         }
2569 
2570         for (i = 2; i < nphdrs; i++) {
2571                 prkillinfo_t killinfo;
2572                 sigqueue_t *sq;
2573                 int sig, j;
2574 
2575                 if (phdr[i].p_filesz == 0)
2576                         continue;
2577 
2578                 /*







2579                  * If dumping out this segment fails, rather than failing
2580                  * the core dump entirely, we reset the size of the mapping
2581                  * to zero to indicate that the data is absent from the core
2582                  * file and or in the PF_SUNW_FAILURE flag to differentiate
2583                  * this from mappings that were excluded due to the core file
2584                  * content settings.
2585                  */
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;


2590                 }
2591 





















2592                 if ((sig = lwp->lwp_cursig) == 0) {
2593                         /*
2594                          * We failed due to something other than a signal.
2595                          * Since the space reserved for the segment is now
2596                          * unused, we stash the errno in the first four
2597                          * bytes. This undocumented interface will let us
2598                          * understand the nature of the failure.
2599                          */
2600                         (void) core_write(vp, UIO_SYSSPACE, phdr[i].p_offset,
2601                             &error, sizeof (error), rlimit, credp);
2602 
2603                         phdr[i].p_filesz = 0;
2604                         phdr[i].p_flags |= PF_SUNW_FAILURE;
2605                         if ((error = core_write(vp, UIO_SYSSPACE,
2606                             poffset + sizeof (Phdr) * i, &phdr[i],
2607                             sizeof (Phdr), rlimit, credp)) != 0)
2608                                 goto done;
2609 
2610                         continue;
2611                 }




  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
  24  */
  25 
  26 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T     */
  27 /*         All Rights Reserved  */
  28 /*
  29  * Copyright 2019 Joyent, Inc.
  30  * Copyright 2021 Oxide Computer Company
  31  */
  32 
  33 #include <sys/types.h>
  34 #include <sys/param.h>
  35 #include <sys/thread.h>
  36 #include <sys/sysmacros.h>
  37 #include <sys/signal.h>
  38 #include <sys/cred.h>
  39 #include <sys/user.h>
  40 #include <sys/errno.h>
  41 #include <sys/vnode.h>
  42 #include <sys/mman.h>
  43 #include <sys/kmem.h>
  44 #include <sys/proc.h>
  45 #include <sys/pathname.h>
  46 #include <sys/policy.h>
  47 #include <sys/cmn_err.h>
  48 #include <sys/systm.h>
  49 #include <sys/elf.h>
  50 #include <sys/vmsystm.h>


  78 extern int at_flags;
  79 extern volatile size_t aslr_max_brk_skew;
  80 
  81 #define ORIGIN_STR      "ORIGIN"
  82 #define ORIGIN_STR_SIZE 6
  83 
  84 static int getelfhead(vnode_t *, cred_t *, Ehdr *, uint_t *, uint_t *,
  85     uint_t *);
  86 static int getelfphdr(vnode_t *, cred_t *, const Ehdr *, uint_t, caddr_t *,
  87     size_t *);
  88 static int getelfshdr(vnode_t *, cred_t *, const Ehdr *, uint_t, uint_t,
  89     caddr_t *, size_t *, caddr_t *, size_t *);
  90 static size_t elfsize(const Ehdr *, uint_t, const caddr_t, uintptr_t *);
  91 static int mapelfexec(vnode_t *, Ehdr *, uint_t, caddr_t, Phdr **, Phdr **,
  92     Phdr **, Phdr **, Phdr *, caddr_t *, caddr_t *, intptr_t *, uintptr_t *,
  93     size_t, size_t *, size_t *);
  94 
  95 #ifdef _ELF32_COMPAT
  96 /* Link against the non-compat instances when compiling the 32-bit version. */
  97 extern size_t elf_datasz_max;
  98 extern size_t elf_zeropg_sz;
  99 extern void elf_ctx_resize_scratch(elf_core_ctx_t *, size_t);
 100 extern uint_t elf_nphdr_max;
 101 extern uint_t elf_nshdr_max;
 102 extern size_t elf_shstrtab_max;
 103 #else
 104 size_t elf_datasz_max = 1 * 1024 * 1024;
 105 size_t elf_zeropg_sz = 4 * 1024;
 106 uint_t elf_nphdr_max = 1000;
 107 uint_t elf_nshdr_max = 10000;
 108 size_t elf_shstrtab_max = 100 * 1024;
 109 #endif
 110 
 111 
 112 
 113 typedef enum {
 114         STR_CTF,
 115         STR_SYMTAB,
 116         STR_DYNSYM,
 117         STR_STRTAB,
 118         STR_DYNSTR,
 119         STR_SHSTRTAB,
 120         STR_NUM
 121 } shstrtype_t;
 122 
 123 static const char *shstrtab_data[] = {
 124         ".SUNW_ctf",
 125         ".symtab",


2250         shstrtab_dump(&shstrtab, ctx->ecc_buf);
2251 
2252         error = core_write(ctx->ecc_vp, UIO_SYSSPACE, ctx->ecc_doffset,
2253             ctx->ecc_buf, v[idx].sh_size, ctx->ecc_rlimit, ctx->ecc_credp);
2254         if (error == 0) {
2255                 ctx->ecc_doffset += v[idx].sh_size;
2256         }
2257 
2258         return (error);
2259 }
2260 
2261 int
2262 elfcore(vnode_t *vp, proc_t *p, cred_t *credp, rlim64_t rlimit, int sig,
2263     core_content_t content)
2264 {
2265         u_offset_t poffset, soffset, doffset;
2266         int error;
2267         uint_t i, nphdrs, nshdrs;
2268         struct seg *seg;
2269         struct as *as = p->p_as;
2270         void *bigwad, *zeropg = NULL;
2271         size_t bigsize, phdrsz, shdrsz;
2272         Ehdr *ehdr;
2273         Phdr *phdr;
2274         Shdr shdr0;
2275         caddr_t brkbase, stkbase;
2276         size_t brksize, stksize;
2277         boolean_t overflowed = B_FALSE, retried = B_FALSE;
2278         klwp_t *lwp = ttolwp(curthread);
2279         elf_core_ctx_t ctx = {
2280                 .ecc_vp = vp,
2281                 .ecc_p = p,
2282                 .ecc_credp = credp,
2283                 .ecc_rlimit = rlimit,
2284                 .ecc_content = content,
2285                 .ecc_doffset = 0,
2286                 .ecc_buf = NULL,
2287                 .ecc_bufsz = 0
2288         };
2289 
2290 top:


2562         }
2563 
2564         if ((error = write_old_elfnotes(p, sig, vp, phdr[0].p_offset, rlimit,
2565             credp)) != 0) {
2566                 goto done;
2567         }
2568         if ((error = write_elfnotes(p, sig, vp, phdr[1].p_offset, rlimit,
2569             credp, content)) != 0) {
2570                 goto done;
2571         }
2572 
2573         for (i = 2; i < nphdrs; i++) {
2574                 prkillinfo_t killinfo;
2575                 sigqueue_t *sq;
2576                 int sig, j;
2577 
2578                 if (phdr[i].p_filesz == 0)
2579                         continue;
2580 
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                  *
2589                  * If dumping out this segment fails, rather than failing
2590                  * the core dump entirely, we reset the size of the mapping
2591                  * to zero to indicate that the data is absent from the core
2592                  * file and or in the PF_SUNW_FAILURE flag to differentiate
2593                  * this from mappings that were excluded due to the core file
2594                  * content settings.
2595                  */
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);
2621                 }
2622                 if (error == 0)
2623                         continue;
2624 
2625                 if ((sig = lwp->lwp_cursig) == 0) {
2626                         /*
2627                          * We failed due to something other than a signal.
2628                          * Since the space reserved for the segment is now
2629                          * unused, we stash the errno in the first four
2630                          * bytes. This undocumented interface will let us
2631                          * understand the nature of the failure.
2632                          */
2633                         (void) core_write(vp, UIO_SYSSPACE, phdr[i].p_offset,
2634                             &error, sizeof (error), rlimit, credp);
2635 
2636                         phdr[i].p_filesz = 0;
2637                         phdr[i].p_flags |= PF_SUNW_FAILURE;
2638                         if ((error = core_write(vp, UIO_SYSSPACE,
2639                             poffset + sizeof (Phdr) * i, &phdr[i],
2640                             sizeof (Phdr), rlimit, credp)) != 0)
2641                                 goto done;
2642 
2643                         continue;
2644                 }