2022-10-19 19:38:52

by Jane Chu

[permalink] [raw]
Subject: [PATCH v3 0/1] vsprintf: check non-canonical pointer by kern_addr_valid()

Changes since v2 [1]:
- revised commit comment for clarification;
- cc linux-mm for expert's review on the kern_addr_valid() usage as suggested by Petr;
- cc Kefeng Wang in light of his recent patch [2]

[1]: https://lore.kernel.org/lkml/[email protected]/T/
[2]: https://lore.kernel.org/lkml/[email protected]/

Jane Chu (1):
vsprintf: protect kernel from panic due to non-canonical pointer
dereference

lib/vsprintf.c | 3 +++
1 file changed, 3 insertions(+)

--
2.18.4


2022-10-19 19:50:28

by Jane Chu

[permalink] [raw]
Subject: [PATCH v3 1/1] vsprintf: protect kernel from panic due to non-canonical pointer dereference

Having stepped on a local kernel bug where reading sysfs has led to
out-of-bound pointer dereference by vsprintf() which led to GPF panic.
And the reason for GPF is that the OOB pointer was turned to a
non-canonical address such as 0x7665645f63616465.

vsprintf() already has this line of defense
if ((unsigned long)ptr < PAGE_SIZE || IS_ERR_VALUE(ptr))
return "(efault)";
Since a non-canonical pointer can be detected by kern_addr_valid()
on architectures that present VM holes as well as meaningful
implementation of kern_addr_valid() that detects the non-canonical
addresses, this patch addes a check on non-canonical string pointer by
kern_addr_valid() and display "(efault)" to alert user that something
is wrong instead of unecessarily panic the server.

On the other hand, if the non-canonical string pointer is dereferenced
else where in the kernel, by virtue of being non-canonical, a crash
is expected to be immediate.

Signed-off-by: Jane Chu <[email protected]>
---
lib/vsprintf.c | 3 +++
1 file changed, 3 insertions(+)

diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index c414a8d9f1ea..b38c12ef1e45 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -698,6 +698,9 @@ static const char *check_pointer_msg(const void *ptr)
if ((unsigned long)ptr < PAGE_SIZE || IS_ERR_VALUE(ptr))
return "(efault)";

+ if (!kern_addr_valid((unsigned long)ptr))
+ return "(efault)";
+
return NULL;
}

--
2.18.4

2022-10-20 12:07:51

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH v3 1/1] vsprintf: protect kernel from panic due to non-canonical pointer dereference

Hi Jane,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on linus/master]
[also build test ERROR on v6.1-rc1]
[cannot apply to next-20221020]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url: https://github.com/intel-lab-lkp/linux/commits/Jane-Chu/vsprintf-check-non-canonical-pointer-by-kern_addr_valid/20221020-103535
patch link: https://lore.kernel.org/r/20221019193431.2923462-2-jane.chu%40oracle.com
patch subject: [PATCH v3 1/1] vsprintf: protect kernel from panic due to non-canonical pointer dereference
config: x86_64-rhel-8.3-func
compiler: gcc-11 (Debian 11.3.0-8) 11.3.0
reproduce (this is a W=1 build):
# https://github.com/intel-lab-lkp/linux/commit/7da79322bb256f65be136ef3ca3d557e42da8ffe
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Jane-Chu/vsprintf-check-non-canonical-pointer-by-kern_addr_valid/20221020-103535
git checkout 7da79322bb256f65be136ef3ca3d557e42da8ffe
# save the config file
mkdir build_dir && cp config build_dir/.config
make W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <[email protected]>

All errors (new ones prefixed by >>):

lib/vsprintf.c: In function 'check_pointer_msg':
>> lib/vsprintf.c:701:14: error: implicit declaration of function 'kern_addr_valid'; did you mean 'virt_addr_valid'? [-Werror=implicit-function-declaration]
701 | if (!kern_addr_valid((unsigned long)ptr))
| ^~~~~~~~~~~~~~~
| virt_addr_valid
lib/vsprintf.c: In function 'va_format':
lib/vsprintf.c:1688:9: warning: function 'va_format' might be a candidate for 'gnu_printf' format attribute [-Wsuggest-attribute=format]
1688 | buf += vsnprintf(buf, end > buf ? end - buf : 0, va_fmt->fmt, va);
| ^~~
cc1: some warnings being treated as errors


vim +701 lib/vsprintf.c

687
688 /*
689 * Do not call any complex external code here. Nested printk()/vsprintf()
690 * might cause infinite loops. Failures might break printk() and would
691 * be hard to debug.
692 */
693 static const char *check_pointer_msg(const void *ptr)
694 {
695 if (!ptr)
696 return "(null)";
697
698 if ((unsigned long)ptr < PAGE_SIZE || IS_ERR_VALUE(ptr))
699 return "(efault)";
700
> 701 if (!kern_addr_valid((unsigned long)ptr))
702 return "(efault)";
703
704 return NULL;
705 }
706

--
0-DAY CI Kernel Test Service
https://01.org/lkp


Attachments:
(No filename) (2.80 kB)
config (172.50 kB)
Download all attachments

2022-10-20 13:40:26

by Kefeng Wang

[permalink] [raw]
Subject: Re: [PATCH v3 0/1] vsprintf: check non-canonical pointer by kern_addr_valid()


On 2022/10/20 3:34, Jane Chu wrote:
> Changes since v2 [1]:
> - revised commit comment for clarification;
> - cc linux-mm for expert's review on the kern_addr_valid() usage as suggested by Petr;

but this won't fix issue on archs which don't have correct
kern_addr_valid(), right?

could we call copy_from_kernel_nofault() when it could works well, and
skip it on early boot?

other options, call some functions in include/asm-generic/sections.h  or
include/linux/kallsyms.h?


> - cc Kefeng Wang in light of his recent patch [2]
>
> [1]: https://lore.kernel.org/lkml/[email protected]/T/
> [2]: https://lore.kernel.org/lkml/[email protected]/
>
> Jane Chu (1):
> vsprintf: protect kernel from panic due to non-canonical pointer
> dereference
>
> lib/vsprintf.c | 3 +++
> 1 file changed, 3 insertions(+)
>