diff options
author | Elad Namdar <eladnamdar@gmail.com> | 2019-05-07 00:24:22 +0300 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2019-05-08 13:12:30 +1000 |
commit | 3f54462adddb3210b46f3dba3f1879cd01e2f16e (patch) | |
tree | 12729001a8d1a88132f4cc1329cf44f8cc593edb | |
parent | b8c74014e42331afca3db5911b30032a109f73f1 (diff) |
unix/modusocket: Fix use of setsockopt in usocket.settimeout impl.
The original code called setsockopt(SO_RCVTIMEO/SO_SNDTIMEO) with NULL
timeout structure argument, which is an illegal usage of that function.
The old code also didn't validate the return value of setsockopt, missing
the bug completely.
-rw-r--r-- | ports/unix/modusocket.c | 20 |
1 files changed, 11 insertions, 9 deletions
diff --git a/ports/unix/modusocket.c b/ports/unix/modusocket.c index fd4092a62..a0f0fc25b 100644 --- a/ports/unix/modusocket.c +++ b/ports/unix/modusocket.c @@ -337,10 +337,9 @@ STATIC mp_obj_t socket_settimeout(mp_obj_t self_in, mp_obj_t timeout_in) { struct timeval tv = {0,}; bool new_blocking = true; - if (timeout_in == mp_const_none) { - setsockopt(self->fd, SOL_SOCKET, SO_RCVTIMEO, NULL, 0); - setsockopt(self->fd, SOL_SOCKET, SO_SNDTIMEO, NULL, 0); - } else { + // Timeout of None means no timeout, which in POSIX is signified with 0 timeout, + // and that's how 'tv' is initialized above + if (timeout_in != mp_const_none) { #if MICROPY_PY_BUILTINS_FLOAT mp_float_t val = mp_obj_get_float(timeout_in); double ipart; @@ -354,14 +353,17 @@ STATIC mp_obj_t socket_settimeout(mp_obj_t self_in, mp_obj_t timeout_in) { // for Python API it means non-blocking. if (tv.tv_sec == 0 && tv.tv_usec == 0) { new_blocking = false; - } else { - setsockopt(self->fd, SOL_SOCKET, SO_RCVTIMEO, - &tv, sizeof(struct timeval)); - setsockopt(self->fd, SOL_SOCKET, SO_SNDTIMEO, - &tv, sizeof(struct timeval)); } } + if (new_blocking) { + int r; + r = setsockopt(self->fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(struct timeval)); + RAISE_ERRNO(r, errno); + r = setsockopt(self->fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(struct timeval)); + RAISE_ERRNO(r, errno); + } + if (self->blocking != new_blocking) { socket_setblocking(self_in, mp_obj_new_bool(new_blocking)); } |