]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lsfd: use memset explicitly to fill bpf_attr with zero
authorMasatake YAMATO <yamato@redhat.com>
Sat, 25 Apr 2026 23:57:17 +0000 (08:57 +0900)
committerKarel Zak <kzak@redhat.com>
Mon, 11 May 2026 09:44:48 +0000 (11:44 +0200)
The original code used initialize-lists for initializing
variables (attr) type of union bpf_attr.

However, the folloing syscalls failed with EINVAL:

     syscall(SYS_bpf, BPF_PROG_GET_FD_BY_ID, &attr, sizeof(attr));
     syscall(SYS_bpf, BPF_MAP_GET_FD_BY_ID, &attr, sizeof(attr));

CHECK_ATTR macro of Linux might cause EINVAL:

    /* helper macro to check that unused fields 'union bpf_attr' are zero */
    #define CHECK_ATTR(CMD) \
    memchr_inv((void *) &attr->CMD##_LAST_FIELD + \
       sizeof(attr->CMD##_LAST_FIELD), 0, \
       sizeof(*attr) - \
       offsetof(union bpf_attr, CMD##_LAST_FIELD) - \
       sizeof(attr->CMD##_LAST_FIELD)) != NULL

I doubt initialize-lists worked well.

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
lsfd-cmd/unkn.c

index efd6d402c084901dfbdda4b6a01d0297dede219e..3bac2feb40d7d0c9957f6753a1344c8c29c838af 100644 (file)
@@ -1070,21 +1070,20 @@ static void anon_bpf_prog_free(struct unkn *unkn)
 
 static void anon_bpf_prog_get_more_info(struct anon_bpf_prog_data *prog_data)
 {
-       union bpf_attr attr = {
-               .prog_id = (int32_t)prog_data->id,
-               .next_id = 0,
-               .open_flags = 0,
-       };
+       int bpf_fd;
+       union bpf_attr attr;
        struct bpf_prog_info info = { 0 };
-       union bpf_attr info_attr = {
-               .info.info_len = sizeof(info),
-               .info.info = (uint64_t)(uintptr_t)&info,
-       };
+       union bpf_attr info_attr;
 
-       int bpf_fd = syscall(SYS_bpf, BPF_PROG_GET_FD_BY_ID, &attr, sizeof(attr));
+       memset(&attr, 0, sizeof(attr));
+       attr.prog_id = (int32_t)prog_data->id;
+       bpf_fd = syscall(SYS_bpf, BPF_PROG_GET_FD_BY_ID, &attr, sizeof(attr));
        if (bpf_fd < 0)
                return;
 
+       memset(&info_attr, 0, sizeof(info_attr));
+       info_attr.info.info_len = sizeof(info);
+       info_attr.info.info = (uint64_t)(uintptr_t)&info;
        info_attr.info.bpf_fd = bpf_fd;
        if (syscall(SYS_bpf, BPF_OBJ_GET_INFO_BY_FD, &info_attr, offsetofend(union bpf_attr, info)) == 0) {
                memcpy(prog_data->name,
@@ -1261,21 +1260,20 @@ static void anon_bpf_map_free(struct unkn *unkn)
 
 static void anon_bpf_map_get_more_info(struct anon_bpf_map_data *map_data)
 {
-       union bpf_attr attr = {
-               .map_id = (int32_t)map_data->id,
-               .next_id = 0,
-               .open_flags = 0,
-       };
+       int bpf_fd;
+       union bpf_attr attr;
        struct bpf_map_info info = { 0 };
-       union bpf_attr info_attr = {
-               .info.info_len = sizeof(info),
-               .info.info = (uint64_t)(uintptr_t)&info,
-       };
+       union bpf_attr info_attr;
 
-       int bpf_fd = syscall(SYS_bpf, BPF_MAP_GET_FD_BY_ID, &attr, sizeof(attr));
+       memset(&attr, 0, sizeof(attr));
+       attr.map_id = (int32_t)map_data->id;
+       bpf_fd = syscall(SYS_bpf, BPF_MAP_GET_FD_BY_ID, &attr, sizeof(attr));
        if (bpf_fd < 0)
                return;
 
+       memset(&info_attr, 0, sizeof(info_attr));
+       info_attr.info.info_len = sizeof(info);
+       info_attr.info.info = (uint64_t)(uintptr_t)&info;
        info_attr.info.bpf_fd = bpf_fd;
        if (syscall(SYS_bpf, BPF_OBJ_GET_INFO_BY_FD, &info_attr, offsetofend(union bpf_attr, info)) == 0) {
                memcpy(map_data->name,