Author: kib
Date: Wed Aug 14 09:56:58 2019
New Revision: 351024
URL: https://svnweb.freebsd.org/changeset/base/351024

Log:
  MFC r350484, r350607, r350608:
  Make randomized stack gap between strings and pointers to argv/envs.

Modified:
  stable/12/sys/amd64/amd64/elf_machdep.c
  stable/12/sys/compat/freebsd32/freebsd32_misc.c
  stable/12/sys/compat/ia32/ia32_sysvec.c
  stable/12/sys/kern/imgact_elf.c
  stable/12/sys/kern/kern_exec.c
  stable/12/sys/sys/imgact.h
  stable/12/sys/sys/imgact_elf.h
  stable/12/sys/sys/sysent.h
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/amd64/amd64/elf_machdep.c
==============================================================================
--- stable/12/sys/amd64/amd64/elf_machdep.c     Wed Aug 14 09:53:30 2019        
(r351023)
+++ stable/12/sys/amd64/amd64/elf_machdep.c     Wed Aug 14 09:56:58 2019        
(r351024)
@@ -83,6 +83,7 @@ struct sysentvec elf64_freebsd_sysvec = {
        .sv_schedtail   = NULL,
        .sv_thread_detach = NULL,
        .sv_trap        = NULL,
+       .sv_stackgap    = elf64_stackgap,
 };
 INIT_SYSENTVEC(elf64_sysvec, &elf64_freebsd_sysvec);
 

Modified: stable/12/sys/compat/freebsd32/freebsd32_misc.c
==============================================================================
--- stable/12/sys/compat/freebsd32/freebsd32_misc.c     Wed Aug 14 09:53:30 
2019        (r351023)
+++ stable/12/sys/compat/freebsd32/freebsd32_misc.c     Wed Aug 14 09:56:58 
2019        (r351024)
@@ -3189,6 +3189,9 @@ freebsd32_copyout_strings(struct image_params *imgp)
        destp = rounddown2(destp, sizeof(uint32_t));
 
        vectp = (uint32_t *)destp;
