Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitbaaf54f

Browse files
committed
extmod/modlwip: Fix crash when calling recv on listening socket.
Add check to prevent calling recv on a socket in the listening state.This prevents a crash/hard fault when user code mistakenly tries torecv on the listening socket instead of on the accepted connection.Add corresponding test case to demonstrate the bug.Signed-off-by: Andrew Leech <andrew.leech@planetinnovation.com.au>
1 parent186caf9 commitbaaf54f

File tree

2 files changed

+56
-15
lines changed

2 files changed

+56
-15
lines changed

‎extmod/modlwip.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -854,6 +854,12 @@ static mp_uint_t lwip_tcp_receive(lwip_socket_obj_t *socket, byte *buf, mp_uint_
854854
}
855855
}
856856

857+
if (socket->state==STATE_LISTENING) {
858+
// original socket in listening state, not the accepted connection.
859+
*_errno=MP_ENOTCONN;
860+
return-1;
861+
}
862+
857863
MICROPY_PY_LWIP_ENTER
858864

859865
assert(socket->pcb.tcp!= NULL);

‎tests/multi_net/tcp_accept_recv.py

Lines changed: 50 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,65 @@
1-
# Test recv on socketthat just accepted a connection
1+
# Test recv onlisteningsocketafter accept with various listen() arguments
22

33
importsocket
44

55
PORT=8000
66

7+
# Test cases for listen() function
8+
LISTEN_ARGS= [None,0,1,2]# None means no argument
9+
710

811
# Server
912
definstance0():
1013
multitest.globals(IP=multitest.get_network_ip())
11-
s=socket.socket()
12-
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
13-
s.bind(socket.getaddrinfo("0.0.0.0",PORT)[0][-1])
14-
s.listen(1)
14+
15+
fori,listen_arginenumerate(LISTEN_ARGS):
16+
s=socket.socket()
17+
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
18+
s.bind(socket.getaddrinfo("0.0.0.0",PORT)[0][-1])
19+
20+
# Call listen with or without argument based on test case
21+
iflisten_argisNone:
22+
print(f"Test case{i+1}/{len(LISTEN_ARGS)}: listen()")
23+
s.listen()
24+
else:
25+
print(f"Test case{i+1}/{len(LISTEN_ARGS)}: listen({listen_arg})")
26+
s.listen(listen_arg)
27+
28+
# Signal client that server is ready
29+
multitest.broadcast(f"server_ready_{i}")
30+
31+
# Wait for client connection
32+
c,_=s.accept()
33+
34+
try:
35+
print("recv",s.recv(10))# should raise Errno 107 ENOTCONN
36+
exceptOSErroraser:
37+
# Verify the error code is either 107 (ENOTCONN) or 128 (ENOTCONN on Windows)
38+
print(er.errnoin (107,128))
39+
40+
# Cleanup
41+
c.close()
42+
s.close()
43+
44+
# Signal client we're done with this test case
45+
multitest.broadcast(f"server_done_{i}")
46+
1547
multitest.next()
16-
s.accept()
17-
try:
18-
print("recv",s.recv(10))# should raise Errno 107 ENOTCONN
19-
exceptOSErroraser:
20-
print(er.errnoin (107,128))
21-
s.close()
2248

2349

2450
# Client
2551
definstance1():
2652
multitest.next()
27-
s=socket.socket()
28-
s.connect(socket.getaddrinfo(IP,PORT)[0][-1])
29-
s.send(b"GET / HTTP/1.0\r\n\r\n")
30-
s.close()
53+
54+
fori,_inenumerate(LISTEN_ARGS):
55+
# Wait for server to be ready
56+
multitest.wait(f"server_ready_{i}")
57+
58+
# Connect to server
59+
s=socket.socket()
60+
s.connect(socket.getaddrinfo(IP,PORT)[0][-1])
61+
s.send(b"GET / HTTP/1.0\r\n\r\n")
62+
s.close()
63+
64+
# Wait for server to finish this test case
65+
multitest.wait(f"server_done_{i}")

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp