aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile1
-rw-r--r--lib/bitmap.c50
-rw-r--r--lib/kstrtox.c6
-rw-r--r--lib/strncpy_from_user.c2
4 files changed, 50 insertions, 9 deletions
diff --git a/lib/Makefile b/lib/Makefile
index f3ca8c0ab634..50144a3aeebd 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -180,6 +180,7 @@ obj-$(CONFIG_IRQ_POLL) += irq_poll.o
180 180
181obj-$(CONFIG_STACKDEPOT) += stackdepot.o 181obj-$(CONFIG_STACKDEPOT) += stackdepot.o
182KASAN_SANITIZE_stackdepot.o := n 182KASAN_SANITIZE_stackdepot.o := n
183KCOV_INSTRUMENT_stackdepot.o := n
183 184
184libfdt_files = fdt.o fdt_ro.o fdt_wip.o fdt_rw.o fdt_sw.o fdt_strerror.o \ 185libfdt_files = fdt.o fdt_ro.o fdt_wip.o fdt_rw.o fdt_sw.o fdt_strerror.o \
185 fdt_empty_tree.o 186 fdt_empty_tree.o
diff --git a/lib/bitmap.c b/lib/bitmap.c
index eca88087fa8a..0b66f0e5eb6b 100644
--- a/lib/bitmap.c
+++ b/lib/bitmap.c
@@ -496,6 +496,11 @@ EXPORT_SYMBOL(bitmap_print_to_pagebuf);
496 * ranges. Consecutively set bits are shown as two hyphen-separated 496 * ranges. Consecutively set bits are shown as two hyphen-separated
497 * decimal numbers, the smallest and largest bit numbers set in 497 * decimal numbers, the smallest and largest bit numbers set in
498 * the range. 498 * the range.
499 * Optionally each range can be postfixed to denote that only parts of it
500 * should be set. The range will divided to groups of specific size.
501 * From each group will be used only defined amount of bits.
502 * Syntax: range:used_size/group_size
503 * Example: 0-1023:2/256 ==> 0,1,256,257,512,513,768,769
499 * 504 *
500 * Returns 0 on success, -errno on invalid input strings. 505 * Returns 0 on success, -errno on invalid input strings.
501 * Error values: 506 * Error values:
@@ -507,16 +512,20 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
507 int is_user, unsigned long *maskp, 512 int is_user, unsigned long *maskp,
508 int nmaskbits) 513 int nmaskbits)
509{ 514{
510 unsigned a, b; 515 unsigned int a, b, old_a, old_b;
516 unsigned int group_size, used_size;
511 int c, old_c, totaldigits, ndigits; 517 int c, old_c, totaldigits, ndigits;
512 const char __user __force *ubuf = (const char __user __force *)buf; 518 const char __user __force *ubuf = (const char __user __force *)buf;
513 int at_start, in_range; 519 int at_start, in_range, in_partial_range;
514 520
515 totaldigits = c = 0; 521 totaldigits = c = 0;
522 old_a = old_b = 0;
523 group_size = used_size = 0;
516 bitmap_zero(maskp, nmaskbits); 524 bitmap_zero(maskp, nmaskbits);
517 do { 525 do {
518 at_start = 1; 526 at_start = 1;
519 in_range = 0; 527 in_range = 0;
528 in_partial_range = 0;
520 a = b = 0; 529 a = b = 0;
521 ndigits = totaldigits; 530 ndigits = totaldigits;
522 531
@@ -547,6 +556,24 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
547 if ((totaldigits != ndigits) && isspace(old_c)) 556 if ((totaldigits != ndigits) && isspace(old_c))
548 return -EINVAL; 557 return -EINVAL;
549 558
559 if (c == '/') {
560 used_size = a;
561 at_start = 1;
562 in_range = 0;
563 a = b = 0;
564 continue;
565 }
566
567 if (c == ':') {
568 old_a = a;
569 old_b = b;
570 at_start = 1;
571 in_range = 0;
572 in_partial_range = 1;
573 a = b = 0;
574 continue;
575 }
576
550 if (c == '-') { 577 if (c == '-') {
551 if (at_start || in_range) 578 if (at_start || in_range)
552 return -EINVAL; 579 return -EINVAL;
@@ -567,15 +594,30 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
567 } 594 }
568 if (ndigits == totaldigits) 595 if (ndigits == totaldigits)
569 continue; 596 continue;
597 if (in_partial_range) {
598 group_size = a;
599 a = old_a;
600 b = old_b;
601 old_a = old_b = 0;
602 }
570 /* if no digit is after '-', it's wrong*/ 603 /* if no digit is after '-', it's wrong*/
571 if (at_start && in_range) 604 if (at_start && in_range)
572 return -EINVAL; 605 return -EINVAL;
573 if (!(a <= b)) 606 if (!(a <= b) || !(used_size <= group_size))
574 return -EINVAL; 607 return -EINVAL;
575 if (b >= nmaskbits) 608 if (b >= nmaskbits)
576 return -ERANGE; 609 return -ERANGE;
577 while (a <= b) { 610 while (a <= b) {
578 set_bit(a, maskp); 611 if (in_partial_range) {
612 static int pos_in_group = 1;
613
614 if (pos_in_group <= used_size)
615 set_bit(a, maskp);
616
617 if (a == b || ++pos_in_group > group_size)
618 pos_in_group = 1;
619 } else
620 set_bit(a, maskp);
579 a++; 621 a++;
580 } 622 }
581 } while (buflen && c == ','); 623 } while (buflen && c == ',');
diff --git a/lib/kstrtox.c b/lib/kstrtox.c
index d8a5cf66c316..b8e2080c1a47 100644
--- a/lib/kstrtox.c
+++ b/lib/kstrtox.c
@@ -48,11 +48,9 @@ unsigned int _parse_integer(const char *s, unsigned int base, unsigned long long
48{ 48{
49 unsigned long long res; 49 unsigned long long res;
50 unsigned int rv; 50 unsigned int rv;
51 int overflow;
52 51
53 res = 0; 52 res = 0;
54 rv = 0; 53 rv = 0;
55 overflow = 0;
56 while (*s) { 54 while (*s) {
57 unsigned int val; 55 unsigned int val;
58 56
@@ -71,15 +69,13 @@ unsigned int _parse_integer(const char *s, unsigned int base, unsigned long long
71 */ 69 */
72 if (unlikely(res & (~0ull << 60))) { 70 if (unlikely(res & (~0ull << 60))) {
73 if (res > div_u64(ULLONG_MAX - val, base)) 71 if (res > div_u64(ULLONG_MAX - val, base))
74 overflow = 1; 72 rv |= KSTRTOX_OVERFLOW;
75 } 73 }
76 res = res * base + val; 74 res = res * base + val;
77 rv++; 75 rv++;
78 s++; 76 s++;
79 } 77 }
80 *p = res; 78 *p = res;
81 if (overflow)
82 rv |= KSTRTOX_OVERFLOW;
83 return rv; 79 return rv;
84} 80}
85 81
diff --git a/lib/strncpy_from_user.c b/lib/strncpy_from_user.c
index 9c5fe8110413..7e35fc450c5b 100644
--- a/lib/strncpy_from_user.c
+++ b/lib/strncpy_from_user.c
@@ -1,6 +1,7 @@
1#include <linux/compiler.h> 1#include <linux/compiler.h>
2#include <linux/export.h> 2#include <linux/export.h>
3#include <linux/kasan-checks.h> 3#include <linux/kasan-checks.h>
4#include <linux/thread_info.h>
4#include <linux/uaccess.h> 5#include <linux/uaccess.h>
5#include <linux/kernel.h> 6#include <linux/kernel.h>
6#include <linux/errno.h> 7#include <linux/errno.h>
@@ -111,6 +112,7 @@ long strncpy_from_user(char *dst, const char __user *src, long count)
111 long retval; 112 long retval;
112 113
113 kasan_check_write(dst, count); 114 kasan_check_write(dst, count);
115 check_object_size(dst, count, false);
114 user_access_begin(); 116 user_access_begin();
115 retval = do_strncpy_from_user(dst, src, count, max); 117 retval = do_strncpy_from_user(dst, src, count, max);
116 user_access_end(); 118 user_access_end();