Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20181112185031.GA2699@openwall.com>
Date: Mon, 12 Nov 2018 19:50:31 +0100
From: Solar Designer <solar@...nwall.com>
To: lkrg-users@...ts.openwall.com
Subject: Re: LKRG 0.5

On Mon, Nov 12, 2018 at 08:03:31PM +0400, Ilya Matveychikov wrote:
> having protection
> system (LKRG) and "malicious" module at the same level of abstraction worth
> nothing to do with the security.

While in this example it's the same abstraction level (kernel module),
what matters more is it's also the same privilege level.  Yes, we can't
guarantee security when the attacker is at the same privilege level.
However, that doesn't mean we can't do anything for security.  We can
reduce the probability that the attack will succeed and stay undetected.
It's like winning in Core War(s) - can't be sure to win, but might win.

https://en.wikipedia.org/wiki/Core_War

(BTW, there are many reimplementations of this game - a Google web
search gives me 5 or so on the first results page.  Must be fun.)

LKRG "main" doesn't try to prevent "supported" kernel modifications -
loading of kernel modules, use of kernel APIs from modules - as that
would make the system less usable, and would require userland changes
(boot chain security, etc.) to consistently deal with this extended
threat model.  That's an LKRG "experimental" thing.

LKRG tries to detect "unsupported" kernel modifications, like what a
kernel vulnerability exploit would possibly attempt when it got a
write-what-where primitive but doesn't yet run its own code (so not yet
at a full Core War with us).  LKRG doesn't prevent all of those,
though - there are still plenty of unprotected yet critical data
structures (including with function pointers).

LKRG also might win against some kernel exploits that already got code
running, but that's harder for LKRG, and easier for exploits to bypass.

On Mon, Nov 12, 2018 at 08:40:10PM +0400, Ilya Matveychikov wrote:
> Well, I had no idea about what was the threat model. And you're right,
> bypassing it from the kernel is quite trivial. Now I can understand LKRG
> concept better thanks to you.

I agree we need to document the threat model(s) better.  Our wiki page:

https://openwall.info/wiki/p_lkrg/Threat_model

says a lot of things but doesn't focus on what's immediately important
to users.  Adam first wrote it in July 2017 - IIRC, before we decided to
split "main" and "experimental", and to prioritize exploit detection.
Despite of a later edit, the original focus of the project still shows
in the way things are described, and that's unhelpful.  Maybe we should
drop the contents of this wiki page, and rewrite it from scratch.

> About the bypass "technique" which I wanted to show I could say that
> it can be used from the user-mode too. Just consider that the only way
> of LKRG to report something is to write to kernel's log. So, simple
> filtering of entries by "[LKRG]" is enough to completely remove all the
> noise produced by LKRG. Valid for both kernel and user modes.

LKRG up to and including 0.4 only enforced exploit detection, and only
lightly (killing the thread(s) that got unauthorized credentials).  LKRG
0.5 now also has optional enforcement of code integrity through calling
panic(), which can be enabled via the newly introduced sysctl.

We didn't do this earlier, and still haven't enabled this sysctl by
default, because of concern for possible false positives.  In fact, Adam
knew that false positives were expected at least until LKRG 0.5's
introduction of *_JUMP_LABEL support for kernel modules, so it's not a
coincidence that we introduce these two features at the same time.
Without the sysctl enabled, LKRG's code integrity is essentially running
in a test/demo mode, and doesn't provide security.

I think we might also need to provide guidelines on other settings where
the panics wouldn't be merely a nuisance (which they would be on
headless servers without IP-KVM access or the like) - I'm thinking also
recommending configuration of netconsole and, say, "panic=600", so that
the server would be back up after a while yet the attack would end up
being rate-limited.

> On Mon, Nov 12, 2018 at 05:21:53PM +0100, Solar Designer wrote:
> > LKRG "main" (unlike "experimental") doesn't include protection against
> > root in its threat model, except when said root access was just obtained
> > via a kernel vulnerability exploit.  I see nothing inconsistent in that.
> > Do you?  If so, what inconsistency do you see?
> 
> Well, it's a good question. Is it OK for the OS kernel to be exploited
> by exploits by itself and this is the case to have things like LKRG or
> should the kernel be designed in the way that having a BUG doesn't give
> attacker a way to exploit it?
> 
> That's the only inconsistency I can see.
> 
> In other words, probably it's better to concentrate on fixing OS kernel
> security rather than developing of runtime guards :)

Ideally, the kernel would be bug-free.  If this were realistically
achievable, we would just find and fix all bugs, not ever introduce any
new bugs, and then we wouldn't need any kernel hardening features that
aim to reduce exploitability of bug classes.  This is roughly what Linus
advocated.  However, a (security) bug-free state is not realistically
achievable.  Hence, the kernel hardening features that aim to reduce
exploitability of bug classes, like what's in grsecurity patches and
like what's partially and slowly getting into mainline under KSPP.  Now,
if we implement such "serious" kernel hardening, why also bother with
"naive" and doomed post-detection of exploits like what's in LKRG?  Two
reasons: we're only getting relatively little hardening into mainline
and typical distro kernels now (not to the extent of grsecurity's) and
it's realistic that a bug wouldn't be mitigated by the hardening yet
would be caught by post-detection, especially if such post-detection is
uncommon (provides diversity).

So it's three different approaches, from least to most controversial:
bug fixing, hardening against exploitability of bug classes, and
post-detection of exploits.  (We can identify more, such as preventing
certain bug classes from existing by a redesign, which would be best.
But I'll keep things simpler for this discussion.)  Any combination of
all three may work, but with different results and for different users.

We can debate how to optimally balance the effort, and this would be a
reasonable discussion to have, but the reality is there are different
people interested in working on different ones of these approaches, and
different potential users - e.g., users of RHEL7'ish distros are not
getting most of whatever hardening we might get into mainline in the
next few years, yet many of them will stay with their distros during
those years and some might use LKRG.  So it's not about what's
theoretically and ultimately best (which perhaps wouldn't be Linux), but
also about what's beneficial for some users now and in the next few
years, even if temporarily (nothing is permanent anyway).

Alexander

P.S. I see that Adam has also posted a reply.  I wrote the above before
seeing his, and I make no edits now.  So these two replies show how the
two of us see this matter, independently.

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.