diff options
author | Christophe Leroy <christophe.leroy@c-s.fr> | 2020-01-23 08:34:18 +0000 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2020-01-29 16:45:29 +0100 |
commit | 9f6216862a2075474fa985ea3b801c2ac4b41de3 (patch) | |
tree | 91dbd12d7b628f110c28aefc309db4a9d55170c0 /lib/strnlen_user.c | |
parent | 9e2e1a5abccd3a4cd331549399c6ff4008aa4bba (diff) | |
download | linux-stable-9f6216862a2075474fa985ea3b801c2ac4b41de3.tar.gz linux-stable-9f6216862a2075474fa985ea3b801c2ac4b41de3.tar.bz2 linux-stable-9f6216862a2075474fa985ea3b801c2ac4b41de3.zip |
lib: Reduce user_access_begin() boundaries in strncpy_from_user() and strnlen_user()
commit ab10ae1c3bef56c29bac61e1201c752221b87b41 upstream.
The range passed to user_access_begin() by strncpy_from_user() and
strnlen_user() starts at 'src' and goes up to the limit of userspace
although reads will be limited by the 'count' param.
On 32 bits powerpc (book3s/32) access has to be granted for each
256Mbytes segment and the cost increases with the number of segments to
unlock.
Limit the range with 'count' param.
Fixes: 594cc251fdd0 ("make 'user_access_begin()' do 'access_ok()'")
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'lib/strnlen_user.c')
-rw-r--r-- | lib/strnlen_user.c | 14 |
1 files changed, 7 insertions, 7 deletions
diff --git a/lib/strnlen_user.c b/lib/strnlen_user.c index 6c0005d5dd5c..41670d4a5816 100644 --- a/lib/strnlen_user.c +++ b/lib/strnlen_user.c @@ -27,13 +27,6 @@ static inline long do_strnlen_user(const char __user *src, unsigned long count, unsigned long c; /* - * Truncate 'max' to the user-specified limit, so that - * we only have one limit we need to check in the loop - */ - if (max > count) - max = count; - - /* * Do everything aligned. But that means that we * need to also expand the maximum.. */ @@ -109,6 +102,13 @@ long strnlen_user(const char __user *str, long count) unsigned long max = max_addr - src_addr; long retval; + /* + * Truncate 'max' to the user-specified limit, so that + * we only have one limit we need to check in the loop + */ + if (max > count) + max = count; + if (user_access_begin(str, max)) { retval = do_strnlen_user(str, count, max); user_access_end(); |