An ESP-in-TCP socket can have a TX timestamp queued and report POLLERR,
but recvmsg(MSG_ERRQUEUE) returns EAGAIN because espintcp_recvmsg()
reads the IKE queue instead. If an IKE message is pending, the same call
consumes that message as though it were an error-queue result.
Handle MSG_ERRQUEUE through inet_recv_error() before reading the IKE
queue. This exposes queued error metadata and leaves IKE messages for
normal receive calls.
Fixes: e27cca96cd68 ("xfrm: add espintcp (RFC 8229)")
Signed-off-by: Baek Kyu, Kim <redacted>
---
With the same arm64 QEMU/KVM configuration and loopback fixture, the
original kernel returned EAGAIN for a queued TX timestamp and consumed
IKE data on MSG_ERRQUEUE. The changed kernel returned the timestamp
metadata and preserved IKE data for normal receive, on both IPv4 and
IPv6. Ordinary TCP and normal IKE receive paths were also compared.
No external IKE peer or physical network was tested.
net/xfrm/espintcp.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/net/xfrm/espintcp.c b/net/xfrm/espintcp.c
index 4052ae5bbb2ea5..3e23900d6446b9 100644
--- a/net/xfrm/espintcp.c
+++ b/net/xfrm/espintcp.c
@@ -148,6 +148,9 @@ static int espintcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
int copied;
int off = 0;
+ if (unlikely(flags & MSG_ERRQUEUE))
+ return inet_recv_error(sk, msg, len);
+
skb = __skb_recv_datagram(sk, &ctx->ike_queue, flags, &off, &err);
if (!skb) {
if (err == -EAGAIN && sk->sk_shutdown & RCV_SHUTDOWN)--
2.55.0