Bug 178881 - [patch] getifaddrs(3) does not report IPv6 addresses properly in 32-bit compatibility mode
Summary: [patch] getifaddrs(3) does not report IPv6 addresses properly in 32-bit compa...
Status: Open
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: 9.1-RELEASE
Hardware: Any Any
: Normal Affects Only Me
Assignee: Bryan Drewery
URL:
Keywords: patch
Depends on:
Blocks:
 
Reported: 2013-05-23 21:00 UTC by Steve Zweep
Modified: 2022-10-17 12:40 UTC (History)
7 users (show)

See Also:


Attachments
file.diff (1.01 KB, patch)
2013-05-23 21:00 UTC, Steve Zweep
no flags Details | Diff
Patch for 10.1-STABLE (r279751) - NOT WORKING (847 bytes, patch)
2015-03-08 21:47 UTC, Marcin Cieślak
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Steve Zweep 2013-05-23 21:00:00 UTC
This was uncovered trying to run 32-bit Postfix on a 64-bit kernel, and subsequently verified with a simple utility which just iterates and prints the IP addresses returned from getifaddrs().

In 32-bit compatibility mode IPv4 addresses are reported correctly, but IPv6 addresses are not. The address family is reported as '0' instead of the expected 28 for AF_INET6. The same test utility works as expected when compiled as a 64-bit executable.

Fix: The problem appears to be in the 32-bit compatibility code in sys/net/rtsock.c which handles the NET_RT_IFLIST sysctl used by getifaddrs(). The calculated size of the sockaddr structure does not match that which the client code in getifaddrs is expecting.

I'm no expert here, but the following patch worked for me:
How-To-Repeat: - configure a network interface with an IPv6 address
- compile a 32-bit program which calls getifaddrs() to iterate through interface addresses
- examine the output
Comment 1 Hiroki Sato freebsd_committer freebsd_triage 2013-05-23 21:42:11 UTC
Responsible Changed
From-To: freebsd-bugs->hrs

Take.
Comment 2 Marcin Cieślak 2015-03-06 15:31:14 UTC
*** Bug 198350 has been marked as a duplicate of this bug. ***
Comment 3 Marcin Cieślak 2015-03-08 21:47:33 UTC
Created attachment 154041 [details]
Patch for 10.1-STABLE (r279751) - NOT WORKING

Since your 9.1 does not apply cleanly I made my own version for 10.1.
But it is not working.

My version patches it only in rt_msg2(), but SA_SIZE is also used in rt_msg1(), rt_xaddrs()

I can confirm this bug is still present in my oldish -CURRENT (as of Sep 2014), although rtsock.c is in part rewritten.

Easy way to test:

Install www/node (version 0.12.0) and try:

> os.networkInterfaces()

