Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests/bpf: Attempt to build BPF programs with -Wsign-compare

GCC's -Wall includes -Wsign-compare while clang does not.
Since BPF programs are built with clang we need to add this flag explicitly
to catch problematic comparisons like:

int i = -1;
unsigned int j = 1;
if (i < j) // this is false.

long i = -1;
unsigned int j = 1;
if (i < j) // this is true.

C standard for reference:

- If either operand is unsigned long the other shall be converted to unsigned long.

- Otherwise, if one operand is a long int and the other unsigned int, then if a
long int can represent all the values of an unsigned int, the unsigned int
shall be converted to a long int; otherwise both operands shall be converted to
unsigned long int.

- Otherwise, if either operand is long, the other shall be converted to long.

- Otherwise, if either operand is unsigned, the other shall be converted to unsigned.

Unfortunately clang's -Wsign-compare is very noisy.
It complains about (s32)a == (u32)b which is safe and doen't have surprising behavior.

This patch fixes some of the issues. It needs a follow up to fix the rest.

Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Acked-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/bpf/20231226191148.48536-2-alexei.starovoitov@gmail.com

authored by

Alexei Starovoitov and committed by
Andrii Nakryiko
495d2d81 a640de4c

+30 -29
+1
tools/testing/selftests/bpf/Makefile
··· 383 383 BPF_CFLAGS = -g -Wall -Werror -D__TARGET_ARCH_$(SRCARCH) $(MENDIAN) \ 384 384 -I$(INCLUDE_DIR) -I$(CURDIR) -I$(APIDIR) \ 385 385 -I$(abspath $(OUTPUT)/../usr/include) 386 + # TODO: enable me -Wsign-compare 386 387 387 388 CLANG_CFLAGS = $(CLANG_SYS_INCLUDES) \ 388 389 -Wno-compare-distinct-pointer-types
+1 -1
tools/testing/selftests/bpf/progs/bpf_iter_bpf_percpu_hash_map.c
··· 20 20 } hashmap1 SEC(".maps"); 21 21 22 22 /* will set before prog run */ 23 - volatile const __u32 num_cpus = 0; 23 + volatile const __s32 num_cpus = 0; 24 24 25 25 /* will collect results during prog run */ 26 26 __u32 key_sum_a = 0, key_sum_b = 0, key_sum_c = 0;
+1 -1
tools/testing/selftests/bpf/progs/bpf_iter_task_vmas.c
··· 35 35 return 0; 36 36 37 37 file = vma->vm_file; 38 - if (task->tgid != pid) { 38 + if (task->tgid != (pid_t)pid) { 39 39 if (one_task) 40 40 one_task_error = 1; 41 41 return 0;
+1 -1
tools/testing/selftests/bpf/progs/bpf_iter_tasks.c
··· 22 22 return 0; 23 23 } 24 24 25 - if (task->pid != tid) 25 + if (task->pid != (pid_t)tid) 26 26 num_unknown_tid++; 27 27 else 28 28 num_known_tid++;
+1 -1
tools/testing/selftests/bpf/progs/bpf_iter_test_kern4.c
··· 45 45 } 46 46 47 47 /* fill seq_file buffer */ 48 - for (i = 0; i < print_len; i++) 48 + for (i = 0; i < (int)print_len; i++) 49 49 bpf_seq_write(seq, &seq_num, sizeof(seq_num)); 50 50 51 51 return ret;
+1 -1
tools/testing/selftests/bpf/progs/cgroup_getset_retval_setsockopt.c
··· 11 11 __u32 invocations = 0; 12 12 __u32 assertion_error = 0; 13 13 __u32 retval_value = 0; 14 - __u32 page_size = 0; 14 + __s32 page_size = 0; 15 15 16 16 SEC("cgroup/setsockopt") 17 17 int get_retval(struct bpf_sockopt *ctx)
+1 -1
tools/testing/selftests/bpf/progs/cgrp_ls_sleepable.c
··· 15 15 __type(value, long); 16 16 } map_a SEC(".maps"); 17 17 18 - __u32 target_pid; 18 + __s32 target_pid; 19 19 __u64 cgroup_id; 20 20 int target_hid; 21 21 bool is_cgroup1;
+1 -1
tools/testing/selftests/bpf/progs/cpumask_success.c
··· 332 332 int BPF_PROG(test_copy_any_anyand, struct task_struct *task, u64 clone_flags) 333 333 { 334 334 struct bpf_cpumask *mask1, *mask2, *dst1, *dst2; 335 - u32 cpu; 335 + int cpu; 336 336 337 337 if (!is_test_task()) 338 338 return 0;
+2 -2
tools/testing/selftests/bpf/progs/iters.c
··· 6 6 #include <bpf/bpf_helpers.h> 7 7 #include "bpf_misc.h" 8 8 9 - #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 9 + #define ARRAY_SIZE(x) (int)(sizeof(x) / sizeof((x)[0])) 10 10 11 11 static volatile int zero = 0; 12 12 ··· 676 676 677 677 while ((t = bpf_iter_num_next(it))) { 678 678 i = *t; 679 - if (i >= n) 679 + if ((__u32)i >= n) 680 680 break; 681 681 sum += arr[i]; 682 682 }
+1 -1
tools/testing/selftests/bpf/progs/linked_funcs1.c
··· 8 8 #include "bpf_misc.h" 9 9 10 10 /* weak and shared between two files */ 11 - const volatile int my_tid __weak; 11 + const volatile __u32 my_tid __weak; 12 12 long syscall_id __weak; 13 13 14 14 int output_val1;
+1 -1
tools/testing/selftests/bpf/progs/linked_funcs2.c
··· 68 68 { 69 69 static volatile int whatever; 70 70 71 - if (my_tid != (u32)bpf_get_current_pid_tgid() || id != syscall_id) 71 + if (my_tid != (s32)bpf_get_current_pid_tgid() || id != syscall_id) 72 72 return 0; 73 73 74 74 /* make sure we have CO-RE relocations in main program */
+1 -1
tools/testing/selftests/bpf/progs/linked_list.c
··· 6 6 #include "bpf_experimental.h" 7 7 8 8 #ifndef ARRAY_SIZE 9 - #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 9 + #define ARRAY_SIZE(x) (int)(sizeof(x) / sizeof((x)[0])) 10 10 #endif 11 11 12 12 #include "linked_list.h"
+1 -1
tools/testing/selftests/bpf/progs/local_storage.c
··· 13 13 14 14 #define DUMMY_STORAGE_VALUE 0xdeadbeef 15 15 16 - int monitored_pid = 0; 16 + __u32 monitored_pid = 0; 17 17 int inode_storage_result = -1; 18 18 int sk_storage_result = -1; 19 19 int task_storage_result = -1;
+1 -1
tools/testing/selftests/bpf/progs/lsm.c
··· 92 92 if (ret != 0) 93 93 return ret; 94 94 95 - __u32 pid = bpf_get_current_pid_tgid() >> 32; 95 + __s32 pid = bpf_get_current_pid_tgid() >> 32; 96 96 int is_stack = 0; 97 97 98 98 is_stack = (vma->vm_start <= vma->vm_mm->start_stack &&
+1 -1
tools/testing/selftests/bpf/progs/normal_map_btf.c
··· 36 36 struct node_data *new; 37 37 int zero = 0; 38 38 39 - if (done || (u32)bpf_get_current_pid_tgid() != pid) 39 + if (done || (int)bpf_get_current_pid_tgid() != pid) 40 40 return 0; 41 41 42 42 value = bpf_map_lookup_elem(&array, &zero);
+2 -2
tools/testing/selftests/bpf/progs/profiler.inc.h
··· 132 132 } disallowed_exec_inodes SEC(".maps"); 133 133 134 134 #ifndef ARRAY_SIZE 135 - #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) 135 + #define ARRAY_SIZE(arr) (int)(sizeof(arr) / sizeof(arr[0])) 136 136 #endif 137 137 138 138 static INLINE bool IS_ERR(const void* ptr) ··· 645 645 for (int i = 0; i < ARRAY_SIZE(arr_struct->array); i++) { 646 646 struct var_kill_data_t* past_kill_data = &arr_struct->array[i]; 647 647 648 - if (past_kill_data != NULL && past_kill_data->kill_target_pid == tpid) { 648 + if (past_kill_data != NULL && past_kill_data->kill_target_pid == (pid_t)tpid) { 649 649 bpf_probe_read_kernel(kill_data, sizeof(*past_kill_data), 650 650 past_kill_data); 651 651 void* payload = kill_data->payload;
+1 -1
tools/testing/selftests/bpf/progs/sockopt_inherit.c
··· 9 9 #define CUSTOM_INHERIT2 1 10 10 #define CUSTOM_LISTENER 2 11 11 12 - __u32 page_size = 0; 12 + __s32 page_size = 0; 13 13 14 14 struct sockopt_inherit { 15 15 __u8 val;
+1 -1
tools/testing/selftests/bpf/progs/sockopt_multi.c
··· 5 5 6 6 char _license[] SEC("license") = "GPL"; 7 7 8 - __u32 page_size = 0; 8 + __s32 page_size = 0; 9 9 10 10 SEC("cgroup/getsockopt") 11 11 int _getsockopt_child(struct bpf_sockopt *ctx)
+1 -1
tools/testing/selftests/bpf/progs/sockopt_qos_to_cc.c
··· 9 9 10 10 char _license[] SEC("license") = "GPL"; 11 11 12 - __u32 page_size = 0; 12 + __s32 page_size = 0; 13 13 14 14 SEC("cgroup/setsockopt") 15 15 int sockopt_qos_to_cc(struct bpf_sockopt *ctx)
+1 -1
tools/testing/selftests/bpf/progs/test_bpf_ma.c
··· 21 21 const volatile unsigned int data_btf_ids[ARRAY_SIZE(data_sizes)] = {}; 22 22 23 23 int err = 0; 24 - int pid = 0; 24 + u32 pid = 0; 25 25 26 26 #define DEFINE_ARRAY_WITH_KPTR(_size) \ 27 27 struct bin_data_##_size { \
+1 -1
tools/testing/selftests/bpf/progs/test_core_reloc_kernel.c
··· 53 53 struct task_struct *task = (void *)bpf_get_current_task(); 54 54 struct core_reloc_kernel_output *out = (void *)&data.out; 55 55 uint64_t pid_tgid = bpf_get_current_pid_tgid(); 56 - uint32_t real_tgid = (uint32_t)pid_tgid; 56 + int32_t real_tgid = (int32_t)pid_tgid; 57 57 int pid, tgid; 58 58 59 59 if (data.my_pid_tgid != pid_tgid)
+4 -4
tools/testing/selftests/bpf/progs/test_core_reloc_module.c
··· 43 43 #if __has_builtin(__builtin_preserve_enum_value) 44 44 struct core_reloc_module_output *out = (void *)&data.out; 45 45 __u64 pid_tgid = bpf_get_current_pid_tgid(); 46 - __u32 real_tgid = (__u32)(pid_tgid >> 32); 47 - __u32 real_pid = (__u32)pid_tgid; 46 + __s32 real_tgid = (__s32)(pid_tgid >> 32); 47 + __s32 real_pid = (__s32)pid_tgid; 48 48 49 49 if (data.my_pid_tgid != pid_tgid) 50 50 return 0; ··· 77 77 #if __has_builtin(__builtin_preserve_enum_value) 78 78 struct core_reloc_module_output *out = (void *)&data.out; 79 79 __u64 pid_tgid = bpf_get_current_pid_tgid(); 80 - __u32 real_tgid = (__u32)(pid_tgid >> 32); 81 - __u32 real_pid = (__u32)pid_tgid; 80 + __s32 real_tgid = (__s32)(pid_tgid >> 32); 81 + __s32 real_pid = (__s32)pid_tgid; 82 82 83 83 if (data.my_pid_tgid != pid_tgid) 84 84 return 0;
+1 -1
tools/testing/selftests/bpf/progs/test_fsverity.c
··· 38 38 return 0; 39 39 got_fsverity = 1; 40 40 41 - for (i = 0; i < sizeof(digest); i++) { 41 + for (i = 0; i < (int)sizeof(digest); i++) { 42 42 if (digest[i] != expected_digest[i]) 43 43 return 0; 44 44 }
+1 -1
tools/testing/selftests/bpf/progs/test_skc_to_unix_sock.c
··· 29 29 len = unix_sk->addr->len - sizeof(short); 30 30 path[0] = '@'; 31 31 for (i = 1; i < len; i++) { 32 - if (i >= sizeof(struct sockaddr_un)) 32 + if (i >= (int)sizeof(struct sockaddr_un)) 33 33 break; 34 34 35 35 path[i] = unix_sk->addr->name->sun_path[i];
+1 -1
tools/testing/selftests/bpf/progs/test_xdp_do_redirect.c
··· 38 38 if (payload + 1 > data_end) 39 39 return XDP_ABORTED; 40 40 41 - if (xdp->ingress_ifindex != ifindex_in) 41 + if (xdp->ingress_ifindex != (__u32)ifindex_in) 42 42 return XDP_ABORTED; 43 43 44 44 if (metadata + 1 > data)