[fixed-upstream] kernel null pointer dereference after setsockopt(…IP_ADD_MEMBERSHIP…)

Bug #1420366 reported by Florian W. on 2015-02-10
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
linux-goldfish (Ubuntu)
High
Ricardo Salveti

Bug Description

Update: The "freeze" I explain in this bug is not an emulator freeze (which I thought at first), but a goldfish kernel panic.

--------------------------------

This might be a bug in one of the products the ubuntu emulator is based on, or maybe it's a configuration issue. I don't know so I report this here.

I'm trying to use libupnp in the Ubuntu emulator (My app was compiled using a 15.04 framework / i386 "kit" chroot created through ubuntu-sdk on Ubuntu 14.04, the emulator runs the "devel" i386 system image, I think r1, and libupnp is statically linked against my c++ backend module).

My system is 14.04 and I use the SDK PPA, so…
ubuntu-emulator is version 0.10-0ubuntu1
ubuntu-emulator-runtime is version 20140922-1903-0ubuntu3

There is a problem because InitUpnp() freezes the emulator instead of initializing the library correctly.

By single-stepping through that library function and the functions called by that function, I figured out that it probably freezes in a setsockopt() call: (*)
> ret = setsockopt(*ssdpSock, IPPROTO_IP, IP_ADD_MEMBERSHIP,
> (char *)&ssdpMcastAddr, sizeof(struct ip_mreq));

Line 846:
> http://sourceforge.net/p/pupnp/code/ci/master/tree/upnp/src/ssdp/ssdp_server.c#l846

* (That guess is based on the fact that after entering create_ssdp_sock_v4(), there's a sequence of socket(), setsockopt(), bind(), inet_addr(), inet_addr(), setsockopt() and then it freezes when typing "fin" in gdb to return from the last setsockopt call – I don't have enough debug information in the binary to know exactly, and I'm looking at libupnp git master but linking against a precompiled libupnp.a supplied by Ubuntu.)

That system call apparently changes the socket to receive multicast packets.

Related: http://sourceforge.net/p/pupnp/mailman/message/18352779/ states that the same line of code caused issues for another qemu-based emulator, but that was in 2008 and AIUI qemu is supposed to support IP_ADD_MEMBERSHIP since 2009.

Florian W. (florian-will) wrote :

Turns out that goget-ubuntu-touch is not the correct source package for this bug, since the emulator runtime is in the "android" package.

affects: goget-ubuntu-touch (Ubuntu) → android (Ubuntu)
Florian W. (florian-will) wrote :

Okay, so it's not actually the emulator. The "guest system" (goldfish?) simply kernel panics, see the attachment.

I guess the android source package is still correct though.

summary: - emulator freeze on setsockopt(…IP_ADD_MEMBERSHIP…)
+ goldfish kernel panic after setsockopt(…IP_ADD_MEMBERSHIP…)
description: updated

I have some more details about the kernel panic.

In net/ipv4/igmp.c, line 320, ip_route_output_ports() is called with socket (aka "sk") = NULL.
In include/net/route.h, line 150, that NULL socket pointer is passed on to sock_i_uid(), so sock_i_uid(NULL) is called.

That sock_i_uid() call is not in mainline Linux (neither 3.4 nor 3.18), but it is in the Google android goldfish kernel.

I'd say that code is faulty, because the ip_route_output_ports() function takes a NULL socket into account, only the recently added sock_i_uid() call is missing a NULL check.

In net/core/sock.c, line 1477, the sock_i_uid() function then dereferences the NULL pointer, which probably explains my kernel panic issue.

Florian W. (florian-will) wrote :

I think the goldfish kernel is not maintained in the android source package, but in this separate linux-goldfish package, so it's time to move this bug again.

affects: android (Ubuntu) → linux-goldfish (Ubuntu)
summary: - goldfish kernel panic after setsockopt(…IP_ADD_MEMBERSHIP…)
+ kernel null pointer dereference after setsockopt(…IP_ADD_MEMBERSHIP…)

There's actually a fix upstream, :
https://android.googlesource.com/kernel/goldfish/+/0836a0c191f580ed69254e0b287cdce58481e978

I hope there are plans to rebase to a recent goldfish kernel some time. :)

Florian W. (florian-will) wrote :

I have now verified that building the goldfish kernel from git with the upstream commit cherry-picked, and then booting that kernel in the emulator, solves my issue with libupnp.

summary: - kernel null pointer dereference after setsockopt(…IP_ADD_MEMBERSHIP…)
+ [fixed-upstream] kernel null pointer dereference after
+ setsockopt(…IP_ADD_MEMBERSHIP…)
Changed in linux-goldfish (Ubuntu):
assignee: nobody → Ricardo Salveti (rsalveti)
status: New → Confirmed
importance: Undecided → High
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers