A 32-bit time_t overflows when the board clock is beyond 2038. time() returns -1, and the first request then has sequence zero. The sequence range check underflows and discards the valid reply, leaving ip blocked in recvmsg(). The same range check also fails on a normal counter wrap. Use zero as a fallback seed when time() fails. Compare the unsigned sequence distance against the number of requests, allowing wraparound and rejecting the sequence immediately before the first request. Signed-off-by: Florian Fainelli --- lib/libnetlink.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/libnetlink.c b/lib/libnetlink.c index edf3a8ba7ce0..5bc7c43245fb 100644 --- a/lib/libnetlink.c +++ b/lib/libnetlink.c @@ -194,6 +194,7 @@ int rtnl_open_byproto(struct rtnl_handle *rth, unsigned int subscriptions, int protocol) { socklen_t addr_len; + time_t now; int sndbuf = 32768; int one = 1; @@ -246,7 +247,8 @@ int rtnl_open_byproto(struct rtnl_handle *rth, unsigned int subscriptions, rth->local.nl_family); goto err; } - rth->seq = time(NULL); + now = time(NULL); + rth->seq = now == (time_t)-1 ? 0 : (__u32)now; return 0; err: rtnl_close(rth); @@ -1092,7 +1094,7 @@ next: if (nladdr.nl_pid != 0 || h->nlmsg_pid != rtnl->local.nl_pid || - h->nlmsg_seq > seq || h->nlmsg_seq < seq - iovlen) { + (unsigned int)(seq - h->nlmsg_seq) >= iovlen) { /* Don't forget to skip that message. */ status -= NLMSG_ALIGN(len); h = (struct nlmsghdr *)((char *)h + NLMSG_ALIGN(len)); -- 2.53.0