On Wed, Jul 10, 2024 at 07:13:26PM +0200, Stefano Brivio wrote:On Wed, 10 Jul 2024 10:23:14 +1000 David Gibson <david(a)gibson.dropbear.id.au> wrote: > On Wed, Jul 10, 2024 at 12:32:33AM +0200, Stefano Brivio wrote: > > On Fri, 5 Jul 2024 12:07:18 +1000 > > David Gibson <david(a)gibson.dropbear.id.au> wrote:[snip]So.. yes, this would check whether close() on a non-last fd for a socket triggers socket closing actions, but that's much stricter than what we actually need here. I would, for example, expect shutdown() on a TCP socket to affect all dups - and I don't actually know if a close() on one dup might trigger that. But we're dealing with UDP here, so there's no "on wire" effect of a close. So all we actually need to check is: 1. Open a "listening" udp socket 2. Dup it 3. Close a dup 4. Can the remaining dup still receive datagrams? I've written a test program for this, which I'll include in the next spin.Ah, probably, yes.I don't believe so. My understanding is that dup() (and the rest) make a new fd referencing the same underlying file object, yes. But AIUI, close() just closes one fd - the underlying object is only closed only when all fds are gone.+ uflow->s[INISIDE] = fcntl(s_ini, F_DUPFD_CLOEXEC, 0);There's one aspect of this I don't understand: if s_ini is closed while checking for bound ports (is it? I didn't really reach the end of this series), aren't duplicates also closed? That is, the documentation of dup2(2), which should be the same for this purpose, states that the duplicate inherits "file status flags", which I would assume also includes the fact that a socket is closed. I didn't test that though.I didn't really find the time to sketch this but I guess the easiest way to check this behaviour is to have a TCP connection between a socket pair, with one socket having two descriptors, then closing one descriptor and check if the peer socket sees a closed connection (recv() returning 0 or similar).If duplicates are closed, I guess an alternative solution could be to introduce some kind of reference counting for sockets... somewhere... in other words, I believe the kernel does the reference counting. I should verify this though, I'll try to come up with something new for doc/platform-requirements.I was wondering whether it's worth to use the vforked namespaced peer trick I drafted here: https://archives.passt.top/passt-dev/20231206160808.3d312733@elisabeth/ just in case we want to use some of those test cases for actual tests, where we don't want to bind an actual TCP port on the machine we're running on. But if it adds complexity I'd say it's not worth it.Yeah, I tend to think we can add that sort of sandboxing when and if we need it. -- David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson