Fortify warning in net/xfrm/xfrm_user.c with arm64 CONFIG_KASAN=y after LLVM commit 90ba33099cbb1
Opened this issue · 0 comments
nathanchance commented
This is the same warning as #1985 but it only appears when KASAN is enabled, as reported by @arndb at https://lore.kernel.org/763214eb-20eb-4627-8d4b-2e7f29db829a@app.fastmail.com/.
$ echo 'CONFIG_FORTIFY_SOURCE=y
CONFIG_KASAN=y
CONFIG_XFRM_USER=y' >arch/arm64/configs/repro.config
$ make -skj"$(nproc)" ARCH=arm64 LLVM=1 {def,repro.}config net/xfrm/xfrm_user.o
In file included from net/xfrm/xfrm_user.c:14:
In file included from include/linux/compat.h:10:
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/arm64/include/asm/timex.h:8:
In file included from arch/arm64/include/asm/arch_timer.h:12:
In file included from arch/arm64/include/asm/hwcap.h:9:
In file included from arch/arm64/include/asm/cpufeature.h:27:
In file included from include/linux/cpumask.h:13:
In file included from include/linux/bitmap.h:13:
In file included from include/linux/string.h:371:
include/linux/fortify-string.h:462:4: warning: call to '__write_overflow_field' declared with 'warning' attribute: detected write beyond size of field (1st parameter); maybe use struct_group()? [-Wattribute-warning]
462 | __write_overflow_field(p_size_field, size);
| ^
1 warning generated.
This is with 6.9-rc4, which contains my change to fix #1985.
cvise
spits out:
enum { false } __fortify_panic() __attribute__((__noreturn__));
struct xfrm_id {
int daddr;
int spi;
char proto;
};
struct xfrm_user_tmpl {
struct xfrm_id id;
short share;
char optional;
int calgos;
} copy_to_user_tmpl_vec[6];
struct xfrm_tmpl {
char optional;
int ealgos;
int calgos;
};
struct {
char xfrm_nr;
struct xfrm_tmpl xfrm_vec[];
} *copy_to_user_tmpl_xp;
void __write_overflow_field()
__attribute__((__warning__("detected write beyond size of field (1st "
"parameter); maybe use struct_group()?")));
void *__underlying_memcpy(void *, void *, long) __asm__("memcpy");
_Bool fortify_memset_chk(unsigned long size, unsigned long p_size,
unsigned long p_size_field) {
if (__builtin_constant_p(p_size_field < size) && p_size_field < size)
__write_overflow_field();
if (p_size < size)
__fortify_panic();
return false;
}
int copy_to_user_tmpl() {
unsigned long __trans_tmp_4, __trans_tmp_3;
int i;
if (copy_to_user_tmpl_xp)
return 5;
for (i = 0; copy_to_user_tmpl_xp->xfrm_nr; i++) {
struct xfrm_user_tmpl *up = ©_to_user_tmpl_vec[i];
struct xfrm_tmpl kp = copy_to_user_tmpl_xp->xfrm_vec[i];
unsigned long __fortify_size = sizeof(up);
__trans_tmp_3 = __trans_tmp_4 = __builtin_dynamic_object_size(up, 1);
fortify_memset_chk(__fortify_size, __trans_tmp_3, __trans_tmp_4);
__fortify_size = sizeof(up->id);
__underlying_memcpy(up, &kp, __fortify_size);
up->share = up->optional = copy_to_user_tmpl_xp->xfrm_vec[i].ealgos;
up->calgos = copy_to_user_tmpl_xp->xfrm_vec[i].calgos;
}
return 0;
}
GCC 13.2.0:
$ aarch64-linux-gcc -O2 -Wall -Wextra -Werror -Wfatal-errors -c -o /dev/null xfrm_user.i
$ aarch64-linux-gcc -O2 -Wall -Wextra -Werror -Wfatal-errors -c -o /dev/null xfrm_user.i -fsanitize=kernel-address
clang @ llvm/llvm-project@98509c7
$ clang -O2 -Wall -Wextra -Werror -Wfatal-errors -c -o /dev/null xfrm_user.i
$ clang -O2 -Wall -Wextra -Werror -Wfatal-errors -c -o /dev/null xfrm_user.i -fsanitize=kernel-address
clang @ llvm/llvm-project@90ba330
$ clang -O2 -Wall -Wextra -Werror -Wfatal-errors -c -o /dev/null xfrm_user.i
$ clang -O2 -Wall -Wextra -Werror -Wfatal-errors -c -o /dev/null xfrm_user.i -fsanitize=kernel-address
xfrm_user.i:29:5: fatal error: call to '__write_overflow_field' declared with 'warning' attribute: detected write beyond size of field (1st parameter); maybe use struct_group()? [-Wattribute-warning]
29 | __write_overflow_field();
| ^
1 error generated.