diff options
author | Ramsay Jones <ramsay@ramsayjones.plus.com> | 2021-09-28 00:43:31 +0100 |
---|---|---|
committer | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2022-05-20 10:54:33 +0200 |
commit | 4cd76bd9eeb3777219a307893e33d072df05eb37 (patch) | |
tree | a8e28b8b6455d036385dbfbe3ac60049d507b78c | |
parent | c4706aa764f3ae68258ba60be6325a5662900362 (diff) | |
download | sparse-4cd76bd9eeb3777219a307893e33d072df05eb37.tar.gz |
sparse: fix broken 'memcpy-max-count' check
commit a69f8d70 ("ptrlist: use ptr_list_nth() instead of linearize_ptr_\
list()", 2021-02-14) replaced a call to a local helper with a more generic
ptr_list function. The local function, argument(), was used to retrieve
the 'argno' argument to a function call, counting the arguments from one.
This call was replaced by the generic ptr_list_nth() function, which
accessed the ptr_list counting from zero. The 'argno' passed to the call to
argument() was 3 (the byte count), which when passed to ptr_list_nth()
was attempting to access the 4th (non-existent) argument. (The resulting
null pointer was then passed to check_byte_count() function, which had
an null-pointer check and so did not dereference the null pointer). This
effectively disabled the memcpy-max-count check.
In order to fix the check, change the 'argno' of 3 to the 'index' of 2.
Also, add a simple regression test.
Signed-off-by: Ramsay Jones <ramsay@ramsayjones.plus.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
-rw-r--r-- | sparse.c | 2 | ||||
-rw-r--r-- | validation/byte-count-max.c | 28 |
2 files changed, 29 insertions, 1 deletions
@@ -165,7 +165,7 @@ static void check_byte_count(struct instruction *insn, pseudo_t count) static void check_memset(struct instruction *insn) { - check_byte_count(insn, ptr_list_nth(insn->arguments, 3)); + check_byte_count(insn, ptr_list_nth(insn->arguments, 2)); } #define check_memcpy check_memset diff --git a/validation/byte-count-max.c b/validation/byte-count-max.c new file mode 100644 index 00000000..0555a505 --- /dev/null +++ b/validation/byte-count-max.c @@ -0,0 +1,28 @@ +typedef unsigned long int size_t; +typedef unsigned long ulong; + +extern void *memset(void *s, int c, size_t n); +extern void *memcpy(void *dest, void *src, size_t n); +extern ulong copy_to_user(void *to, const void *from, ulong count); +extern ulong copy_from_user(void *to, const void *from, ulong count); + +static void func (char *s) +{ + char d[250000]; + + memset(d, 0, 250000); + memcpy(d, s, 250000); + copy_to_user(s, d, 250000); + copy_from_user(d, s, 250000); +} + +/* + * check-name: byte-count-max + * + * check-error-start +byte-count-max.c:13:15: warning: memset with byte count of 250000 +byte-count-max.c:14:15: warning: memcpy with byte count of 250000 +byte-count-max.c:15:21: warning: copy_to_user with byte count of 250000 +byte-count-max.c:16:23: warning: copy_from_user with byte count of 250000 + * check-error-end + */ |