pespin has submitted this change. ( https://gerrit.osmocom.org/c/osmo-ggsn/+/38502?usp=email )
Change subject: tun: Fix null pointer derefence when in kernel gtp mode ......................................................................
tun: Fix null pointer derefence when in kernel gtp mode
When using gtp kernel module, the kernel sends GTP-U packets to userspace (osmo-ggsn) when it is unable to find a related pdp ctx for the packet. This is so far processes through the code path: ggsn_gtp_fd_cb => gtp_decaps1u => gtp_gpdu_ind => encaps_tun = > tun_encaps
In usual circumstances, if the gtp module sends a packet to userspace because it is unable to find a pdp ctx, userspace shouldn't be able anyway, so it should go through a different code path and answer over GTP-U with a "Error Indication". Other specific packets (such as ICMPv6 with link local address) are also being forwarded to userspace. Some of them are being handled in encaps_tun() in a special way (eg. Router Soliciation), but others, such as Neighbor Solicitation, are not being handled there and follow the generic path where they try to be forwarded over the tun towards the Internet.
When using the kernel gtp mode, there's no way to re-inject into the network stack a packet we received from the gtp mode, like done when using the tun device mode.
Prior to 38b607ece3ad248c7c864a50255f2a06ca383e19, a bug existed in tun_encaps() which would still try to use tun->fd (-1) when in gtp kernel module, which ended up in an error being printed. After the mentioned commit was applied, when in gtp kernel module it started accessing tun->tundev which is is NULL under that setup, hence making the bug consequences worse.
Add a pointer guard with a log line to inform about the problem, while still discussing the originating problem in OS#6600.
Related: OS#6600 Change-Id: I508758696a0bcbb7c780a0ed33b28ba640602488 --- M lib/tun.c 1 file changed, 9 insertions(+), 1 deletion(-)
Approvals: pespin: Looks good to me, approved Jenkins Builder: Verified osmith: Looks good to me, but someone else must approve; Verified
diff --git a/lib/tun.c b/lib/tun.c index 055c4fc..5f73d32 100644 --- a/lib/tun.c +++ b/lib/tun.c @@ -202,9 +202,17 @@
int tun_encaps(struct tun_t *tun, void *pack, unsigned len) { - struct msgb *msg = msgb_alloc(PACKET_MAX, "tun_tx"); + struct msgb *msg; int rc;
+ if (!tun->tundev) { + LOGTUN(LOGL_ERROR, tun, + "Injecting decapsulated packet not supported in kernel gtp mode: %s\n", + osmo_hexdump(pack, len)); + return -ENOTSUP; + } + + msg = msgb_alloc(PACKET_MAX, "tun_tx"); OSMO_ASSERT(msg); memcpy(msgb_put(msg, len), pack, len); rc = osmo_tundev_send(tun->tundev, msg);