-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
drivers/misc/lkdtm: add new file in LKDTM to test fortified strscpy
This new test ensures that fortified strscpy has the same behavior than vanilla strscpy (e.g. returning -E2BIG when src content is truncated). Finally, it generates a crash at runtime because there is a write overflow in destination string. Link: https://lkml.kernel.org/r/20201122162451.27551-5-laniel_francis@privacyrequired.com Signed-off-by: Francis Laniel <laniel_francis@privacyrequired.com> Reviewed-by: Kees Cook <keescook@chromium.org> Cc: Daniel Axtens <dja@axtens.net> Cc: Daniel Micay <danielmicay@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
- Loading branch information
Francis Laniel
authored and
Linus Torvalds
committed
Dec 16, 2020
1 parent
33e56a5
commit febebaf
Showing
5 changed files
with
88 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
/* | ||
* Copyright (c) 2020 Francis Laniel <laniel_francis@privacyrequired.com> | ||
* | ||
* Add tests related to fortified functions in this file. | ||
*/ | ||
#include "lkdtm.h" | ||
#include <linux/string.h> | ||
#include <linux/slab.h> | ||
|
||
|
||
/* | ||
* Calls fortified strscpy to test that it returns the same result as vanilla | ||
* strscpy and generate a panic because there is a write overflow (i.e. src | ||
* length is greater than dst length). | ||
*/ | ||
void lkdtm_FORTIFIED_STRSCPY(void) | ||
{ | ||
char *src; | ||
char dst[5]; | ||
|
||
struct { | ||
union { | ||
char big[10]; | ||
char src[5]; | ||
}; | ||
} weird = { .big = "hello!" }; | ||
char weird_dst[sizeof(weird.src) + 1]; | ||
|
||
src = kstrdup("foobar", GFP_KERNEL); | ||
|
||
if (src == NULL) | ||
return; | ||
|
||
/* Vanilla strscpy returns -E2BIG if size is 0. */ | ||
if (strscpy(dst, src, 0) != -E2BIG) | ||
pr_warn("FAIL: strscpy() of 0 length did not return -E2BIG\n"); | ||
|
||
/* Vanilla strscpy returns -E2BIG if src is truncated. */ | ||
if (strscpy(dst, src, sizeof(dst)) != -E2BIG) | ||
pr_warn("FAIL: strscpy() did not return -E2BIG while src is truncated\n"); | ||
|
||
/* After above call, dst must contain "foob" because src was truncated. */ | ||
if (strncmp(dst, "foob", sizeof(dst)) != 0) | ||
pr_warn("FAIL: after strscpy() dst does not contain \"foob\" but \"%s\"\n", | ||
dst); | ||
|
||
/* Shrink src so the strscpy() below succeeds. */ | ||
src[3] = '\0'; | ||
|
||
/* | ||
* Vanilla strscpy returns number of character copied if everything goes | ||
* well. | ||
*/ | ||
if (strscpy(dst, src, sizeof(dst)) != 3) | ||
pr_warn("FAIL: strscpy() did not return 3 while src was copied entirely truncated\n"); | ||
|
||
/* After above call, dst must contain "foo" because src was copied. */ | ||
if (strncmp(dst, "foo", sizeof(dst)) != 0) | ||
pr_warn("FAIL: after strscpy() dst does not contain \"foo\" but \"%s\"\n", | ||
dst); | ||
|
||
/* Test when src is embedded inside a union. */ | ||
strscpy(weird_dst, weird.src, sizeof(weird_dst)); | ||
|
||
if (strcmp(weird_dst, "hello") != 0) | ||
pr_warn("FAIL: after strscpy() weird_dst does not contain \"hello\" but \"%s\"\n", | ||
weird_dst); | ||
|
||
/* Restore src to its initial value. */ | ||
src[3] = 'b'; | ||
|
||
/* | ||
* Use strlen here so size cannot be known at compile time and there is | ||
* a runtime write overflow. | ||
*/ | ||
strscpy(dst, src, strlen(src)); | ||
|
||
pr_warn("FAIL: No overflow in above strscpy()\n"); | ||
|
||
kfree(src); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters