* [kernel-hardening] [PATCH] lkdtm: add bad USER_DS test
@ 2017-03-23 20:34 Kees Cook
2017-03-24 8:14 ` [kernel-hardening] " Heiko Carstens
0 siblings, 1 reply; 6+ messages in thread
From: Kees Cook @ 2017-03-23 20:34 UTC (permalink / raw)
To: Thomas Garnier
Cc: Martin Schwidefsky, Heiko Carstens, David Howells, Arnd Bergmann,
Dave Hansen, Al Viro, Thomas Gleixner, René Nyffenegger,
Andrew Morton, Paul E . McKenney, Ingo Molnar, Oleg Nesterov,
Pavel Tikhomirov, Stephen Smalley, Ingo Molnar, H . Peter Anvin,
Andy Lutomirski, Paolo Bonzini, Rik van Riel, Josh Poimboeuf,
Borislav Petkov, Brian Gerst, Kirill A . Shutemov,
Christian Borntraeger, Russell King, Will Deacon,
Catalin Marinas, Mark Rutland, James Morse, linux-s390, LKML,
Linux API, x86, linux-arm-kernel, kernel-hardening
This adds CORRUPT_USER_DS to check that the get_fs() test on syscall return
still sees USER_DS during the new VERIFY_PRE_USERMODE_STATE checks.
Signed-off-by: Kees Cook <keescook@chromium.org>
---
drivers/misc/lkdtm.h | 1 +
drivers/misc/lkdtm_bugs.c | 20 ++++++++++++++++++++
drivers/misc/lkdtm_core.c | 1 +
3 files changed, 22 insertions(+)
diff --git a/drivers/misc/lkdtm.h b/drivers/misc/lkdtm.h
index 67d27be60405..3b4976396ec4 100644
--- a/drivers/misc/lkdtm.h
+++ b/drivers/misc/lkdtm.h
@@ -27,6 +27,7 @@ void lkdtm_REFCOUNT_ZERO_SUB(void);
void lkdtm_REFCOUNT_ZERO_ADD(void);
void lkdtm_CORRUPT_LIST_ADD(void);
void lkdtm_CORRUPT_LIST_DEL(void);
+void lkdtm_CORRUPT_USER_DS(void);
/* lkdtm_heap.c */
void lkdtm_OVERWRITE_ALLOCATION(void);
diff --git a/drivers/misc/lkdtm_bugs.c b/drivers/misc/lkdtm_bugs.c
index e3f4cd8876b5..4906e53a6df3 100644
--- a/drivers/misc/lkdtm_bugs.c
+++ b/drivers/misc/lkdtm_bugs.c
@@ -8,6 +8,7 @@
#include <linux/list.h>
#include <linux/refcount.h>
#include <linux/sched.h>
+#include <linux/uaccess.h>
struct lkdtm_list {
struct list_head node;
@@ -279,3 +280,22 @@ void lkdtm_CORRUPT_LIST_DEL(void)
else
pr_err("list_del() corruption not detected!\n");
}
+
+void lkdtm_CORRUPT_USER_DS(void)
+{
+ /*
+ * Test that USER_DS has been set correctly on exiting a syscall.
+ * Since setting this higher than USER_DS (TASK_SIZE) would introduce
+ * an exploitable condition, we lower it instead, since that should
+ * not create as large a problem on an unprotected system.
+ */
+ mm_segment_t lowfs;
+#ifdef MAKE_MM_SEG
+ lowfs = MAKE_MM_SEG(TASK_SIZE - PAGE_SIZE);
+#else
+ lowfs = TASK_SIZE - PAGE_SIZE;
+#endif
+
+ pr_info("setting bad task size limit\n");
+ set_fs(lowfs);
+}
diff --git a/drivers/misc/lkdtm_core.c b/drivers/misc/lkdtm_core.c
index b9a4cd4a9b68..42d2b8e31e6b 100644
--- a/drivers/misc/lkdtm_core.c
+++ b/drivers/misc/lkdtm_core.c
@@ -199,6 +199,7 @@ struct crashtype crashtypes[] = {
CRASHTYPE(OVERFLOW),
CRASHTYPE(CORRUPT_LIST_ADD),
CRASHTYPE(CORRUPT_LIST_DEL),
+ CRASHTYPE(CORRUPT_USER_DS),
CRASHTYPE(CORRUPT_STACK),
CRASHTYPE(UNALIGNED_LOAD_STORE_WRITE),
CRASHTYPE(OVERWRITE_ALLOCATION),
--
2.7.4
--
Kees Cook
Pixel Security
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [kernel-hardening] Re: [PATCH] lkdtm: add bad USER_DS test
2017-03-23 20:34 [kernel-hardening] [PATCH] lkdtm: add bad USER_DS test Kees Cook
@ 2017-03-24 8:14 ` Heiko Carstens
2017-03-24 15:17 ` Thomas Garnier
0 siblings, 1 reply; 6+ messages in thread
From: Heiko Carstens @ 2017-03-24 8:14 UTC (permalink / raw)
To: Kees Cook
Cc: Thomas Garnier, Martin Schwidefsky, David Howells, Arnd Bergmann,
Dave Hansen, Al Viro, Thomas Gleixner, René Nyffenegger,
Andrew Morton, Paul E . McKenney, Ingo Molnar, Oleg Nesterov,
Pavel Tikhomirov, Stephen Smalley, Ingo Molnar, H . Peter Anvin,
Andy Lutomirski, Paolo Bonzini, Rik van Riel, Josh Poimboeuf,
Borislav Petkov, Brian Gerst, Kirill A . Shutemov,
Christian Borntraeger, Russell King, Will Deacon,
Catalin Marinas, Mark Rutland, James Morse, linux-s390, LKML,
Linux API, x86, linux-arm-kernel, kernel-hardening
On Thu, Mar 23, 2017 at 01:34:19PM -0700, Kees Cook wrote:
> This adds CORRUPT_USER_DS to check that the get_fs() test on syscall return
> still sees USER_DS during the new VERIFY_PRE_USERMODE_STATE checks.
>
> Signed-off-by: Kees Cook <keescook@chromium.org>
...
> +void lkdtm_CORRUPT_USER_DS(void)
> +{
> + /*
> + * Test that USER_DS has been set correctly on exiting a syscall.
> + * Since setting this higher than USER_DS (TASK_SIZE) would introduce
> + * an exploitable condition, we lower it instead, since that should
> + * not create as large a problem on an unprotected system.
> + */
> + mm_segment_t lowfs;
> +#ifdef MAKE_MM_SEG
> + lowfs = MAKE_MM_SEG(TASK_SIZE - PAGE_SIZE);
> +#else
> + lowfs = TASK_SIZE - PAGE_SIZE;
> +#endif
> +
> + pr_info("setting bad task size limit\n");
> + set_fs(lowfs);
> +}
This won't work on architectures where the set_fs() argument does not
contain an address but an address space identifier. This is true e.g. for
s390 and as far as I know also for sparc.
On s390 we have complete distinct address spaces for kernel and user space
that each start at address zero.
^ permalink raw reply [flat|nested] 6+ messages in thread
* [kernel-hardening] Re: [PATCH] lkdtm: add bad USER_DS test
2017-03-24 8:14 ` [kernel-hardening] " Heiko Carstens
@ 2017-03-24 15:17 ` Thomas Garnier
2017-03-24 15:24 ` Christian Borntraeger
0 siblings, 1 reply; 6+ messages in thread
From: Thomas Garnier @ 2017-03-24 15:17 UTC (permalink / raw)
To: Heiko Carstens
Cc: Kees Cook, Martin Schwidefsky, David Howells, Arnd Bergmann,
Dave Hansen, Al Viro, Thomas Gleixner, René Nyffenegger,
Andrew Morton, Paul E . McKenney, Ingo Molnar, Oleg Nesterov,
Pavel Tikhomirov, Stephen Smalley, Ingo Molnar, H . Peter Anvin,
Andy Lutomirski, Paolo Bonzini, Rik van Riel, Josh Poimboeuf,
Borislav Petkov, Brian Gerst, Kirill A . Shutemov,
Christian Borntraeger, Russell King, Will Deacon,
Catalin Marinas, Mark Rutland, James Morse, linux-s390, LKML,
Linux API, x86, linux-arm-kernel, kernel-hardening
On Fri, Mar 24, 2017 at 1:14 AM, Heiko Carstens
<heiko.carstens@de.ibm.com> wrote:
> On Thu, Mar 23, 2017 at 01:34:19PM -0700, Kees Cook wrote:
>> This adds CORRUPT_USER_DS to check that the get_fs() test on syscall return
>> still sees USER_DS during the new VERIFY_PRE_USERMODE_STATE checks.
>>
>> Signed-off-by: Kees Cook <keescook@chromium.org>
>
> ...
>
>> +void lkdtm_CORRUPT_USER_DS(void)
>> +{
>> + /*
>> + * Test that USER_DS has been set correctly on exiting a syscall.
>> + * Since setting this higher than USER_DS (TASK_SIZE) would introduce
>> + * an exploitable condition, we lower it instead, since that should
>> + * not create as large a problem on an unprotected system.
>> + */
>> + mm_segment_t lowfs;
>> +#ifdef MAKE_MM_SEG
>> + lowfs = MAKE_MM_SEG(TASK_SIZE - PAGE_SIZE);
>> +#else
>> + lowfs = TASK_SIZE - PAGE_SIZE;
>> +#endif
>> +
>> + pr_info("setting bad task size limit\n");
>> + set_fs(lowfs);
>> +}
>
> This won't work on architectures where the set_fs() argument does not
> contain an address but an address space identifier. This is true e.g. for
> s390 and as far as I know also for sparc.
> On s390 we have complete distinct address spaces for kernel and user space
> that each start at address zero.
>
The patch that enforce USER_DS is disabled on s390 anyway. I guess, we
can just do a set_fs(KERNEL_DS) for the others.
--
Thomas
^ permalink raw reply [flat|nested] 6+ messages in thread
* [kernel-hardening] Re: [PATCH] lkdtm: add bad USER_DS test
2017-03-24 15:17 ` Thomas Garnier
@ 2017-03-24 15:24 ` Christian Borntraeger
2017-03-24 16:11 ` Thomas Garnier
2017-03-24 17:46 ` Kees Cook
0 siblings, 2 replies; 6+ messages in thread
From: Christian Borntraeger @ 2017-03-24 15:24 UTC (permalink / raw)
To: Thomas Garnier, Heiko Carstens
Cc: Kees Cook, Martin Schwidefsky, David Howells, Arnd Bergmann,
Dave Hansen, Al Viro, Thomas Gleixner, René Nyffenegger,
Andrew Morton, Paul E . McKenney, Ingo Molnar, Oleg Nesterov,
Pavel Tikhomirov, Stephen Smalley, Ingo Molnar, H . Peter Anvin,
Andy Lutomirski, Paolo Bonzini, Rik van Riel, Josh Poimboeuf,
Borislav Petkov, Brian Gerst, Kirill A . Shutemov, Russell King,
Will Deacon, Catalin Marinas, Mark Rutland, James Morse,
linux-s390, LKML, Linux API, x86, linux-arm-kernel,
kernel-hardening
On 03/24/2017 04:17 PM, Thomas Garnier wrote:
> On Fri, Mar 24, 2017 at 1:14 AM, Heiko Carstens
> <heiko.carstens@de.ibm.com> wrote:
>> On Thu, Mar 23, 2017 at 01:34:19PM -0700, Kees Cook wrote:
>>> This adds CORRUPT_USER_DS to check that the get_fs() test on syscall return
>>> still sees USER_DS during the new VERIFY_PRE_USERMODE_STATE checks.
>>>
>>> Signed-off-by: Kees Cook <keescook@chromium.org>
>>
>> ...
>>
>>> +void lkdtm_CORRUPT_USER_DS(void)
>>> +{
>>> + /*
>>> + * Test that USER_DS has been set correctly on exiting a syscall.
>>> + * Since setting this higher than USER_DS (TASK_SIZE) would introduce
>>> + * an exploitable condition, we lower it instead, since that should
>>> + * not create as large a problem on an unprotected system.
>>> + */
>>> + mm_segment_t lowfs;
>>> +#ifdef MAKE_MM_SEG
>>> + lowfs = MAKE_MM_SEG(TASK_SIZE - PAGE_SIZE);
>>> +#else
>>> + lowfs = TASK_SIZE - PAGE_SIZE;
>>> +#endif
>>> +
>>> + pr_info("setting bad task size limit\n");
>>> + set_fs(lowfs);
>>> +}
>>
>> This won't work on architectures where the set_fs() argument does not
>> contain an address but an address space identifier. This is true e.g. for
>> s390 and as far as I know also for sparc.
>> On s390 we have complete distinct address spaces for kernel and user space
>> that each start at address zero.
>>
>
> The patch that enforce USER_DS is disabled on s390 anyway. I guess, we
> can just do a set_fs(KERNEL_DS) for the others.
that would enable the test, but it would also mean that lkdtm can be used by
a program to escalate its rights. I think that is the reason why Kees did this
lowfs things.
^ permalink raw reply [flat|nested] 6+ messages in thread
* [kernel-hardening] Re: [PATCH] lkdtm: add bad USER_DS test
2017-03-24 15:24 ` Christian Borntraeger
@ 2017-03-24 16:11 ` Thomas Garnier
2017-03-24 17:46 ` Kees Cook
1 sibling, 0 replies; 6+ messages in thread
From: Thomas Garnier @ 2017-03-24 16:11 UTC (permalink / raw)
To: Christian Borntraeger
Cc: Heiko Carstens, Kees Cook, Martin Schwidefsky, David Howells,
Arnd Bergmann, Dave Hansen, Al Viro, Thomas Gleixner,
René Nyffenegger, Andrew Morton, Paul E . McKenney,
Ingo Molnar, Oleg Nesterov, Pavel Tikhomirov, Stephen Smalley,
Ingo Molnar, H . Peter Anvin, Andy Lutomirski, Paolo Bonzini,
Rik van Riel, Josh Poimboeuf, Borislav Petkov, Brian Gerst,
Kirill A . Shutemov, Russell King, Will Deacon, Catalin Marinas,
Mark Rutland, James Morse, linux-s390, LKML, Linux API, x86,
linux-arm-kernel, kernel-hardening
On Fri, Mar 24, 2017 at 8:24 AM, Christian Borntraeger
<borntraeger@de.ibm.com> wrote:
> On 03/24/2017 04:17 PM, Thomas Garnier wrote:
>> On Fri, Mar 24, 2017 at 1:14 AM, Heiko Carstens
>> <heiko.carstens@de.ibm.com> wrote:
>>> On Thu, Mar 23, 2017 at 01:34:19PM -0700, Kees Cook wrote:
>>>> This adds CORRUPT_USER_DS to check that the get_fs() test on syscall return
>>>> still sees USER_DS during the new VERIFY_PRE_USERMODE_STATE checks.
>>>>
>>>> Signed-off-by: Kees Cook <keescook@chromium.org>
>>>
>>> ...
>>>
>>>> +void lkdtm_CORRUPT_USER_DS(void)
>>>> +{
>>>> + /*
>>>> + * Test that USER_DS has been set correctly on exiting a syscall.
>>>> + * Since setting this higher than USER_DS (TASK_SIZE) would introduce
>>>> + * an exploitable condition, we lower it instead, since that should
>>>> + * not create as large a problem on an unprotected system.
>>>> + */
>>>> + mm_segment_t lowfs;
>>>> +#ifdef MAKE_MM_SEG
>>>> + lowfs = MAKE_MM_SEG(TASK_SIZE - PAGE_SIZE);
>>>> +#else
>>>> + lowfs = TASK_SIZE - PAGE_SIZE;
>>>> +#endif
>>>> +
>>>> + pr_info("setting bad task size limit\n");
>>>> + set_fs(lowfs);
>>>> +}
>>>
>>> This won't work on architectures where the set_fs() argument does not
>>> contain an address but an address space identifier. This is true e.g. for
>>> s390 and as far as I know also for sparc.
>>> On s390 we have complete distinct address spaces for kernel and user space
>>> that each start at address zero.
>>>
>>
>> The patch that enforce USER_DS is disabled on s390 anyway. I guess, we
>> can just do a set_fs(KERNEL_DS) for the others.
>
> that would enable the test, but it would also mean that lkdtm can be used by
> a program to escalate its rights. I think that is the reason why Kees did this
> lowfs things.
>
I see, I need to look at how lkdtm works exactly.
--
Thomas
^ permalink raw reply [flat|nested] 6+ messages in thread
* [kernel-hardening] Re: [PATCH] lkdtm: add bad USER_DS test
2017-03-24 15:24 ` Christian Borntraeger
2017-03-24 16:11 ` Thomas Garnier
@ 2017-03-24 17:46 ` Kees Cook
1 sibling, 0 replies; 6+ messages in thread
From: Kees Cook @ 2017-03-24 17:46 UTC (permalink / raw)
To: Christian Borntraeger
Cc: Thomas Garnier, Heiko Carstens, Martin Schwidefsky,
David Howells, Arnd Bergmann, Dave Hansen, Al Viro,
Thomas Gleixner, René Nyffenegger, Andrew Morton,
Paul E . McKenney, Ingo Molnar, Oleg Nesterov, Pavel Tikhomirov,
Stephen Smalley, Ingo Molnar, H . Peter Anvin, Andy Lutomirski,
Paolo Bonzini, Rik van Riel, Josh Poimboeuf, Borislav Petkov,
Brian Gerst, Kirill A . Shutemov, Russell King, Will Deacon,
Catalin Marinas, Mark Rutland, James Morse, linux-s390, LKML,
Linux API, x86, linux-arm-kernel, kernel-hardening
On Fri, Mar 24, 2017 at 8:24 AM, Christian Borntraeger
<borntraeger@de.ibm.com> wrote:
> On 03/24/2017 04:17 PM, Thomas Garnier wrote:
>> On Fri, Mar 24, 2017 at 1:14 AM, Heiko Carstens
>> <heiko.carstens@de.ibm.com> wrote:
>>> On Thu, Mar 23, 2017 at 01:34:19PM -0700, Kees Cook wrote:
>>>> This adds CORRUPT_USER_DS to check that the get_fs() test on syscall return
>>>> still sees USER_DS during the new VERIFY_PRE_USERMODE_STATE checks.
>>>>
>>>> Signed-off-by: Kees Cook <keescook@chromium.org>
>>>
>>> ...
>>>
>>>> +void lkdtm_CORRUPT_USER_DS(void)
>>>> +{
>>>> + /*
>>>> + * Test that USER_DS has been set correctly on exiting a syscall.
>>>> + * Since setting this higher than USER_DS (TASK_SIZE) would introduce
>>>> + * an exploitable condition, we lower it instead, since that should
>>>> + * not create as large a problem on an unprotected system.
>>>> + */
>>>> + mm_segment_t lowfs;
>>>> +#ifdef MAKE_MM_SEG
>>>> + lowfs = MAKE_MM_SEG(TASK_SIZE - PAGE_SIZE);
>>>> +#else
>>>> + lowfs = TASK_SIZE - PAGE_SIZE;
>>>> +#endif
>>>> +
>>>> + pr_info("setting bad task size limit\n");
>>>> + set_fs(lowfs);
>>>> +}
>>>
>>> This won't work on architectures where the set_fs() argument does not
>>> contain an address but an address space identifier. This is true e.g. for
>>> s390 and as far as I know also for sparc.
>>> On s390 we have complete distinct address spaces for kernel and user space
>>> that each start at address zero.
>>>
>>
>> The patch that enforce USER_DS is disabled on s390 anyway. I guess, we
>> can just do a set_fs(KERNEL_DS) for the others.
>
> that would enable the test, but it would also mean that lkdtm can be used by
> a program to escalate its rights. I think that is the reason why Kees did this
> lowfs things.
Yeah, but it seems like getting this right for all architectures isn't
sane. I'm going to change it to use KERNEL_DS but also post a SIGKILL
to the process. That way it'll still trigger the syscall return
checking, but will be unable to continue running with a potentially
uncaught KERNEL_DS.
-Kees
--
Kees Cook
Pixel Security
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2017-03-24 17:46 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-23 20:34 [kernel-hardening] [PATCH] lkdtm: add bad USER_DS test Kees Cook
2017-03-24 8:14 ` [kernel-hardening] " Heiko Carstens
2017-03-24 15:17 ` Thomas Garnier
2017-03-24 15:24 ` Christian Borntraeger
2017-03-24 16:11 ` Thomas Garnier
2017-03-24 17:46 ` Kees Cook
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).