Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 6 Sep 2019 10:51:46 -0700
From:      Harlan Stenn <stenn@nwtime.org>
To:        Cy Schubert <Cy.Schubert@cschubert.com>, =?UTF-8?Q?Trond_Endrest=c3=b8l?= <trond.endrestol@ximalas.info>
Cc:        freebsd-stable@freebsd.org
Subject:   Re: ntpd doesn't like ASLR on stable/12 post-r350672
Message-ID:  <9b0c95de-2d0e-89b4-32e6-63ec5af729b4@nwtime.org>
In-Reply-To: <201909060639.x866dL68090189@slippy.cwsent.com>
References:  <alpine.BSF.2.21.99999.352.1908242135380.6386@enterprise.ximalas.info> <201909060639.x866dL68090189@slippy.cwsent.com>

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

It's easy for us to customize the default value for DFLT_RLIMIT_STACK on
a per-version and per-OS basis.  We do this in the "configure" machinery.

The defaults are expected to be "generally sane", and were likely chosen
a relatively long time ago.

What would you like the value(s) to be for what versions of FreeBSD?

H

On 9/5/2019 11:39 PM, Cy Schubert wrote:
> In message <alpine.BSF.2.21.99999.352.1908242135380.6386@enterprise.ximalas.
> inf
> o>, =?UTF-8?Q?Trond_Endrest=C3=B8l?= writes:
>> Hi,
>>
>> I'm running stable/12 with ASLR enabled in /etc/sysctl.conf:
>>
>> kern.elf64.aslr.enable=1
>> kern.elf64.aslr.pie_enable=1
>> kern.elf32.aslr.enable=1
>> kern.elf32.aslr.pie_enable=1
>>
>> After upgrading to anything after r350672, now at r351450, ntpd 
>> refuses to start at boot.
>>
>> Aug 24 21:25:42 <ntp.notice> HOSTNAME ntpd[5618]: ntpd 4.2.8p12-a (1): Starti
>> ng
>> Aug 24 21:25:43 <kern.info> HOSTNAME kernel: [406] pid 5619 (ntpd), jid 0, ui
>> d 123: exited on signal 11
>>
>> Disabling ASLR, kern.elf64.aslr.enable=0, before starting ntpd 
>> manually is a workaround, but this is not viable in the long run.
>>
>> I tried changing command="/usr/sbin/${name}" to 
>> command="/usr/bin/proccontrol -m aslr -s disable /usr/sbin/${name}" in 
>> /etc/rc.d/ntpd, but that didn't go well.
> 
> For now, until this can be solved, add this to your rc.conf:
> 
> ntpd_prepend="/usr/bin/proccontrol -m aslr -s disable"
> 
>>
>> Running ntpd through gdb while ASLR was enabled, I narrowed it down to
>> /usr/src/contrib/ntp/ntpd/ntpd.c:1001
>>
>>   ntp_rlimit(RLIMIT_STACK, DFLT_RLIMIT_STACK * 4096, 4096, "4k");
>>
>> which calls /usr/src/contrib/ntp/ntpd/ntp_config.c:5211 and proceeds 
>> to /usr/src/contrib/ntp/ntpd/ntp_config.c:5254
>>
>>   if (-1 == getrlimit(RLIMIT_STACK, &rl)) {
>>
>> Single stepping from this point gave me:
>>
>> ====
>>
>> (gdb) s
>> _thr_rtld_set_flag (mask=1) at /usr/src/lib/libthr/thread/thr_rtld.c:171
>> 171     {
>> (gdb)
>> 176             return (0);
>> (gdb)
>> _thr_rtld_rlock_acquire (lock=0x80180d200) at /usr/src/lib/libthr/thread/thr_
>> rtld.c:115
>> 115     {
>> (gdb)
>> 120             curthread = _get_curthread();
>> (gdb)
>> _get_curthread () at /usr/src/lib/libthr/arch/amd64/include/pthread_md.h:97
>> 97              return (TCB_GET64(tcb_thread));
>> (gdb)
>> _thr_rtld_rlock_acquire (lock=0x80180d200) at /usr/src/lib/libthr/thread/thr_
>> rtld.c:121
>> 121             SAVE_ERRNO();
>> (gdb)
>> 124             THR_CRITICAL_ENTER(curthread);
>> (gdb)
>> _thr_rwlock_tryrdlock (rwlock=<optimized out>, flags=0) at /usr/src/lib/libth
>> r/thread/thr_umtx.h:192
>> 192                 (rwlock->rw_flags & URWLOCK_PREFER_READER) != 0)
>> (gdb)
>> 191             if ((flags & URWLOCK_PREFER_READER) != 0 ||
>> (gdb)
>> 197             while (!(state & wrflags)) {
>> (gdb)
>> 201                     if (atomic_cmpset_acq_32(&rwlock->rw_state, state, st
>> ate + 1))
>> (gdb)
>> atomic_cmpset_int (dst=<optimized out>, expect=<optimized out>, src=1) at /us
>> r/obj/usr/src/amd64.amd64/tmp/usr/include/machine/atomic.h:220
>> 220     ATOMIC_CMPSET(int);
>> (gdb)
>> _thr_rwlock_tryrdlock (rwlock=<optimized out>, flags=0) at /usr/src/lib/libth
>> r/thread/thr_umtx.h:201
>> 201                     if (atomic_cmpset_acq_32(&rwlock->rw_state, state, st
>> ate + 1))
>> (gdb)
>> _thr_rtld_rlock_acquire (lock=0x80180d200) at /usr/src/lib/libthr/thread/thr_
>> rtld.c:127
>> 127             curthread->rdlock_count++;
>> (gdb)
>> 128             RESTORE_ERRNO();
>> (gdb)
>> 129     }
>> (gdb)
>> _thr_rtld_clr_flag (mask=1) at /usr/src/lib/libthr/thread/thr_rtld.c:181
>> 181     {
>> (gdb)
>> 182             return (0);
>> (gdb)
>> _thr_rtld_lock_release (lock=0x80180d200) at /usr/src/lib/libthr/thread/thr_r
>> tld.c:150
>> 150     {
>> (gdb)
>> _get_curthread () at /usr/src/lib/libthr/arch/amd64/include/pthread_md.h:97
>> 97              return (TCB_GET64(tcb_thread));
>> (gdb)
>> _thr_rtld_lock_release (lock=0x80180d200) at /usr/src/lib/libthr/thread/thr_r
>> tld.c:157
>> 157             SAVE_ERRNO();
>> (gdb)
>> 160             state = l->lock.rw_state;
>> (gdb)
>> 161             if (_thr_rwlock_unlock(&l->lock) == 0) {
>> (gdb)
>> _thr_rwlock_unlock (rwlock=0x80180d200) at /usr/src/lib/libthr/thread/thr_umt
>> x.h:249
>> 249             state = rwlock->rw_state;
>> (gdb)
>> 250             if ((state & URWLOCK_WRITE_OWNER) != 0) {
>> (gdb)
>> 256                             if (__predict_false(URWLOCK_READER_COUNT(stat
>> e) == 0))
>> (gdb)
>> 260                                 URWLOCK_READER_COUNT(state) == 1)) 
>> {
>> (gdb)
>> 259                                 URWLOCK_READ_WAITERS)) != 0 &&
>> (gdb)
>> 262                                         state, state - 1))
>> (gdb)
>> 261                                     if (atomic_cmpset_rel_32(&rwlock->rw_
>> state,
>> (gdb)
>> atomic_cmpset_int (dst=<optimized out>, expect=<optimized out>, src=0) at /us
>> r/obj/usr/src/amd64.amd64/tmp/usr/include/machine/atomic.h:220
>> 220     ATOMIC_CMPSET(int);
>> (gdb)
>> _thr_rwlock_unlock (rwlock=0x80180d200) at /usr/src/lib/libthr/thread/thr_umt
>> x.h:261
>> 261                                     if (atomic_cmpset_rel_32(&rwlock->rw_
>> state,
>> (gdb)
>> _thr_rtld_lock_release (lock=<optimized out>) at /usr/src/lib/libthr/thread/t
>> hr_rtld.c:162
>> 162                     if ((state & URWLOCK_WRITE_OWNER) == 0)
>> (gdb)
>> 163                             curthread->rdlock_count--;
>> (gdb)
>> 164                     THR_CRITICAL_LEAVE(curthread);
>> (gdb)
>> _thr_ast (curthread=0x80864b000) at /usr/src/lib/libthr/thread/thr_sig.c:271
>> 271             if (!THR_IN_CRITICAL(curthread)) {
>> (gdb)
>> 272                     check_deferred_signal(curthread);
>> (gdb)
>> check_deferred_signal (curthread=0x80864b000) at /usr/src/lib/libthr/thread/t
>> hr_sig.c:332
>> 332             if (__predict_true(curthread->deferred_siginfo.si_signo == 0 
>> ||
>> (gdb)
>> 351     }
>> (gdb)
>> _thr_ast (curthread=0x80864b000) at /usr/src/lib/libthr/thread/thr_sig.c:273
>> 273                     check_suspend(curthread);
>> (gdb)
>> check_suspend (curthread=0x80864b000) at /usr/src/lib/libthr/thread/thr_sig.c
>> :358
>> 358             if (__predict_true((curthread->flags &
>> (gdb)
>> 401     }
>> (gdb)
>> _thr_ast (curthread=0x80864b000) at /usr/src/lib/libthr/thread/thr_sig.c:274
>> 274                     check_cancel(curthread, NULL);
>> (gdb)
>> check_cancel (curthread=0x80864b000, ucp=0x0) at /usr/src/lib/libthr/thread/t
>> hr_sig.c:283
>> 283             if (__predict_true(!curthread->cancel_pending ||
>> (gdb)
>> _thr_ast (curthread=<optimized out>) at /usr/src/lib/libthr/thread/thr_sig.c:
>> 276
>> 276     }
>> (gdb)
>> _thr_rtld_lock_release (lock=<optimized out>) at /usr/src/lib/libthr/thread/t
>> hr_rtld.c:166
>> 166             RESTORE_ERRNO();
>> (gdb)
>> 167     }
>> (gdb)
>> getrlimit () at getrlimit.S:3
>> 3       RSYSCALL(getrlimit)
>> (gdb)
>> ntp_rlimit (rl_what=<optimized out>, rl_value=204800, rl_scale=<optimized out
>>> , rl_sstr=<optimized out>) at /usr/src/contrib/ntp/ntpd/ntp_config.c:5257
>> 5257                            if (rl_value > rl.rlim_max) {
>> (gdb)
>> 5264                            rl.rlim_cur = rl_value;
>> (gdb)
>> 5265                            if (-1 == setrlimit(RLIMIT_STACK, &rl)) {
>> (gdb)
>> _thr_rtld_set_flag (mask=1) at /usr/src/lib/libthr/thread/thr_rtld.c:171
>> 171     {
>> (gdb)
>> 176             return (0);
>> (gdb)
>> _thr_rtld_rlock_acquire (lock=0x80180d200) at /usr/src/lib/libthr/thread/thr_
>> rtld.c:115
>> 115     {
>> (gdb)
>> 120             curthread = _get_curthread();
>> (gdb)
>> _get_curthread () at /usr/src/lib/libthr/arch/amd64/include/pthread_md.h:97
>> 97              return (TCB_GET64(tcb_thread));
>> (gdb)
>> _thr_rtld_rlock_acquire (lock=0x80180d200) at /usr/src/lib/libthr/thread/thr_
>> rtld.c:121
>> 121             SAVE_ERRNO();
>> (gdb)
>> 124             THR_CRITICAL_ENTER(curthread);
>> (gdb)
>> _thr_rwlock_tryrdlock (rwlock=<optimized out>, flags=0) at /usr/src/lib/libth
>> r/thread/thr_umtx.h:192
>> 192                 (rwlock->rw_flags & URWLOCK_PREFER_READER) != 0)
>> (gdb)
>> 191             if ((flags & URWLOCK_PREFER_READER) != 0 ||
>> (gdb)
>> 197             while (!(state & wrflags)) {
>> (gdb)
>> 201                     if (atomic_cmpset_acq_32(&rwlock->rw_state, state, st
>> ate + 1))
>> (gdb)
>> atomic_cmpset_int (dst=<optimized out>, expect=<optimized out>, src=1) at /us
>> r/obj/usr/src/amd64.amd64/tmp/usr/include/machine/atomic.h:220
>> 220     ATOMIC_CMPSET(int);
>> (gdb)
>> _thr_rwlock_tryrdlock (rwlock=<optimized out>, flags=0) at /usr/src/lib/libth
>> r/thread/thr_umtx.h:201
>> 201                     if (atomic_cmpset_acq_32(&rwlock->rw_state, state, st
>> ate + 1))
>> (gdb)
>> _thr_rtld_rlock_acquire (lock=0x80180d200) at /usr/src/lib/libthr/thread/thr_
>> rtld.c:127
>> 127             curthread->rdlock_count++;
>> (gdb)
>> 128             RESTORE_ERRNO();
>> (gdb)
>> 129     }
>> (gdb)
>> _thr_rtld_clr_flag (mask=1) at /usr/src/lib/libthr/thread/thr_rtld.c:181
>> 181     {
>> (gdb)
>> 182             return (0);
>> (gdb)
>> _thr_rtld_lock_release (lock=0x80180d200) at /usr/src/lib/libthr/thread/thr_r
>> tld.c:150
>> 150     {
>> (gdb)
>> _get_curthread () at /usr/src/lib/libthr/arch/amd64/include/pthread_md.h:97
>> 97              return (TCB_GET64(tcb_thread));
>> (gdb)
>> _thr_rtld_lock_release (lock=0x80180d200) at /usr/src/lib/libthr/thread/thr_r
>> tld.c:157
>> 157             SAVE_ERRNO();
>> (gdb)
>> 160             state = l->lock.rw_state;
>> (gdb)
>> 161             if (_thr_rwlock_unlock(&l->lock) == 0) {
>> (gdb)
>> _thr_rwlock_unlock (rwlock=0x80180d200) at /usr/src/lib/libthr/thread/thr_umt
>> x.h:249
>> 249             state = rwlock->rw_state;
>> (gdb)
>> 250             if ((state & URWLOCK_WRITE_OWNER) != 0) {
>> (gdb)
>> 256                             if (__predict_false(URWLOCK_READER_COUNT(stat
>> e) == 0))
>> (gdb)
>> 260                                 URWLOCK_READER_COUNT(state) == 1)) {
>> (gdb)
>> 259                                 URWLOCK_READ_WAITERS)) != 0 &&
>> (gdb)
>> 262                                         state, state - 1))
>> (gdb)
>> 261                                     if (atomic_cmpset_rel_32(&rwlock->rw_
>> state,
>> (gdb)
>> atomic_cmpset_int (dst=<optimized out>, expect=<optimized out>, src=0) at /us
>> r/obj/usr/src/amd64.amd64/tmp/usr/include/machine/atomic.h:220
>> 220     ATOMIC_CMPSET(int);
>> (gdb)
>> _thr_rwlock_unlock (rwlock=0x80180d200) at /usr/src/lib/libthr/thread/thr_umt
>> x.h:261
>> 261                                     if (atomic_cmpset_rel_32(&rwlock->rw_
>> state,
>> (gdb)
>> _thr_rtld_lock_release (lock=<optimized out>) at /usr/src/lib/libthr/thread/t
>> hr_rtld.c:162
>> 162                     if ((state & URWLOCK_WRITE_OWNER) == 0)
>> (gdb)
>> 163                             curthread->rdlock_count--;
>> (gdb)
>> 164                     THR_CRITICAL_LEAVE(curthread);
>> (gdb)
>> _thr_ast (curthread=0x80864b000) at /usr/src/lib/libthr/thread/thr_sig.c:271
>> 271             if (!THR_IN_CRITICAL(curthread)) {
>> (gdb)
>> 272                     check_deferred_signal(curthread);
>> (gdb)
>> check_deferred_signal (curthread=0x80864b000) at /usr/src/lib/libthr/thread/t
>> hr_sig.c:332
>> 332             if 
>> (__predict_true(curthread->deferred_siginfo.si_signo == 0 ||
>> (gdb)
>> 351     }
>> (gdb)
>> _thr_ast (curthread=0x80864b000) at /usr/src/lib/libthr/thread/thr_sig.c:273
>> 273                     check_suspend(curthread);
>> (gdb)
>> check_suspend (curthread=0x80864b000) at /usr/src/lib/libthr/thread/thr_sig.c
>> :358
>> 358             if (__predict_true((curthread->flags &
>> (gdb)
>> 401     }
>> (gdb)
>> _thr_ast (curthread=0x80864b000) at /usr/src/lib/libthr/thread/thr_sig.c:274
>> 274                     check_cancel(curthread, NULL);
>> (gdb)
>> check_cancel (curthread=0x80864b000, ucp=0x0) at /usr/src/lib/libthr/thread/t
>> hr_sig.c:283
>> 283             if (__predict_true(!curthread->cancel_pending ||
>> (gdb)
>> _thr_ast (curthread=<optimized out>) at /usr/src/lib/libthr/thread/thr_sig.c:
>> 276
>> 276     }
>> (gdb)
>> _thr_rtld_lock_release (lock=<optimized out>) at /usr/src/lib/libthr/thread/t
>> hr_rtld.c:166
>> 166             RESTORE_ERRNO();
>> (gdb)
>> 167     }
>> (gdb)
>> setrlimit () at setrlimit.S:3
>> 3       RSYSCALL(setrlimit)
>> (gdb)
>>
>> Program received signal SIGSEGV, Segmentation fault.
>> setrlimit () at setrlimit.S:3
>> 3       RSYSCALL(setrlimit)
>> (gdb)
>>
>> Program terminated with signal SIGSEGV, Segmentation fault.
>> The program no longer exists.
>> (gdb) q
>>
>> ====
>>
>> I'm sorry for the long post. Is there anything (else) I can do to 
>> further narrow it down?
> 
> I've been able to confirm that kib@'s hunch regarding the gap is correct.
> 
> Use the workaround until this can be solved.
> 
> 

-- 
Harlan Stenn <stenn@nwtime.org>
http://networktimefoundation.org - be a member!



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?9b0c95de-2d0e-89b4-32e6-63ec5af729b4>