Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 24 Aug 2019 22:04:49 +0200 (CEST)
From:      =?UTF-8?Q?Trond_Endrest=C3=B8l?= <trond.endrestol@ximalas.info>
To:        freebsd-stable@freebsd.org
Subject:   ntpd doesn't like ASLR on stable/12 post-r350672
Message-ID:  <alpine.BSF.2.21.99999.352.1908242135380.6386@enterprise.ximalas.info>

next in thread | raw e-mail | index | archive | help
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): Starting
Aug 24 21:25:43 <kern.info> HOSTNAME kernel: [406] pid 5619 (ntpd), jid 0, uid 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.

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/libthr/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, state + 1))
(gdb)
atomic_cmpset_int (dst=<optimized out>, expect=<optimized out>, src=1) at /usr/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/libthr/thread/thr_umtx.h:201
201                     if (atomic_cmpset_acq_32(&rwlock->rw_state, state, state + 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_rtld.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_rtld.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_umtx.h:249
249             state = rwlock->rw_state;
(gdb)
250             if ((state & URWLOCK_WRITE_OWNER) != 0) {
(gdb)
256                             if (__predict_false(URWLOCK_READER_COUNT(state) == 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 /usr/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_umtx.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/thr_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/thr_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/thr_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/thr_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/libthr/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, state + 1))
(gdb)
atomic_cmpset_int (dst=<optimized out>, expect=<optimized out>, src=1) at /usr/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/libthr/thread/thr_umtx.h:201
201                     if (atomic_cmpset_acq_32(&rwlock->rw_state, state, state + 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_rtld.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_rtld.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_umtx.h:249
249             state = rwlock->rw_state;
(gdb)
250             if ((state & URWLOCK_WRITE_OWNER) != 0) {
(gdb)
256                             if (__predict_false(URWLOCK_READER_COUNT(state) == 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 /usr/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_umtx.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/thr_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/thr_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/thr_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/thr_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?

-- 
Trond.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?alpine.BSF.2.21.99999.352.1908242135380.6386>