Skip to content

Commit 9d0b3c1

Browse files
yonghong-songAlexei Starovoitov
authored andcommitted
tools/bpf: fix a netlink recv issue
Commit f701077 ("tools/bpf: move bpf/lib netlink related functions into a new file") introduced a while loop for the netlink recv path. This while loop is needed since the buffer in recv syscall may not be enough to hold all the information and in such cases multiple recv calls are needed. There is a bug introduced by the above commit as the while loop may block on recv syscall if there is no more messages are expected. The netlink message header flag NLM_F_MULTI is used to indicate that more messages are expected and this patch fixed the bug by doing further recv syscall only if multipart message is expected. The patch added another fix regarding to message length of 0. When netlink recv returns message length of 0, there will be no more messages for returning data so the while loop can end. Fixes: f701077 ("tools/bpf: move bpf/lib netlink related functions into a new file") Reported-by: Björn Töpel <[email protected]> Tested-by: Björn Töpel <[email protected]> Signed-off-by: Yonghong Song <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent 2e2a0c9 commit 9d0b3c1

File tree

1 file changed

+8
-1
lines changed

1 file changed

+8
-1
lines changed

tools/lib/bpf/netlink.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,18 +65,23 @@ static int bpf_netlink_recv(int sock, __u32 nl_pid, int seq,
6565
__dump_nlmsg_t _fn, dump_nlmsg_t fn,
6666
void *cookie)
6767
{
68+
bool multipart = true;
6869
struct nlmsgerr *err;
6970
struct nlmsghdr *nh;
7071
char buf[4096];
7172
int len, ret;
7273

73-
while (1) {
74+
while (multipart) {
75+
multipart = false;
7476
len = recv(sock, buf, sizeof(buf), 0);
7577
if (len < 0) {
7678
ret = -errno;
7779
goto done;
7880
}
7981

82+
if (len == 0)
83+
break;
84+
8085
for (nh = (struct nlmsghdr *)buf; NLMSG_OK(nh, len);
8186
nh = NLMSG_NEXT(nh, len)) {
8287
if (nh->nlmsg_pid != nl_pid) {
@@ -87,6 +92,8 @@ static int bpf_netlink_recv(int sock, __u32 nl_pid, int seq,
8792
ret = -LIBBPF_ERRNO__INVSEQ;
8893
goto done;
8994
}
95+
if (nh->nlmsg_flags & NLM_F_MULTI)
96+
multipart = true;
9097
switch (nh->nlmsg_type) {
9198
case NLMSG_ERROR:
9299
err = (struct nlmsgerr *)NLMSG_DATA(nh);

0 commit comments

Comments
 (0)