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

Bug #1420366 reported by Florian W.
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
linux-goldfish (Ubuntu)
Confirmed
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.

Revision history for this message
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)
Revision history for this message
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
Revision history for this message
Florian W. (florian-will) wrote : Re: goldfish kernel panic after setsockopt(…IP_ADD_MEMBERSHIP…)

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.

Revision history for this message
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…)
Revision history for this message
Florian W. (florian-will) wrote : Re: 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. :)

Revision history for this message
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  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.