micropython/tests/extmod/socket_badconstructor.py
Damien George 406356ec8b extmod/modlwip: Ensure socket is finalisable if error during creation.
Because socket objects have a finaliser they must be created carefully, in
case an exception is raised during the population of their members, eg
invalid input argument or out-of-memory when allocating additional arrays.

Prior to the fix in this commit, the finaliser would crash due to
`incoming.udp_raw.array` being an invalid pointer in the following cases:
- if a SOCK_RAW was created with a proto argument that was not an integer
- if a SOCK_DGRAM or SOCK_RAW was created where the allocation of
  `lwip_incoming_packet_t` failed
- if an integer was passed in for the socket type but it was not one of
  SOCK_STREAM, SOCK_DGRAM or SOCK_RAW

Furthermore, if the allocation of `lwip_incoming_packet_t` failed then it
may have led to corruption within lwIP when freeing `socket->pcb.raw`
because that PCB was not fully set up with its callbacks.

This commit fixes all of these issues by ensuring:
- `pcb.tcp` and `incoming.udp_raw.array` are initialised to NULL early on
- the proto argument is parsed before allocating the PCB
- the allocation of `lwip_incoming_packet_t` occurs befor allocating the
  PCB
- `incoming.udp_raw.array` is checked for NULL in the finaliser code

The corresponding test (which already checked most of these causes of
failure) has been updated to include a previously-uncovered scenario.

Signed-off-by: Damien George <damien@micropython.org>
2026-03-21 16:39:40 +11:00

28 lines
493 B
Python

# Test passing in bad values to socket.socket constructor.
try:
import socket
except:
print("SKIP")
raise SystemExit
try:
s = socket.socket(None)
except TypeError:
print("TypeError")
try:
s = socket.socket(socket.AF_INET, None)
except TypeError:
print("TypeError")
try:
s = socket.socket(socket.AF_INET, 123456)
except OSError:
print("OSError")
try:
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, None)
except TypeError:
print("TypeError")