Thread (6 messages) 6 messages, 2 authors, 2023-02-08

Re: [PATCH v1 net] net: Remove WARN_ON_ONCE(sk->sk_forward_alloc) from sk_stream_kill_queues().

From: Kuniyuki Iwashima <hidden>
Date: 2023-02-08 00:43:05

From:   Kuniyuki Iwashima <redacted>
Date:   Tue, 7 Feb 2023 16:37:13 -0800
From:   Eric Dumazet <edumazet@google.com>
Date:   Tue, 7 Feb 2023 20:25:19 +0100
quoted
On Tue, Feb 7, 2023 at 7:37 PM Kuniyuki Iwashima [off-list ref] wrote:
quoted
In commit b5fc29233d28 ("inet6: Remove inet6_destroy_sock() in
sk->sk_prot->destroy()."), we delay freeing some IPv6 resources
from sk->destroy() to sk->sk_destruct().

Christoph Paasch reported the commit started triggering
WARN_ON_ONCE(sk->sk_forward_alloc) in sk_stream_kill_queues()
(See [0 - 2]).

For example, if inet6_sk(sk)->rxopt is not zero by setting
IPV6_RECVPKTINFO or its friends, tcp_v6_do_rcv() clones a skb
and calls skb_set_owner_r(), which charges it to sk.
skb_set_owner_r() in this place seems wrong.
This could lead to a negative sk->sk_forward_alloc
(because we have not sk_rmem_schedule() it ?)

Do you have a repro ?
I created a repro and confirmed sk->sk_forward_alloc was always positive.

---8<---
Sorry, I missed unistd.h here while copy-and-paste.

#include <unistd.h>
#include <stdio.h>

#include <sys/socket.h>
#include <netinet/in.h>

#define IPV6_FLOWINFO		11

int main(void)
{
	struct sockaddr_in6 addr = {
		.sin6_family = AF_INET6,
		.sin6_addr = in6addr_any,
		.sin6_port = htons(0),
	};
	int fd, ret = 0;
	socklen_t len;

	ret = socket(AF_INET6, SOCK_STREAM, IPPROTO_IP);
	perror("socket");
	if (ret < 0)
		return ret;

	fd = ret;
	ret = setsockopt(fd, SOL_IPV6, IPV6_FLOWINFO, &(int){1}, sizeof(int));
	perror("setsockopt");

	ret = bind(fd, (struct sockaddr *)&addr, sizeof(addr));
	perror("bind");
	if (ret)
		goto out;

	len = sizeof(addr);
	ret = getsockname(fd, (struct sockaddr *)&addr, &len);
	perror("getsockname");
	if (ret)
		goto out;

	ret = connect(fd, (struct sockaddr *)&addr, len);
	perror("connect");
	if (ret)
		goto out;

out:
	close(fd);

	return ret;
}
---8<---
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help