strncpy_from_user and strnlen_user accept user addresses as arguments, and
do not go through the same path as copy_from_user and others, so here we
need to handle the case of tagged user addresses separately.

Untag user pointers passed to these functions.

Signed-off-by: Andrey Konovalov <andreyk...@google.com>
---
 lib/strncpy_from_user.c | 2 ++
 lib/strnlen_user.c      | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/lib/strncpy_from_user.c b/lib/strncpy_from_user.c
index b53e1b5d80f4..97467cd2bc59 100644
--- a/lib/strncpy_from_user.c
+++ b/lib/strncpy_from_user.c
@@ -106,6 +106,8 @@ long strncpy_from_user(char *dst, const char __user *src, 
long count)
        if (unlikely(count <= 0))
                return 0;
 
+       src = untagged_addr(src);
+
        max_addr = user_addr_max();
        src_addr = (unsigned long)src;
        if (likely(src_addr < max_addr)) {
diff --git a/lib/strnlen_user.c b/lib/strnlen_user.c
index 60d0bbda8f5e..8b5f56466e00 100644
--- a/lib/strnlen_user.c
+++ b/lib/strnlen_user.c
@@ -108,6 +108,8 @@ long strnlen_user(const char __user *str, long count)
        if (unlikely(count <= 0))
                return 0;
 
+       str = untagged_addr(str);
+
        max_addr = user_addr_max();
        src_addr = (unsigned long)str;
        if (likely(src_addr < max_addr)) {
-- 
2.20.0.rc2.403.gdbc3b29805-goog

Reply via email to