summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorElad Namdar <eladnamdar@gmail.com>2019-05-07 00:24:22 +0300
committerDamien George <damien.p.george@gmail.com>2019-05-08 13:12:30 +1000
commit3f54462adddb3210b46f3dba3f1879cd01e2f16e (patch)
tree12729001a8d1a88132f4cc1329cf44f8cc593edb
parentb8c74014e42331afca3db5911b30032a109f73f1 (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.c20
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));
}