it will return bogus values for IPv6 or crash if running 32-bit binary on amd64.
Comment 4 Hiroki Sato freebsd_committer freebsd_triage 2015-03-25 02:22:43 UTC
Please do not remove me from Cc list with no notification.
Comment 5 Bryan Drewery freebsd_committer freebsd_triage 2015-03-25 02:34:58 UTC
(In reply to Hiroki Sato from comment #4)
> Please do not remove me from Cc list with no notification.

Sorry that was not my intent. I took assignment. I'm working on a patch.
Comment 6 Bryan Drewery freebsd_committer freebsd_triage 2015-03-25 05:19:08 UTC
Working patch available at https://reviews.freebsd.org/D2131
Comment 7 Marcin Cieślak 2015-03-25 11:35:43 UTC
Early testing shows no improvement, but trying full rebuild now.
Comment 8 Marcin Cieślak 2015-03-25 11:37:42 UTC
(In reply to Marcin Cieślak from comment #7)
(pls forget it, the patch didn't apply correctly to my 10.1 tree)
Comment 9 Bryan Drewery freebsd_committer freebsd_triage 2015-03-25 17:15:32 UTC
Summary: The fix is larger than expected. I am working on it.

There is a lot of complexity involved with this issue. The original issue and fix were fine. However r263102 broke ABI compatibility with all consumers of NET_RT_IFLIST. Fixing this is difficult since if_data has different structure for <r263102 NET_RT_IFLIST users and >r263102.

Given we have added NET_RT_IFLISTL as a better way to grab this data we will be removing NET_RT_IFLIST from all consumers in the tree and then removing NET_RT_IFLIST.

We will fix ABI compatibility by having NET_RT_IFLIST return the older if_data for both 64bit and 32bit calls. My current patch works on amd64 by accident since the new if_data is "close enough" to the old if_data in terms of sizes. The counters and baudrate are different. The change was enough to fix getifaddrs(3) but is not fully correct.

This change will break ABI compatibility on head only but that is generally acceptable, especially when restoring older ABI compatibility.

All of these will need to be updated to use NET_RT_IFLISTL or getifaddrs(3):

sbin/route/route.c:     mib[4] = NET_RT_IFLIST;
sbin/routed/if.c:       mib[4] = NET_RT_IFLIST;
sbin/ipfw/nat.c:        mib[4] = NET_RT_IFLIST;
sbin/natd/natd.c:       mib[4] = NET_RT_IFLIST;
usr.sbin/rtsold/if.c:   int mib[6] = {CTL_NET, AF_ROUTE, 0, 0, NET_RT_IFLIST, 0};
usr.sbin/rwhod/rwhod.c: mib[4] = NET_RT_IFLIST;
usr.sbin/rwhod/rwhod.c:                 quit("out of sync parsing NET_RT_IFLIST");
usr.sbin/route6d/route6d.c:     mib[4] = NET_RT_IFLIST;
usr.sbin/route6d/route6d.c:             fatal("sysctl estimate NET_RT_IFLIST");
usr.sbin/route6d/route6d.c:             fatal("sysctl NET_RT_IFLIST");
usr.sbin/ppp/iface.c:  mib[4] = NET_RT_IFLIST;
usr.sbin/ppp/route.c:    mib[4] = NET_RT_IFLIST;
usr.sbin/ppp/arp.c:  mib[4] = NET_RT_IFLIST;
usr.sbin/wpa/ndis_events/ndis_events.c: mib[4] = NET_RT_IFLIST;
usr.sbin/wpa/wpa_supplicant/Packet32.c: mib[4] = NET_RT_IFLIST;
usr.sbin/rtadvd/if.c:   int mib[] = { CTL_NET, PF_ROUTE, 0, AF_INET6, NET_RT_IFLIST, 0 };
usr.sbin/rtadvd/if.c:               "<%s> sysctl: NET_RT_IFLIST size get failed", __func__);
usr.sbin/rtadvd/if.c:               "<%s> sysctl: NET_RT_IFLIST get failed", __func__);
usr.sbin/rtadvd/if.c:                       "out of sync parsing NET_RT_IFLIST\n"
lib/libc/net/getifaddrs.c:#ifdef        NET_RT_IFLIST
lib/libc/net/getifaddrs.c:      mib[4] = NET_RT_IFLISTL;/* extra fields for extensible msghdr structs */
lib/libc/gen/sysctl.3:.It "NET_RT_IFLIST    0 or if_index" Ta None
lib/libc/gen/sysctl.3:.It "NET_RT_IFLISTL   0 or if_index" Ta None
lib/libc/gen/sysctl.3:.Dv NET_RT_IFLISTL
lib/libc/gen/sysctl.3:.Dv NET_RT_IFLIST ,
lib/libc/gen/sysctl.3:.Dv NET_RT_IFLISTL
Comment 10 Eitan Adler freebsd_committer freebsd_triage 2018-05-28 19:48:25 UTC
batch change:

For bugs that match the following
-  Status Is In progress 
AND
- Untouched since 2018-01-01.
AND
- Affects Base System OR Documentation

DO:

Reset to open status.


Note:
I did a quick pass but if you are getting this email it might be worthwhile to double check to see if this bug ought to be closed.
Comment 11 Graham Perrin freebsd_committer freebsd_triage 2022-10-17 12:40:06 UTC
Keyword: 

    patch
or  patch-ready

– in lieu of summary line prefix: 

    [patch]

* bulk change for the keyword
* summary lines may be edited manually (not in bulk). 

Keyword descriptions and search interface: 

    <https://bugs.freebsd.org/bugzilla/describekeywords.cgi>