Skip to content

Commit 04d8b7c

Browse files
jukkarmmahadevan108
authored andcommitted
net: sockets: Cleanup socket properly if POSIX API is enabled
The sock_obj_core_dealloc() was not called if close() is called instead of zsock_close(). This happens if POSIX API is enabled. Fix this by calling zvfs_close() from zsock_close() and then pass the socket number to zsock_close_ctx() so that the cleanup can be done properly. Reported-by: Andreas Ålgård <[email protected]> Signed-off-by: Jukka Rissanen <[email protected]>
1 parent 92d0287 commit 04d8b7c

File tree

7 files changed

+48
-40
lines changed

7 files changed

+48
-40
lines changed

include/zephyr/sys/fdtable.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,10 @@ struct fd_op_vtable {
6464
ssize_t (*write)(void *obj, const void *buf, size_t sz);
6565
ssize_t (*write_offs)(void *obj, const void *buf, size_t sz, size_t offset);
6666
};
67-
int (*close)(void *obj);
67+
union {
68+
int (*close)(void *obj);
69+
int (*close2)(void *obj, int fd);
70+
};
6871
int (*ioctl)(void *obj, unsigned int request, va_list args);
6972
};
7073

lib/os/fdtable.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,14 @@ int zvfs_close(int fd)
389389
(void)k_mutex_lock(&fdtable[fd].lock, K_FOREVER);
390390
if (fdtable[fd].vtable->close != NULL) {
391391
/* close() is optional - e.g. stdinout_fd_op_vtable */
392-
res = fdtable[fd].vtable->close(fdtable[fd].obj);
392+
if (fdtable[fd].mode & ZVFS_MODE_IFSOCK) {
393+
/* Network socket needs to know socket number so pass
394+
* it via close2() call.
395+
*/
396+
res = fdtable[fd].vtable->close2(fdtable[fd].obj, fd);
397+
} else {
398+
res = fdtable[fd].vtable->close(fdtable[fd].obj);
399+
}
393400
}
394401
k_mutex_unlock(&fdtable[fd].lock);
395402

subsys/net/lib/sockets/sockets.c

Lines changed: 8 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -147,42 +147,26 @@ static inline int z_vrfy_zsock_socket(int family, int type, int proto)
147147
#include <zephyr/syscalls/zsock_socket_mrsh.c>
148148
#endif /* CONFIG_USERSPACE */
149149

150+
extern int zvfs_close(int fd);
151+
150152
int z_impl_zsock_close(int sock)
153+
{
154+
return zvfs_close(sock);
155+
}
156+
157+
#ifdef CONFIG_USERSPACE
158+
static inline int z_vrfy_zsock_close(int sock)
151159
{
152160
const struct socket_op_vtable *vtable;
153161
struct k_mutex *lock;
154162
void *ctx;
155-
int ret;
156-
157-
SYS_PORT_TRACING_OBJ_FUNC_ENTER(socket, close, sock);
158163

159164
ctx = get_sock_vtable(sock, &vtable, &lock);
160165
if (ctx == NULL) {
161166
errno = EBADF;
162-
SYS_PORT_TRACING_OBJ_FUNC_EXIT(socket, close, sock, -errno);
163167
return -1;
164168
}
165169

166-
(void)k_mutex_lock(lock, K_FOREVER);
167-
168-
NET_DBG("close: ctx=%p, fd=%d", ctx, sock);
169-
170-
ret = vtable->fd_vtable.close(ctx);
171-
172-
k_mutex_unlock(lock);
173-
174-
SYS_PORT_TRACING_OBJ_FUNC_EXIT(socket, close, sock, ret < 0 ? -errno : ret);
175-
176-
zvfs_free_fd(sock);
177-
178-
(void)sock_obj_core_dealloc(sock);
179-
180-
return ret;
181-
}
182-
183-
#ifdef CONFIG_USERSPACE
184-
static inline int z_vrfy_zsock_close(int sock)
185-
{
186170
return z_impl_zsock_close(sock);
187171
}
188172
#include <zephyr/syscalls/zsock_close_mrsh.c>

subsys/net/lib/sockets/sockets_inet.c

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -137,10 +137,14 @@ static int zsock_socket_internal(int family, int type, int proto)
137137
return fd;
138138
}
139139

