Fix the issue where loopback-bound sockets attempt to connect to a public IP#3531
Fix the issue where loopback-bound sockets attempt to connect to a public IP#3531stevenengler merged 14 commits intoshadow:mainfrom
Conversation
|
The current fix was based on two-month-old commits and passed all tests at that time. I'm still investigating why the tests are failing now. |
In the past month, we've migrated Shadow to the rust 2024 edition, the rustfmt 2024 edition, and are building with rust 1.85 in the CI now. There have also been some CI fixes due to a breaking change in rustup that may affect older commits that don't have the CI fixes. You might need to rebase to get the fixes, and then run rustfmt and clippy to make sure they still pass. |
|
Also thanks for the PR! One additional thing we'll need is some tests in (Also see #3526.) |
|
This PR is ready for review. I believe the new TCP implementation also has this issue. I attempted to fix it but couldn't write a test for the fix, as adding Additionally, I found a minor issue: calling connect() to a public IP on a socket bound to 127.0.0.1 returns EINVAL, but I believe it should return EISCONN. The EISCONN check is currently in the C code and needs to be moved out. shadow/src/main/host/descriptor/tcp.c Lines 1713 to 1716 in 3e478a9 Do you want me to include the fix for that issue within this PR? |
stevenengler
left a comment
There was a problem hiding this comment.
Thanks for the fixes and for the tests. This looks great! I just have one small change request, and then it's ready to merge.
Don't worry about the new TCP implementation. It still needs lots of work, and once we eventually enable the tests, they should fail and we'll remember to fix this there too.
If there's a bug here, feel free to fix this either in this MR, or a new MR. But I'm not clear on what the issue is here. Doesn't the new
Agreed. Hopefully we get there some day :) |
|
I'm going to merge the PR as-is, and I'll do a follow up with the small changes. I hope you don't mind. I think this PR is good and I'd like to get this in to shadow. |
Hi, sorry, I was a bit busy last week. I'll make the necessary changes today, and it'll be good. |
Okay no problem, I don't mean to rush you. I just figured the changes I mentioned would be easy for me to add. But if you want to do them then that's great too, whenever you get time. |
|
I've added another fix and test for loopback-bound listening sockets: sys_connect should return Can you review the changes I just made? |
stevenengler
left a comment
There was a problem hiding this comment.
I've added another fix and test for loopback-bound listening sockets: sys_connect should return
EISCONNregardless of whether the connecting address is loopback or not.Can you review the changes I just made?
These look good, thanks!
Previously a UDP socket that called `sendto()` would be implicitly bound to an address on the same interface. So sending to 127.0.0.1 would cause the socket to be bound to 127.0.0.1. Sending to 1.2.3.4 would cause the socket to be bound to the public IP address of the host. This PR fixes the behaviour so that regardless of the address used with `sendto()`, the socket will always be bound to 0.0.0.0. This, along with #3531, should fix #3526.
In the current sys_connect handler, sockets bound to localhost are not handled correctly.
shadow/src/main/host/descriptor/socket/inet/legacy_tcp.rs
Lines 760 to 765 in 3e478a9
Shadow does not check cases where it connects to an external address using a socket bound to 127.0.0.1, which later causes crashes when the worker fails to resolve the localhost address to a host.
shadow/src/main/core/worker.rs
Lines 356 to 358 in 3e478a9
The same issue also occurs with UDP (and possibly in tcp.rs).
This PR brings a fix to this issue, although I think we'd want to mimic a routing table and perform these handling there.