Bug 174933 - [linux] if_nameindex fail in linuxulator enviroment (PF_NETLINK needed)
Summary: [linux] if_nameindex fail in linuxulator enviroment (PF_NETLINK needed)
Status: Open
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: 9.0-RELEASE
Hardware: Any Any
: Normal Affects Only Me
Assignee: freebsd-emulation (Nobody)
URL:
Keywords:
Depends on:
Blocks: 247219
  Show dependency treegraph
 
Reported: 2013-01-03 11:00 UTC by Martin Laabs
Modified: 2020-07-18 20:18 UTC (History)
6 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Laabs 2013-01-03 11:00:00 UTC
The function call if_nameindex out of the libc failes (return NULL) if it is called out of a linux application.
The cause of the failure is an inappropriate call of socket likely called in the __opensock function in the libc. This can be seen out of a ktrace dump:

[...]
3319 a.out    CALL  linux_socketcall(0x1,0xffffc6d4)
3319 a.out    RET   linux_socketcall -1 errno 97 Address family not supported by protocol family
[...]

The cause of the wrong arguments for this socket call is not known to me up to now.

For all the test I use the f10 linux environment. Tests with different linux-base versions are pending. Maybe someone who installed them can do it. On request I can send the linux binary compiled on debian with a 2.6.18 kernel and libc-2.3.6.

How-To-Repeat: Compile the following program on FreeBSD and Linux:
Check the return code - maybe the program will segfault if run as linux binary.

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[])
{
     struct if_nameindex *ifn;
  
  /*Can be omitted - just to test if this makes a difference since
  the __opensock function remember the last socket options*/
  socket(AF_INET, SOCK_DGRAM, 0);

  ifn=if_nameindex();
  if(ifn==0) 
     err("if_nameindex failed\n"); 

 return 0;
}
Comment 1 Eitan Adler freebsd_committer freebsd_triage 2013-01-04 18:04:31 UTC
---------- Forwarded message ----------
From: Martin Laabs <info@martinlaabs.de>
Date: 4 January 2013 12:40
Subject: Bug analyzed - how to fix it?
To: freebsd-emulation@freebsd.org


Hi,

I'm (hopefully) done with the bug analyses of
"http://www.freebsd.org/cgi/query-pr.cgi?pr=174933".
The bug in one sentences: if_nameindex (resided in the libc) fails if
called out of a linux binary.

The cause is that the if_nameindex calls a function named __opensock that
return a socket. This socket is used to call an ioctl(SIOCGIFCONF ...).
This ioctl call is actually implemented in the linuxulator. Unfortunately
the __opensock function tries to create the following socket:

socket(PF_NETLINK, SOCK_RAW, 0)
in decimal: socket(16,3,0)

This type of socket type however is not supported by the linuxulator and
IMHO in freebsd at all. However - maybe it just has another name in FreeBSD.

So - for me there seem to be two solutions:

1. Write a dirty patch that returns a PF_INET instead of the PF_NETLINK
socket if called with the arguments above. This should be OK since I assume
that SIOCGIFCONF ioctl works also fine with PF_INET sockets. (I'll test
this to verify whether this is true)
This however would be somewhat dirty since PF_NETLINK sockets are not
really supported and if another application tries to open a real PF_NETLINK
socket it will get a false positive result.

2. Patch the glibc to not create a PF_NETLINK socket in __opensock but
create a PF_INET socket instead. The problem is that I do not know about
the side effects since the __opensock function is used elsewhere in the
libc also. The second drawback is that this would lead to a customized libc
for the linuxulator. As far as I know the current libc(s) are just bare
copies out of linux systems. So this solution would also increase
maintenance effort.

Do you have an other idea how to fix the problem?

Thank you,
 Martin

_______________________________________________
freebsd-emulation@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-emulation
To unsubscribe, send any mail to "freebsd-emulation-unsubscribe@freebsd.org"


-- 
Eitan Adler
Comment 2 Dmitry Chagin freebsd_committer 2013-01-08 13:09:13 UTC
Responsible Changed
From-To: freebsd-bugs->freebsd-emulation

Over to maintainers.
Comment 3 Tijl Coosemans freebsd_committer 2016-09-06 14:22:58 UTC
Mailing list discussion with additional information:
https://lists.freebsd.org/pipermail/freebsd-emulation/2013-January/010315.html
Comment 4 pete 2020-07-18 04:09:37 UTC
Hello, I am running into this issue on my 13-CURRENT system running X-Plane 11 (https://www.x-plane.com/).  The application runs fine on my system using the linux_c7 packages, I am even able to download the application via its Linux installer and run the app in Demo mode.

The issue is their DRM seems to trigger this bug and the app is unable to authenticate against their license servers.

Anyway, I'm not sure if anyone has taken a look at this in a long time but I'd be keen to test out patches or workarounds as it'll probably prevent other issues with linuxulator networking in other apps.
Comment 5 Alex S 2020-07-18 11:23:25 UTC
(In reply to pete from comment #4)

> The issue is their DRM seems to trigger this bug
> and the app is unable to authenticate against their license servers.

> as it'll probably prevent other issues with linuxulator networking

PF_NETLINK is only tangentially related to networking, it's a yet another (kernel) event notification mechanism stuffed into the socket API for some reason. Probably to work with epoll.

It's very unlikely to be the cause of your issue.
Comment 6 pete 2020-07-18 17:33:59 UTC
(In reply to Alex S from comment #5)
Interesting, I thought it looked related because I am seeing this when running the binary through truss which looked very similar to Martin's original post:

89106: linux_socket(0x2,0x2,0x0)                 = 11 (0xb)
89106: linux_socket(0x10,0x3,0x0)                ERR#-97 'Address family not supported by protocol family'
89106: write(1,"Failed to get if_nameindex: 97\n",31) = 31 (0x1f)


In terms of the binary I unfortunately do not have much visibility into how they build it due to it being proprietary, but if this isn't related it'd be really appreciated if you could me in a better direction to debug this.
Comment 7 Alex S 2020-07-18 20:18:36 UTC
(In reply to pete from comment #6)

Hmm… Judging by the installer/demo disassembly, this syscall comes from the function named GetMACAddressLIN, so intent is clear enough. The code mostly involves socket(AF_INET, SOCK_DGRAM, IPPROTO_IP) + SIOCGIFFLAGS and SIOCGIFHWADDR ioctls. However, there is also if_nameindex (obviously), which is internally implemented in glibc with a PF_NETLINK socket. X-Plane is probably only interested there in the name of the first returned interface. (Disclaimer: I'm not actually good at reading assembly by any measure.)

If you are willing to spend your time on application-specific hacks, you should try writing LD_PRELOADable variants for if_nameindex and if_freenameindex. Either stub them or get the necessary information from linsysfs at /sys/class/net.