Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 18 Oct 2021 13:02:52 +0200
From:      Marcin Wojtas <mw@semihalf.com>
To:        Cy Schubert <Cy.Schubert@cschubert.com>
Cc:        Marcin Wojtas <mw@freebsd.org>, src-committers <src-committers@freebsd.org>,  dev-commits-src-all@freebsd.org, dev-commits-src-main@freebsd.org
Subject:   Re: git: 889b56c8cd84 - main - setrlimit: Take stack gap into account.
Message-ID:  <CAPv3WKeP-xFMzwNDVTt9--k0LawzPe8uN8feEBRg_MjX2-Rv7A@mail.gmail.com>
In-Reply-To: <202110161602.19GG2FYs004292@slippy.cwsent.com>
References:  <202110150823.19F8NEr9047194@gitrepo.freebsd.org> <202110161602.19GG2FYs004292@slippy.cwsent.com>

next in thread | previous in thread | raw e-mail | index | archive | help
Hi Cy,



sob., 16 pa=C5=BA 2021 o 18:02 Cy Schubert <Cy.Schubert@cschubert.com> napi=
sa=C5=82(a):
>
> In message <202110150823.19F8NEr9047194@gitrepo.freebsd.org>, Marcin Wojt=
as
> wri
> tes:
> > The branch main has been updated by mw:
> >
> > URL: https://cgit.FreeBSD.org/src/commit/?id=3D889b56c8cd84c9a9f2d9e3b0=
19c154d6
> > f14d9021
> >
> > commit 889b56c8cd84c9a9f2d9e3b019c154d6f14d9021
> > Author:     Dawid Gorecki <dgr@semihalf.com>
> > AuthorDate: 2021-10-13 19:01:08 +0000
> > Commit:     Marcin Wojtas <mw@FreeBSD.org>
> > CommitDate: 2021-10-15 08:21:47 +0000
> >
> >     setrlimit: Take stack gap into account.
> >
> >     Calling setrlimit with stack gap enabled and with low values of sta=
ck
> >     resource limit often caused the program to abort immediately after
> >     exiting the syscall. This happened due to the fact that the resourc=
e
> >     limit was calculated assuming that the stack started at sv_usrstack=
,
> >     while with stack gap enabled the stack is moved by a random number
> >     of bytes.
> >
> >     Save information about stack size in struct vmspace and adjust the
> >     rlim_cur value. If the rlim_cur and stack gap is bigger than rlim_m=
ax,
> >     then the value is truncated to rlim_max.
> >
> >     PR: 253208
> >     Reviewed by: kib
> >     Obtained from: Semihalf
> >     Sponsored by: Stormshield
> >     MFC after: 1 month
> >     Differential Revision: https://reviews.freebsd.org/D31516
> > ---
> >  sys/kern/imgact_elf.c    |  5 +++--
> >  sys/kern/kern_exec.c     | 11 ++++++++---
> >  sys/kern/kern_resource.c |  3 +++
> >  sys/sys/imgact_elf.h     |  2 +-
> >  sys/sys/sysent.h         |  2 +-
> >  sys/vm/vm_map.c          |  2 ++
> >  sys/vm/vm_map.h          |  1 +
> >  7 files changed, 19 insertions(+), 7 deletions(-)
> >
> > diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c
> > index ef1edfcabaf0..898f0f66a532 100644
> > --- a/sys/kern/imgact_elf.c
> > +++ b/sys/kern/imgact_elf.c
> > @@ -2684,7 +2684,7 @@ __elfN(untrans_prot)(vm_prot_t prot)
> >       return (flags);
> >  }
> >
> > -void
> > +vm_size_t
> >  __elfN(stackgap)(struct image_params *imgp, uintptr_t *stack_base)
> >  {
> >       uintptr_t range, rbase, gap;
> > @@ -2692,7 +2692,7 @@ __elfN(stackgap)(struct image_params *imgp, uintp=
tr_t *
> > stack_base)
> >
> >       pct =3D __elfN(aslr_stack_gap);
> >       if (pct =3D=3D 0)
> > -             return;
> > +             return (0);
> >       if (pct > 50)
> >               pct =3D 50;
> >       range =3D imgp->eff_stack_sz * pct / 100;
> > @@ -2700,4 +2700,5 @@ __elfN(stackgap)(struct image_params *imgp, uintp=
tr_t *
> > stack_base)
> >       gap =3D rbase % range;
> >       gap &=3D ~(sizeof(u_long) - 1);
> >       *stack_base -=3D gap;
> > +     return (gap);
> >  }
> > diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c
> > index 50e75fda6cfb..9dceebdd8441 100644
> > --- a/sys/kern/kern_exec.c
> > +++ b/sys/kern/kern_exec.c
> > @@ -1148,6 +1148,7 @@ exec_new_vmspace(struct image_params *imgp, struc=
t syse
> > ntvec *sv)
> >                   stack_prot, error, vm_mmap_to_errno(error));
> >               return (vm_mmap_to_errno(error));
> >       }
> > +     vmspace->vm_stkgap =3D 0;
> >
> >       /*
> >        * vm_ssize and vm_maxsaddr are somewhat antiquated concepts, but=
 they
> > @@ -1493,12 +1494,16 @@ exec_args_get_begin_envv(struct image_args *arg=
s)
> >  void
> >  exec_stackgap(struct image_params *imgp, uintptr_t *dp)
> >  {
> > +     struct proc *p =3D imgp->proc;
> > +
> >       if (imgp->sysent->sv_stackgap =3D=3D NULL ||
> > -         (imgp->proc->p_fctl0 & (NT_FREEBSD_FCTL_ASLR_DISABLE |
> > +         (p->p_fctl0 & (NT_FREEBSD_FCTL_ASLR_DISABLE |
> >           NT_FREEBSD_FCTL_ASG_DISABLE)) !=3D 0 ||
> > -         (imgp->map_flags & MAP_ASLR) =3D=3D 0)
> > +         (imgp->map_flags & MAP_ASLR) =3D=3D 0) {
> > +             p->p_vmspace->vm_stkgap =3D 0;
> >               return;
> > -     imgp->sysent->sv_stackgap(imgp, dp);
> > +     }
> > +     p->p_vmspace->vm_stkgap =3D imgp->sysent->sv_stackgap(imgp, dp);
> >  }
> >
> >  /*
> > diff --git a/sys/kern/kern_resource.c b/sys/kern/kern_resource.c
> > index 4c62961e1bc4..b556d4fded51 100644
> > --- a/sys/kern/kern_resource.c
> > +++ b/sys/kern/kern_resource.c
> > @@ -671,6 +671,9 @@ kern_proc_setrlimit(struct thread *td, struct proc =
*p, u_
> > int which,
> >       if (limp->rlim_max < 0)
> >               limp->rlim_max =3D RLIM_INFINITY;
> >
> > +     if (which =3D=3D RLIMIT_STACK && limp->rlim_cur !=3D RLIM_INFINIT=
Y)
> > +             limp->rlim_cur +=3D p->p_vmspace->vm_stkgap;
> > +
> >       oldssiz.rlim_cur =3D 0;
> >       newlim =3D lim_alloc();
> >       PROC_LOCK(p);
> > diff --git a/sys/sys/imgact_elf.h b/sys/sys/imgact_elf.h
> > index 97383c6eeeb8..294f17c87b6f 100644
> > --- a/sys/sys/imgact_elf.h
> > +++ b/sys/sys/imgact_elf.h
> > @@ -118,7 +118,7 @@ int       __elfN(remove_brand_entry)(Elf_Brandinfo =
*entry
> > );
> >  int  __elfN(freebsd_fixup)(uintptr_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 *, uintptr_t *);
> > +vm_size_t    __elfN(stackgap)(struct image_params *, uintptr_t *);
> >  int  __elfN(freebsd_copyout_auxargs)(struct image_params *, uintptr_t)=
;
> >  void __elfN(puthdr)(struct thread *, void *, size_t, int, size_t, int)=
;
> >  void __elfN(prepare_notes)(struct thread *, struct note_info_list *,
> > diff --git a/sys/sys/sysent.h b/sys/sys/sysent.h
> > index ad50bf56e87d..ea96c87a79af 100644
> > --- a/sys/sys/sysent.h
> > +++ b/sys/sys/sysent.h
> > @@ -119,7 +119,7 @@ struct sysentvec {
> >       void            (*sv_elf_core_prepare_notes)(struct thread *,
> >                           struct note_info_list *, size_t *);
> >       int             (*sv_imgact_try)(struct image_params *);
> > -     void            (*sv_stackgap)(struct image_params *, uintptr_t *=
);
> > +     vm_size_t       (*sv_stackgap)(struct image_params *, uintptr_t *=
);
> >       int             (*sv_copyout_auxargs)(struct image_params *,
> >                           uintptr_t);
> >       int             sv_minsigstksz; /* minimum signal stack size */
> > diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
> > index 1ac4ccf72f11..87a290b998b9 100644
> > --- a/sys/vm/vm_map.c
> > +++ b/sys/vm/vm_map.c
> > @@ -343,6 +343,7 @@ vmspace_alloc(vm_offset_t min, vm_offset_t max, pma=
p_pini
> > t_t pinit)
> >       vm->vm_taddr =3D 0;
> >       vm->vm_daddr =3D 0;
> >       vm->vm_maxsaddr =3D 0;
> > +     vm->vm_stkgap =3D 0;
> >       return (vm);
> >  }
> >
> > @@ -4265,6 +4266,7 @@ vmspace_fork(struct vmspace *vm1, vm_ooffset_t *f=
ork_ch
> > arge)
> >       vm2->vm_taddr =3D vm1->vm_taddr;
> >       vm2->vm_daddr =3D vm1->vm_daddr;
> >       vm2->vm_maxsaddr =3D vm1->vm_maxsaddr;
> > +     vm2->vm_stkgap =3D vm1->vm_stkgap;
> >       vm_map_lock(old_map);
> >       if (old_map->busy)
> >               vm_map_wait_busy(old_map);
> > diff --git a/sys/vm/vm_map.h b/sys/vm/vm_map.h
> > index ace205b21b42..873ff62eec4a 100644
> > --- a/sys/vm/vm_map.h
> > +++ b/sys/vm/vm_map.h
> > @@ -293,6 +293,7 @@ struct vmspace {
> >       caddr_t vm_taddr;       /* (c) user virtual address of text */
> >       caddr_t vm_daddr;       /* (c) user virtual address of data */
> >       caddr_t vm_maxsaddr;    /* user VA at max stack growth */
> > +     vm_size_t vm_stkgap;    /* stack gap size in bytes */
> >       u_int vm_refcnt;        /* number of references */
> >       /*
> >        * Keep the PMAP last, so that CPU-specific variations of that
> >
>
> Is it possible to have a __FreeBSD_version bump for ports?
>
>

At a first glance I don't see the ports' global versioning apart from
creating tags, but maybe ports' maintainers will have more insight.

Best regards,
Marcin



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAPv3WKeP-xFMzwNDVTt9--k0LawzPe8uN8feEBRg_MjX2-Rv7A>