Open
Description
This is a copy of the downstream report: ClangBuiltLinux/linux#2007
After 3589cac, I see the following error when building the Linux kernel for x86_64 using the allmodconfig
configuration target, which enables CONFIG_KCSAN
(i.e, -fsanitize=thread
):
$ make -skj"$(nproc)" ARCH=x86_64 LLVM=1 clean allmodconfig net/bluetooth/sco.o
In file included from net/bluetooth/sco.c:27:
In file included from include/linux/module.h:13:
In file included from include/linux/stat.h:19:
In file included from include/linux/time.h:60:
In file included from include/linux/time32.h:13:
In file included from include/linux/timex.h:67:
In file included from arch/x86/include/asm/timex.h:6:
In file included from arch/x86/include/asm/tsc.h:10:
In file included from arch/x86/include/asm/msr.h:15:
In file included from include/linux/percpu.h:7:
In file included from include/linux/smp.h:118:
include/linux/thread_info.h:244:4: error: call to '__bad_copy_from' declared with 'error' attribute: copy source size is too small
244 | __bad_copy_from();
| ^
1 error generated.
which comes from check_copy_size()
in copy_to_user()
. I also see the same error emitted in net/bluetooth/l2cap_sock.c
. If I disable CONFIG_KCSAN, there is no error. The parent of 3589cac does not show this error and GCC does not show an error either, so I am not sure the kernel code is at fault here but I could be missing something obvious.
cvise
spits out:
struct {
short hci_handledev_class[3];
} sco_sock_getsockopt_old_cinfo;
typeof(__builtin_choose_expr(
sizeof(char), 0,
__builtin_choose_expr(
sizeof(short), 0,
__builtin_choose_expr(sizeof(int), 0,
__builtin_choose_expr(sizeof(long), 0, 0)))))
sco_sock_getsockopt_old___val_gu;
void kmsan_unpoison_memory(void *address) {}
void __attribute__((__error__("copy source size is too small")))
__bad_copy_from();
long copy_to_user(void *from, long n) {
void *addr = from;
long bytes = n;
int sz = __builtin_object_size(addr, 0);
if (__builtin_expect(sz >= 0 && sz < bytes, 0))
__bad_copy_from();
return 0;
}
int sco_sock_getsockopt_old() {
int len;
long __tmp = sco_sock_getsockopt_old___val_gu;
kmsan_unpoison_memory(&__tmp);
len = __tmp;
len = __builtin_choose_expr(
0, 0, ({
typeof(0) __UNIQUE_ID___x1646 = len;
unsigned __UNIQUE_ID___y1647 = sizeof(sco_sock_getsockopt_old_cinfo);
__UNIQUE_ID___x1646 < __UNIQUE_ID___y1647 ? __UNIQUE_ID___x1646 : 0;
}));
copy_to_user(&sco_sock_getsockopt_old_cinfo, len);
return 0;
}
GCC 13.2.0:
$ x86_64-linux-gcc -O2 -Wall -c -o /dev/null sco.i
$ x86_64-linux-gcc -O2 -Wall -fsanitize=thread -c -o /dev/null sco.i
Clang @ 0cbbcf1:
$ clang -O2 -Wall -c -o /dev/null sco.i
$ clang -O2 -Wall -fsanitize=thread -c -o /dev/null sco.i
Clang @ 3589cac:
$ clang -O2 -Wall -c -o /dev/null sco.i
$ clang -O2 -Wall -fsanitize=thread -c -o /dev/null sco.i
sco.i:19:5: error: call to '__bad_copy_from' declared with 'error' attribute: copy source size is too small
19 | __bad_copy_from();
| ^
1 error generated.
cc @dtcxzyw