From mboxrd@z Thu Jan 1 00:00:00 1970 From: Yonghong Song Subject: [PATCH bpf-next] tools/bpf: fix a netlink recv issue Date: Tue, 11 Sep 2018 14:09:11 -0700 Message-ID: <20180911210911.3235080-1-yhs@fb.com> Mime-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Cc: To: , , Return-path: Received: from mx0b-00082601.pphosted.com ([67.231.153.30]:40412 "EHLO mx0b-00082601.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726870AbeILCK2 (ORCPT ); Tue, 11 Sep 2018 22:10:28 -0400 Received: from pps.filterd (m0109332.ppops.net [127.0.0.1]) by mx0a-00082601.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w8BL3htE023273 for ; Tue, 11 Sep 2018 14:09:19 -0700 Received: from mail.thefacebook.com ([199.201.64.23]) by mx0a-00082601.pphosted.com with ESMTP id 2mejdv0krg-2 (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NOT) for ; Tue, 11 Sep 2018 14:09:19 -0700 Sender: netdev-owner@vger.kernel.org List-ID: Commit f7010770fbac ("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: f7010770fbac ("tools/bpf: move bpf/lib netlink related functions i= nto a new file") Reported-by: Bj=C3=B6rn T=C3=B6pel Tested-by: Bj=C3=B6rn T=C3=B6pel Signed-off-by: Yonghong Song --- tools/lib/bpf/netlink.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tools/lib/bpf/netlink.c b/tools/lib/bpf/netlink.c index 469e068dd0c5..fde1d7bf8199 100644 --- a/tools/lib/bpf/netlink.c +++ b/tools/lib/bpf/netlink.c @@ -65,18 +65,23 @@ static int bpf_netlink_recv(int sock, __u32 nl_pid, i= nt seq, __dump_nlmsg_t _fn, dump_nlmsg_t fn, void *cookie) { + bool multipart =3D true; struct nlmsgerr *err; struct nlmsghdr *nh; char buf[4096]; int len, ret; =20 - while (1) { + while (multipart) { + multipart =3D false; len =3D recv(sock, buf, sizeof(buf), 0); if (len < 0) { ret =3D -errno; goto done; } =20 + if (len =3D=3D 0) + break; + for (nh =3D (struct nlmsghdr *)buf; NLMSG_OK(nh, len); nh =3D NLMSG_NEXT(nh, len)) { if (nh->nlmsg_pid !=3D nl_pid) { @@ -87,6 +92,8 @@ static int bpf_netlink_recv(int sock, __u32 nl_pid, int= seq, ret =3D -LIBBPF_ERRNO__INVSEQ; goto done; } + if (nh->nlmsg_flags & NLM_F_MULTI) + multipart =3D true; switch (nh->nlmsg_type) { case NLMSG_ERROR: err =3D (struct nlmsgerr *)NLMSG_DATA(nh); --=20 2.17.1