Skip to content

function with error attribute not eliminated after commit 3589cacfa8da8 #85647

Open
@nathanchance

Description

@nathanchance

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions