Looking at https://github.com/freebsd/freebsd-src/blob/872164f559d2637f8de30fcd9da46d9b43d24328/sys/netinet/in_pcb.c#L1312-L1331 and confirming by testing, any listening port, no matter which interface it is on, will also accept connections on 0.0.0.0/32. This has recently gained attention in the form of a "browser bug", where network sandboxing can be evaded (and remotely-loaded javascript can talk to any service running on the host). The original code is from BSD4.3, and (guessing here) might be there because someone didn't want to wait for the tape with the localhost interface code - or was simply too lazy to type 127.0.0.1? :)
The change appears to have originated in BSD here: https://github.com/csrg/csrg/commit/86fd50f180107b5998a451da64dd08668499e9f9 The context of these changes is that at the time, the broadcast address appeared to be all zeroes, and this series of commits was creating separate INADDR_ANY and INADDR_BROADCAST. Curiously, INADDR_ANY was previously blocked by the old code in in_pcbconnect: https://github.com/csrg/csrg/commit/86fd50f180107b5998a451da64dd08668499e9f9#diff-947bd731f5c96a4641a584beac83dfcab5bac246a65cdba49fcf041bbb0ad5aeL111-R121 It does seem to be intentional, and the comment documenting it was added a month later in commit 125629be4b7de3a379dee96a625a272271c0bb87. Given that it was an error before makes me wonder if this might have been intended as some sort of compatibility hack? One of the other commits in this series is https://github.com/csrg/csrg/commit/b7aed1f9e438540acd1a66e07dd809fe8af34021 which added some similar logic in icmp_reflect(). That logic was later cleaned up a few months later in commit 36dd422b2b80fd43eb60c920c2494858cded07b8 to not depend on INADDR_ANY, and I believe that commit 02eb20c4604d7dad81aaa8cf7a96ef9f712f410d effectively blocked ICMP replies back to 0.0.0.0. macOS Sonoma seems to also still support this behavior. I do think just removing the block of code in question is sensible.
Some rudimentary testing - on my own retro hardware and on copy.sh/v86/ - it seems that many OSes with IP stacks of BSD origin share this trait. Notable exceptions are OpenBSD and Windows 2000, but macOS, NetBSD, Haiku and others all do this. Even OS/2, at least versions 2.11 and 3.0 (both 16 and 32-bit TCP/IP stacks). I can't think of a good reason to keep this now, but I'll leave that decision to people with more experience with obscure use cases. Perhaps hide it behind a compile-time option, default off?
It certainly was intentional and I think documented. The first libresolv depended upon an uninitialized resaddr being the local host.
(In reply to paul vixie from comment #4) I don't think that's a concern any longer, is it? The reason I'm even reporting this as a bug (and not simply leaving it to browser vendors to fix since that's how this surfaced now) is how it completely blindsides anyone who might come across it, and I would not be surprised if a plethora of new attack vectors - having nothing to do with browsers - crop up in the near future. I don't have a firm understanding of how bad it might be, but it might be worth a security advisory. Then again, I might be seeing ghosts in broad daylight. (Well, a ghost it is, I guess..)
It has always been the case that if you bind to inaddr_any your socket will be available on all host interface addresses, and if you connect or sendto inaddr_any you'll reach some socket bound to some host interface address. In that sense yes this will be a breaking change. However, it's "good trouble" and we should follow openbsd's lead on the matter.
It seems to me that the logical first step is to introduce a sysctl to control this behaviour. Using that, we can see what breaks. I posted a straw proposal here: https://reviews.freebsd.org/D46259
(In reply to paul vixie from comment #6) But this happens also if you do not; bind *only* to localhost, and it works. Bind *only* to some other interface, and it works.
(In reply to Eirik Oeverby from comment #8) I tried this on 14.0-stable from March, and from my testing, it appears this does happen if you bind to 127.0.0.1, but not any other IP (even 127.0.0.2 aliased on lo0 didn't exhibit the behaviour) IE bind to 127.0.0.1 allows connections to 0.0.0.0, but binding to anything else doesn't. Still, I wouldn't have expected the bind to 127.0.0.1 to accept 0.0.0.0
(In reply to Jamie Landeg-Jones from comment #9) Apparently, I may have misread my own tests. I cannot reproduce other than with 127.0.0.1/0.0.0.0 now. Not sure what I was doing. However, the original statement in the subject stands.
(In reply to Eirik Oeverby from comment #10) > However, the original statement in the subject stands. Yep, I agreed with you in my last sentence!
I also support idea of removing this whole block of code, including the case for INADDR_BROADCAST as well.
A commit in branch main references this bug: URL: https://cgit.FreeBSD.org/src/commit/?id=417b35a97b7669eb0bf417b43e97cccbedbce6f9 commit 417b35a97b7669eb0bf417b43e97cccbedbce6f9 Author: Mark Johnston <markj@FreeBSD.org> AuthorDate: 2024-08-20 21:31:57 +0000 Commit: Mark Johnston <markj@FreeBSD.org> CommitDate: 2024-08-20 21:31:57 +0000 netinet: Add a sysctl to allow disabling connections to INADDR_ANY See the discussion in Bugzilla PR 280705 for context. PR: 280705 MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D46259 sys/netinet/in_pcb.c | 8 +++++++- sys/netinet6/in6_pcb.c | 12 +++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-)
A commit in branch stable/14 references this bug: URL: https://cgit.FreeBSD.org/src/commit/?id=8ae58e0edbfb4c56125fb6d7468ebfea638847b9 commit 8ae58e0edbfb4c56125fb6d7468ebfea638847b9 Author: Mark Johnston <markj@FreeBSD.org> AuthorDate: 2024-08-20 21:31:57 +0000 Commit: Mark Johnston <markj@FreeBSD.org> CommitDate: 2024-09-03 14:54:42 +0000 netinet: Add a sysctl to allow disabling connections to INADDR_ANY See the discussion in Bugzilla PR 280705 for context. PR: 280705 MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D46259 (cherry picked from commit 417b35a97b7669eb0bf417b43e97cccbedbce6f9) sys/netinet/in_pcb.c | 8 +++++++- sys/netinet6/in6_pcb.c | 12 +++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-)