+       if (imgp->sysent->sv_stackgap != NULL)
+               imgp->sysent->sv_stackgap(imgp, (u_long *)&vectp);
+
        if (imgp->auxargs) {
                /*
                 * Allocate room on the stack for the ELF auxargs

Modified: stable/12/sys/compat/ia32/ia32_sysvec.c
==============================================================================
--- stable/12/sys/compat/ia32/ia32_sysvec.c     Wed Aug 14 09:53:30 2019        
(r351023)
+++ stable/12/sys/compat/ia32/ia32_sysvec.c     Wed Aug 14 09:56:58 2019        
(r351024)
@@ -129,6 +129,7 @@ struct sysentvec ia32_freebsd_sysvec = {
        .sv_schedtail   = NULL,
        .sv_thread_detach = NULL,
        .sv_trap        = NULL,
+       .sv_stackgap    = elf32_stackgap,
 };
 INIT_SYSENTVEC(elf_ia32_sysvec, &ia32_freebsd_sysvec);
 

Modified: stable/12/sys/kern/imgact_elf.c
==============================================================================
--- stable/12/sys/kern/imgact_elf.c     Wed Aug 14 09:53:30 2019        
(r351023)
+++ stable/12/sys/kern/imgact_elf.c     Wed Aug 14 09:56:58 2019        
(r351024)
@@ -157,6 +157,12 @@ SYSCTL_INT(ASLR_NODE_OID, OID_AUTO, honor_sbrk, CTLFLA
     &__elfN(aslr_honor_sbrk), 0,
     __XSTRING(__CONCAT(ELF, __ELF_WORD_SIZE)) ": assume sbrk is used");
 
+static int __elfN(aslr_stack_gap) = 3;
+SYSCTL_INT(ASLR_NODE_OID, OID_AUTO, stack_gap, CTLFLAG_RW,
+    &__elfN(aslr_stack_gap), 0,
+    __XSTRING(__CONCAT(ELF, __ELF_WORD_SIZE))
+    ": maximum percentage of main stack to waste on a random gap");
+
 static Elf_Brandinfo *elf_brand_list[MAX_BRANDS];
 
 #define        aligned(a, t)   (rounddown2((u_long)(a), sizeof(t)) == 
(u_long)(a))
@@ -2723,4 +2729,24 @@ __elfN(untrans_prot)(vm_prot_t prot)
        if (prot & VM_PROT_WRITE)
                flags |= PF_W;
        return (flags);
+}
+
+void
+__elfN(stackgap)(struct image_params *imgp, u_long *stack_base)
+{
+       u_long range, rbase, gap;
+       int pct;
+
+       if ((imgp->map_flags & MAP_ASLR) == 0)
+               return;
+       pct = __elfN(aslr_stack_gap);
+       if (pct == 0)
+               return;
+       if (pct > 50)
+               pct = 50;
+       range = imgp->eff_stack_sz * pct / 100;
+       arc4rand(&rbase, sizeof(rbase), 0);
+       gap = rbase % range;
+       gap &= ~(sizeof(u_long) - 1);
+       *stack_base -= gap;
 }

Modified: stable/12/sys/kern/kern_exec.c
==============================================================================
--- stable/12/sys/kern/kern_exec.c      Wed Aug 14 09:53:30 2019        
(r351023)
+++ stable/12/sys/kern/kern_exec.c      Wed Aug 14 09:56:58 2019        
(r351024)
@@ -1144,6 +1144,9 @@ exec_new_vmspace(struct image_params *imgp, struct sys
        } else {
                ssiz = maxssiz;
        }
+       imgp->eff_stack_sz = lim_cur(curthread, RLIMIT_STACK);
+       if (ssiz < imgp->eff_stack_sz)
+               imgp->eff_stack_sz = ssiz;
        stack_addr = sv->sv_usrstack - ssiz;
        error = vm_map_stack(map, stack_addr, (vm_size_t)ssiz,
            obj != NULL && imgp->stack_prot != 0 ? imgp->stack_prot :
@@ -1538,6 +1541,9 @@ exec_copyout_strings(struct image_params *imgp)
        destp = rounddown2(destp, sizeof(void *));
 
        vectp = (char **)destp;
+       if (imgp->sysent->sv_stackgap != NULL)
+               imgp->sysent->sv_stackgap(imgp, (u_long *)&vectp);
+
        if (imgp->auxargs) {
                /*
                 * Allocate room on the stack for the ELF auxargs

Modified: stable/12/sys/sys/imgact.h
==============================================================================
--- stable/12/sys/sys/imgact.h  Wed Aug 14 09:53:30 2019        (r351023)
+++ stable/12/sys/sys/imgact.h  Wed Aug 14 09:56:58 2019        (r351024)
@@ -86,6 +86,7 @@ struct image_params {
        int pagesizeslen;
        vm_prot_t stack_prot;
        u_long stack_sz;
+       u_long eff_stack_sz;
        struct ucred *newcred;          /* new credentials if changing */
        bool credential_setid;          /* true if becoming setid */
        bool textset;

Modified: stable/12/sys/sys/imgact_elf.h
==============================================================================
--- stable/12/sys/sys/imgact_elf.h      Wed Aug 14 09:53:30 2019        
(r351023)
+++ stable/12/sys/sys/imgact_elf.h      Wed Aug 14 09:56:58 2019        
(r351024)
@@ -98,6 +98,7 @@ int   __elfN(remove_brand_entry)(Elf_Brandinfo *entry);
 int    __elfN(freebsd_fixup)(register_t **, struct image_params *);
 int    __elfN(coredump)(struct thread *, struct vnode *, off_t, int);
 size_t __elfN(populate_note)(int, void *, void *, size_t, void **);
+void   __elfN(stackgap)(struct image_params *, u_long *);
 
 /* Machine specific function to dump per-thread information. */
 void   __elfN(dump_thread)(struct thread *, void *, size_t *);

Modified: stable/12/sys/sys/sysent.h
==============================================================================
--- stable/12/sys/sys/sysent.h  Wed Aug 14 09:53:30 2019        (r351023)
+++ stable/12/sys/sys/sysent.h  Wed Aug 14 09:56:58 2019        (r351024)
@@ -110,6 +110,7 @@ struct sysentvec {
        int             (*sv_coredump)(struct thread *, struct vnode *, off_t, 
int);
                                        /* function to dump core, or NULL */
        int             (*sv_imgact_try)(struct image_params *);
+       void            (*sv_stackgap)(struct image_params *, u_long *);
        int             sv_minsigstksz; /* minimum signal stack size */
        int             sv_pagesize;    /* spare / no longer used */
        vm_offset_t     sv_minuser;     /* VM_MIN_ADDRESS */
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to