140-
int zsock_close_ctx(struct net_context *ctx)
140+
int zsock_close_ctx(struct net_context *ctx, int sock)
141141
{
142142
int ret;
143143

144+
SYS_PORT_TRACING_OBJ_FUNC_ENTER(socket, close, sock);
145+
146+
NET_DBG("close: ctx=%p, fd=%d", ctx, sock);
147+
144148
/* Reset callbacks to avoid any race conditions while
145149
* flushing queues. No need to check return values here,
146150
* as these are fail-free operations and we're closing
@@ -160,10 +164,16 @@ int zsock_close_ctx(struct net_context *ctx)
160164
ret = net_context_put(ctx);
161165
if (ret < 0) {
162166
errno = -ret;
163-
return -1;
167+
ret = -1;
164168
}
165169

166-
return 0;
170+
SYS_PORT_TRACING_OBJ_FUNC_EXIT(socket, close, sock, ret < 0 ? -errno : ret);
171+
172+
if (ret == 0) {
173+
(void)sock_obj_core_dealloc(sock);
174+
}
175+
176+
return ret;
167177
}
168178

169179
static void zsock_accepted_cb(struct net_context *new_ctx,
@@ -2771,9 +2781,9 @@ static int sock_setsockopt_vmeth(void *obj, int level, int optname,
27712781
return zsock_setsockopt_ctx(obj, level, optname, optval, optlen);
27722782
}
27732783

2774-
static int sock_close_vmeth(void *obj)
2784+
static int sock_close2_vmeth(void *obj, int fd)
27752785
{
2776-
return zsock_close_ctx(obj);
2786+
return zsock_close_ctx(obj, fd);
27772787
}
27782788
static int sock_getpeername_vmeth(void *obj, struct sockaddr *addr,
27792789
socklen_t *addrlen)
@@ -2791,7 +2801,7 @@ const struct socket_op_vtable sock_fd_op_vtable = {
27912801
.fd_vtable = {
27922802
.read = sock_read_vmeth,
27932803
.write = sock_write_vmeth,
2794-
.close = sock_close_vmeth,
2804+
.close2 = sock_close2_vmeth,
27952805
.ioctl = sock_ioctl_vmeth,
27962806
},
27972807
.shutdown = sock_shutdown_vmeth,

subsys/net/lib/sockets/sockets_internal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
#define SOCK_NONBLOCK 2
1616
#define SOCK_ERROR 4
1717

18-
int zsock_close_ctx(struct net_context *ctx);
18+
int zsock_close_ctx(struct net_context *ctx, int sock);
1919
int zsock_poll_internal(struct zsock_pollfd *fds, int nfds, k_timeout_t timeout);
2020

2121
int zsock_wait_data(struct net_context *ctx, k_timeout_t *timeout);

subsys/net/lib/sockets/sockets_packet.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -462,16 +462,16 @@ static int packet_sock_setsockopt_vmeth(void *obj, int level, int optname,
462462
return zpacket_setsockopt_ctx(obj, level, optname, optval, optlen);
463463
}
464464

465-
static int packet_sock_close_vmeth(void *obj)
465+
static int packet_sock_close2_vmeth(void *obj, int fd)
466466
{
467-
return zsock_close_ctx(obj);
467+
return zsock_close_ctx(obj, fd);
468468
}
469469

470470
static const struct socket_op_vtable packet_sock_fd_op_vtable = {
471471
.fd_vtable = {
472472
.read = packet_sock_read_vmeth,
473473
.write = packet_sock_write_vmeth,
474-
.close = packet_sock_close_vmeth,
474+
.close2 = packet_sock_close2_vmeth,
475475
.ioctl = packet_sock_ioctl_vmeth,
476476
},
477477
.bind = packet_sock_bind_vmeth,

subsys/net/lib/sockets/sockets_tls.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2108,7 +2108,7 @@ static int ztls_socket(int family, int type, int proto)
21082108
return -1;
21092109
}
21102110

2111-
int ztls_close_ctx(struct tls_context *ctx)
2111+
int ztls_close_ctx(struct tls_context *ctx, int sock)
21122112
{
21132113
int ret, err = 0;
21142114

@@ -2120,6 +2120,10 @@ int ztls_close_ctx(struct tls_context *ctx)
21202120
err = tls_release(ctx);
21212121
ret = zsock_close(ctx->sock);
21222122

2123+
if (ret == 0) {
2124+
(void)sock_obj_core_dealloc(sock);
2125+
}
2126+
21232127
/* In case close fails, we propagate errno value set by close.
21242128
* In case close succeeds, but tls_release fails, set errno
21252129
* according to tls_release return value.
@@ -3826,9 +3830,9 @@ static int tls_sock_setsockopt_vmeth(void *obj, int level, int optname,
38263830
return ztls_setsockopt_ctx(obj, level, optname, optval, optlen);
38273831
}
38283832

3829-
static int tls_sock_close_vmeth(void *obj)
3833+
static int tls_sock_close2_vmeth(void *obj, int sock)
38303834
{
3831-
return ztls_close_ctx(obj);
3835+
return ztls_close_ctx(obj, sock);
38323836
}
38333837

38343838
static int tls_sock_getpeername_vmeth(void *obj, struct sockaddr *addr,
@@ -3851,7 +3855,7 @@ static const struct socket_op_vtable tls_sock_fd_op_vtable = {
38513855
.fd_vtable = {
38523856
.read = tls_sock_read_vmeth,
38533857
.write = tls_sock_write_vmeth,
3854-
.close = tls_sock_close_vmeth,
3858+
.close2 = tls_sock_close2_vmeth,
38553859
.ioctl = tls_sock_ioctl_vmeth,
38563860
},
38573861
.shutdown = tls_sock_shutdown_vmeth,

0 commit comments

Comments
 (0)