| From b69edab47f1da8edd8e7bfdf8c70f51a2a5d89fb Mon Sep 17 00:00:00 2001 |
| From: Kees Cook <keescook@chromium.org> |
| Date: Thu, 2 Mar 2023 14:49:50 -0800 |
| Subject: kheaders: Use array declaration instead of char |
| |
| From: Kees Cook <keescook@chromium.org> |
| |
| commit b69edab47f1da8edd8e7bfdf8c70f51a2a5d89fb upstream. |
| |
| Under CONFIG_FORTIFY_SOURCE, memcpy() will check the size of destination |
| and source buffers. Defining kernel_headers_data as "char" would trip |
| this check. Since these addresses are treated as byte arrays, define |
| them as arrays (as done everywhere else). |
| |
| This was seen with: |
| |
| $ cat /sys/kernel/kheaders.tar.xz >> /dev/null |
| |
| detected buffer overflow in memcpy |
| kernel BUG at lib/string_helpers.c:1027! |
| ... |
| RIP: 0010:fortify_panic+0xf/0x20 |
| [...] |
| Call Trace: |
| <TASK> |
| ikheaders_read+0x45/0x50 [kheaders] |
| kernfs_fop_read_iter+0x1a4/0x2f0 |
| ... |
| |
| Reported-by: Jakub Kicinski <kuba@kernel.org> |
| Link: https://lore.kernel.org/bpf/20230302112130.6e402a98@kernel.org/ |
| Acked-by: Joel Fernandes (Google) <joel@joelfernandes.org> |
| Reviewed-by: Alexander Lobakin <aleksander.lobakin@intel.com> |
| Tested-by: Jakub Kicinski <kuba@kernel.org> |
| Fixes: 43d8ce9d65a5 ("Provide in-kernel headers to make extending kernel easier") |
| Cc: stable@vger.kernel.org |
| Signed-off-by: Kees Cook <keescook@chromium.org> |
| Link: https://lore.kernel.org/r/20230302224946.never.243-kees@kernel.org |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| kernel/kheaders.c | 10 +++++----- |
| 1 file changed, 5 insertions(+), 5 deletions(-) |
| |
| --- a/kernel/kheaders.c |
| +++ b/kernel/kheaders.c |
| @@ -26,15 +26,15 @@ asm ( |
| " .popsection \n" |
| ); |
| |
| -extern char kernel_headers_data; |
| -extern char kernel_headers_data_end; |
| +extern char kernel_headers_data[]; |
| +extern char kernel_headers_data_end[]; |
| |
| static ssize_t |
| ikheaders_read(struct file *file, struct kobject *kobj, |
| struct bin_attribute *bin_attr, |
| char *buf, loff_t off, size_t len) |
| { |
| - memcpy(buf, &kernel_headers_data + off, len); |
| + memcpy(buf, &kernel_headers_data[off], len); |
| return len; |
| } |
| |
| @@ -48,8 +48,8 @@ static struct bin_attribute kheaders_att |
| |
| static int __init ikheaders_init(void) |
| { |
| - kheaders_attr.size = (&kernel_headers_data_end - |
| - &kernel_headers_data); |
| + kheaders_attr.size = (kernel_headers_data_end - |
| + kernel_headers_data); |
| return sysfs_create_bin_file(kernel_kobj, &kheaders_attr); |
| } |
| |