lib/strscpy: Shut up KASAN false-positives in strscpy() [Linux 4.9.187]

This Linux kernel change "lib/strscpy: Shut up KASAN false-positives in strscpy()" is included in the Linux 4.9.187 release. This change is authored by Andrey Ryabinin <aryabinin [at] virtuozzo.com> on Thu Feb 1 21:00:50 2018 +0300. The commit for this change in Linux stable tree is 8dd8b4d (patch) which is from upstream commit 1a3241f. The same Linux upstream change may have been applied to various maintained Linux releases and you can find all Linux releases containing changes from upstream 1a3241f.

lib/strscpy: Shut up KASAN false-positives in strscpy()

[ Upstream commit 1a3241ff10d038ecd096d03380327f2a0b5840a6 ]

strscpy() performs the word-at-a-time optimistic reads.  So it may may
access the memory past the end of the object, which is perfectly fine
since strscpy() doesn't use that (past-the-end) data and makes sure the
optimistic read won't cross a page boundary.

Use new read_word_at_a_time() to shut up the KASAN.

Note that this potentially could hide some bugs.  In example bellow,
stscpy() will copy more than we should (1-3 extra uninitialized bytes):

        char dst[8];
        char *src;

        src = kmalloc(5, GFP_KERNEL);
        memset(src, 0xff, 5);
        strscpy(dst, src, 8);

Signed-off-by: Andrey Ryabinin <aryabinin@virtuozzo.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>

There are 2 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 lib/string.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/string.c b/lib/string.c
index 1cd9757..8f1a2a0 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -202,7 +202,7 @@ ssize_t strscpy(char *dest, const char *src, size_t count)
    while (max >= sizeof(unsigned long)) {
        unsigned long c, data;

-       c = *(unsigned long *)(src+res);
+       c = read_word_at_a_time(src+res);
        if (has_zero(c, &data, &constants)) {
            data = prep_zero_mask(c, data, &constants);
            data = create_zero_mask(data);

Leave a Reply

Your email address will not be published. Required fields are marked *