Page MenuHomeFreeBSD

NTPD Circumvent ASLR
ClosedPublic

Authored by cy on Nov 14 2019, 3:02 AM.
Tags
None
Referenced Files
F103348857: D22358.id64299.diff
Sat, Nov 23, 9:35 PM
F103337055: D22358.diff
Sat, Nov 23, 5:54 PM
Unknown Object (File)
Sat, Nov 23, 11:09 AM
Unknown Object (File)
Fri, Nov 22, 6:30 PM
Unknown Object (File)
Fri, Nov 22, 10:22 AM
Unknown Object (File)
Thu, Nov 21, 5:23 AM
Unknown Object (File)
Wed, Nov 20, 9:06 AM
Unknown Object (File)
Sun, Nov 10, 5:38 AM
Subscribers

Details

Summary

ntpd fails again with ASLR stack gap != 0. This patch circumvents the issue by duplicating proccontrol within ntpd until a proper solution can be developed with nwtime.org.

This has been submitted upstream and may be included in the next release of ntp.

This is a resolution for PR/241421 and PR/241960.

A corresponding ports patch will be created.

Test Plan

Currently in use locally.

Submitted upstream.

Diff Detail

Repository
rP FreeBSD ports repository
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

Seems sane to me, but I'd feel better about getting it committed if others more deeply familiar with the aslr stuff give it their blessing.

This revision is now accepted and ready to land.Nov 14 2019, 3:20 AM

If you want to disable ASLR, it is enough to issue procctl(), checking global system settings gives no value and is in fact racy.

If the problem is only with the gap, then you can just disable the gap using procctl, I believe this is what jdk does.

That said, why the gap is the problem ? Wasn't the rlimit(2) call that created problems, removed from ntpd ?

contrib/ntp/ntpd/ntpd.c
427 ↗(On Diff #64299)

And if __FreeBSD_cc_version is undefined, this code is ending with the error.

The rlimit() for mlock() was removed. The rlimit() for stack wasn't. Removing the second rlimit() causes an an assertion callback when an IPv6 packet is received. Your suggestion for simply calling procctl() works as well.

Unconditionally call procctl() as suggested by kib@.

This revision now requires review to proceed.Nov 14 2019, 9:55 PM
contrib/ntp/ntpd/ntpd.c
141 ↗(On Diff #64341)

Why not #ifdef __FreeBSD ?

415 ↗(On Diff #64341)

I suggest to disable stack gap instead of ASLR. Use PROC_STACKGAP_CTL with DISABLE when available. If not available, it is safe to assume that stackgap is not supported as well.

contrib/ntp/ntpd/ntpd.c
409 ↗(On Diff #64341)

Is there a PR for this problem? I think this whole block needs a comment, something simple like

/* Must disable STACKGAP on FreeBSD to avoid <whatever the problem was>. See PR NNNN. */

cy edited the summary of this revision. (Show Details)

A better solution.

contrib/ntp/ntpd/ntpd.c
141 ↗(On Diff #64341)

FreeBSD is not defined by llvm or gcc. FreeBSD_cc_version is defined by our cc, without including any headers. It's portable and can be shared with our ntp upline, nwtime.org.

contrib/ntp/ntpd/ntpd.c
141 ↗(On Diff #64341)

Ummm, FreeBSD is defined to be the major version of FreeBSD without needing a header. FreeBSD_version needs sys/param.h....

contrib/ntp/ntpd/ntpd.c
141 ↗(On Diff #64341)

FreeBSD is defined, I should have said

s/__FreeBSD_cc_version/__FreeBSD__/

contrib/ntp/ntpd/ntpd.c
421 ↗(On Diff #64360)

I suggest to silently ignore the error from procctl(2). The only real situation where it can occur is when PROC_STACKGAP_CTL is not supported, because the kernel we running on is too old. Then there is no harm from the error, and running the daemon instead of abruptly terminating is much better outcome.

I might even go further with this suggestion and propose to do e.g.

#ifdef __FreeBSD__
#include <sys/procctl.h>
#ifndef PROC_STACKGAP_CTL
#define	PROC_STACKGAP_CTL	17
#define	PROC_STACKGAP_DISABLE	0x0002
#endif
...

So that even if we compile on the older system, we still can run on newer kernels.

That said, we probably need to allocate a bit for stack gap in image flags. Unfortunately, the image flag editor is still not installed.

Latest reviews incorporated.

This revision is now accepted and ready to land.Nov 15 2019, 3:39 PM