Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 27 Jan 2022 09:11:01 -0800
From:      Gleb Smirnoff <glebius@freebsd.org>
To:        Mateusz Guzik <mjguzik@gmail.com>
Cc:        src-committers@freebsd.org, dev-commits-src-all@freebsd.org, dev-commits-src-main@freebsd.org
Subject:   Re: git: e1882428dcbb - main - ifnet/mbuf: provide KPI to serialize/restore m->m_pkthdr.rcvif
Message-ID:  <YfLSJUJN2MKYxUTK@FreeBSD.org>
In-Reply-To: <CAGudoHE1NDQOujYGAgrG0fCuCMXKU9dPi478xaLfdojViZXk%2Bw@mail.gmail.com>
References:  <202201270600.20R602KH059925@gitrepo.freebsd.org> <CAGudoHE1NDQOujYGAgrG0fCuCMXKU9dPi478xaLfdojViZXk%2Bw@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
  Mateusz,

On Thu, Jan 27, 2022 at 05:59:03PM +0100, Mateusz Guzik wrote:
M> --- trap 0xc, rip = 0xffffffff80616d98, rsp = 0xfffffe06462889e0, rbp
M> = 0xfffffe06462889e0 ---
M> m_rcvif_serialize() at m_rcvif_serialize+0x8/frame 0xfffffe06462889e0
M> netisr_queue_src() at netisr_queue_src+0x15c/frame 0xfffffe0646288a30
M> route_output() at route_output+0x890/frame 0xfffffe0646288c70
M> sosend_generic() at sosend_generic+0x456/frame 0xfffffe0646288d10
M> soo_write() at soo_write+0x43/frame 0xfffffe0646288d40
M> dofilewrite() at dofilewrite+0x81/frame 0xfffffe0646288d90
M> sys_write() at sys_write+0xbc/frame 0xfffffe0646288e00
M> amd64_syscall() at amd64_syscall+0x107/frame 0xfffffe0646288f30
M> fast_syscall_common() at fast_syscall_common+0xf8/frame 0xfffffe0646288f30
M> --- syscall (4, FreeBSD ELF64, sys_write), rip = 0x3b000ba6703a, rsp =

The breaking commit is 6871de9363e559fef6765f0e49acc47f77544999,
not exactly this one.

This means route_output() tries to queue on netisr an mbuf without
rcvif set. And by means of route protocol it is legitimate.

The question is how did that work before?

If we look at netisr.c before my change, we see that on dequeuing we
would require the rcvif for VIMAGE case:

netisr_process_workstream_proto():

		VNET_ASSERT(m->m_pkthdr.rcvif != NULL,
		    ("%s:%d rcvif == NULL: m=%p", __func__, __LINE__, m));
		CURVNET_SET(m->m_pkthdr.rcvif->if_vnet);
		netisr_proto[proto].np_handler(m);

This won't panic without VIMAGE however.

It also is dereferenced in netisr_drain_proto_vnet(), but apparently
this function is also disabled without VIMAGE.


-- 
Gleb Smirnoff



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?YfLSJUJN2MKYxUTK>