-
Notifications
You must be signed in to change notification settings - Fork 8.3k
net: posix: Fix close() not closing sockets properly #79357
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
With CONFIG_POSIX_API enabled close() does not call sock_obj_core_dealloc. This results in sockets not being closed properly, which can be verified by running the shell command 'net sockets' Signed-off-by: Andreas Ålgård <[email protected]>
af02269 to
f09c7d6
Compare
|
|
||
| zvfs_free_fd(fd); | ||
|
|
||
| (void)sock_obj_core_dealloc(fd); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is called by zsock_close() so wondering why we would need to call it again here. What kind of socket is this, a TLS one?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, I don't think we should call socket specific API here in the generic code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a TCP socket.
sock_obj_core_dealloc is indeed called by zsock_close, however with POSIX_API enabled we never reach zsock_close, and comparing the two functions the only real difference is that zsock_close actually calls sock_obj_core_dealloc, which properly closes the socket.
zsock_close does the following: https://github.com/zephyrproject-rtos/zephyr/blob/main/subsys/net/lib/sockets/sockets.c#L137
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something is now wrong if socket close is not called. Either this function should not be called at all but zsock_close() should, or the system should be configured so that the fdtable[fd].vtable->close(fdtable[fd].obj); would call the network socket close. In all cases this function should not do anything socket specific as this is a generic function that just dispatches the call to correct subsystem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I would agree - the vtable call should deallocate any fs-specific object associated with the generic fd.
|
|
||
| zvfs_free_fd(fd); | ||
|
|
||
| (void)sock_obj_core_dealloc(fd); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something is now wrong if socket close is not called. Either this function should not be called at all but zsock_close() should, or the system should be configured so that the fdtable[fd].vtable->close(fdtable[fd].obj); would call the network socket close. In all cases this function should not do anything socket specific as this is a generic function that just dispatches the call to correct subsystem.
|
@icsys-aal how did you see the issue, is there easy way to reproduce with network samples for example? |
|
Just to expand on the behavior we see, there is a difference between what happens when we call When calling close, with CONFIG_POSIX_API enabled, we see this call sequence: It's possible to reproduce similar behavior to what we see in our application by modifying the http_server sample application, which has However, with the original Adding I do agree that performing a socket operation in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's keep this code generic, and use the vtable call to deallocate fd-specific resources.
|
Couldn't the vtable method simply call |
|
I would suggest adding a file-descriptor memory leak test to the posix network testsuite as well. It should be sufficient to attempt to call |
|
I agree that calling a socket function in fdtable.c seems wrong, but I'm unable to see where else it is possible to do so. Currently, the As far as I can see, the only place that maps an fd to its corresponding The idea to call Are there any other options we're missing? |
zephyr/subsys/net/lib/sockets/sockets.c Line 166 in 1ec5ce0
|
Yeah, line 178 here, the call to |
The fd is only used to get the object, so it would make some sense to maybe factor that part out to a common function (preferably static) that could be called by both |
Thanks, but unfortunately it seems like the object used inside |
This is a strange case of fdtable usage because the same integer file descriptor is associated with two separate vtables. In that case, I would suggest that a union be made using the https://github.com/zephyrproject-rtos/zephyr/blob/main/include%2Fzephyr%2Fsys%2Ffdtable.h The With that, you can directly call |
Actually there is one fdtable involved, the zephyr/subsys/net/lib/sockets/sockets.c Line 53 in 6e653a9
There would be no issues if |
|
Perhaps calling it a vtable was the wrong terminology. Effectively though, the close method just needs access to the integer fd. I don't see any reason to keep that a secret from vtable methods though. Please see the solution in my previous comment. |
|
I think we could do and let |
Yes, I agree, we could easily pass the fd to |
@cfriedt How can we know in fdtable.c the type of the fd, this is not very clear to me? |
Found it, there is the |
|
I created alternative proposal here #80232, @icsys-aal please take a look if it works for you. |


With CONFIG_POSIX_API enabled close() does not call
sock_obj_core_dealloc. This results in sockets not being
closed properly, which can be verified by running the
shell command 'net sockets'