On Wed, Jul 18, 2018 at 9:59 PM Paul Moore <paul(a)paul-moore.com> wrote:
On Wed, Jul 18, 2018 at 3:36 PM Steve Grubb <sgrubb(a)redhat.com>
wrote:
> On Wednesday, July 18, 2018 2:36:11 PM EDT Paul Moore wrote:
> > > Changes in v2:
> > > - The audit_adjtime() function has been modified to only log those
> > > fields that contain values that are actually used, resulting in more
> > > compact records.
> > > - The audit_adjtime() call has been moved to do_adjtimex() in
> > > timekeeping.c
> > > - Added an additional patch (for review) that simplifies the detection
> > > if the syscall is read-only.
> >
> > Looking at these new records, and trying to guess a bit at the
> > original intent of the feature request, I think we may be going a bit
> > overboard with the information we are logging. I'm thinking all we
> > really need to capture in the audit log is the system time both before
> > and after the change (for the sake of simplicity I suggest using a
> > data format similar to the audit record timestamp).
> >
> > While I created the GH issue for this, I believe the original request
> > came from a Red Hat BZ that Steve created; Steve, what sort of
> > certification requirements (if any?) are there for logging system time
> > changes?
>
> That we record any attempts to change the system time. The problem is that
> adjtimex passes a data structure that is opaque to user space. So, we can't
> tell if someone is setting time, adjusting a tolerance, or simply retrieving
> status.
>
> With stime, we can clearly see the time that was sent into the kernel and it
> unconditionally sets time. With settimeofday, it uses a data structure that
> we cannot see, but whatever the contents are we are definitely setting time.
> Same goes for clock_settime. Only in 1 case do we actually see what the time
> is. So, that is not really needed. So, I think what we need to know is did
> the syscall do anything that adjusted the system's notion of time? And
that's
> all.
So presumably my above suggestion of simply recording the system time
both before and after the change would be sufficient, yes?
I wouldn't say this is the right approach here, for two reasons that
I'll try to explain below.
adjtimex(2) can be basically used for two major types of adjustment:
1. for (immediately) injecting offset into system time,
2. for changing NTP status variables.
(1.) is the more obvious and simple adjustment, which *directly*
alters the system time. For this adjustment the current proposed
solution simply logs the delta, by which the time is adjusted (it can
be retrieved easily from the supplied timex struct). In my opinion,
logging of this delta is more explicit than logging the timestamps
(which might not give the precise offset anyway, since time might flow
between the two timestamps) and is also more easily grepped in the
logs, as Steve pointed out in his reply. For example, you can quickly
filter out adjustments of less than +/-1 second by simply comparing
the offset in the records.
(2.) is a lot more tricky... These adjustments modify the variables of
the NTP algorithm, which is quite complex and it is not obvious how it
influences the system time. From my understanding, the algorithm is
used for adjustments that require smooth transition over time - such
as (or maybe this is the only use case) inserting a leap second. Note
that in this case, just logging timestamp before and after the syscall
is not sufficient, since the change doesn't happen immediately, but in
small increments that are gradually added *after* the syscall already
finished. I don't know if (or which of) these adjustments can be used
for a real attack, but at least the leap second insertion sounds like
something that could be used to shift the time without being easily
detected. This is why I am wary of throwing things out from the
logging until we understand what is truly important and what is not.
So, to sum up, my two arguments against logging before/after timestamps are:
1. For the case of direct offset injection we can much more easily log
the actual offset and this is also more informative.
2. For the case of NTP adjustments it is just not sufficient, we need
to log some or all of the variable adjustments and let the people
analyzing the logs figure out how that influenced the clock later (NTP
algorithm is just too complex).
I hope this explanation makes the situation a bit more clear. Time is
hard [1] and this particular time issue just refuses to be any
different :)
[1]
http://sflanders.net/2015/02/09/time-hard-proper-ntp-configuration/
--
Ondrej Mosnacek <omosnace at redhat dot com>
Associate Software Engineer, Security Technologies
Red Hat, Inc.