From 4cd76bd9eeb3777219a307893e33d072df05eb37 Mon Sep 17 00:00:00 2001 From: Ramsay Jones Date: Tue, 28 Sep 2021 00:43:31 +0100 Subject: 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 Signed-off-by: Luc Van Oostenryck --- sparse.c | 2 +- validation/byte-count-max.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 validation/byte-count-max.c diff --git a/sparse.c b/sparse.c index 9d62d4fe..e7cc6f55 100644 --- a/sparse.c +++ b/sparse.c @@ -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 + */ -- cgit 1.2.3-korg