diff options
author | Signed-off-by: Susant Sahani <ssahani@redhat.com> | 2013-11-25 13:53:28 -0500 |
---|---|---|
committer | Steve Dickson <steved@redhat.com> | 2013-11-25 14:10:49 -0500 |
commit | 514c713abc2ed83e551befa8e0273fb913030448 (patch) | |
tree | c6d87ef5335e033c86aa565e7f9ee3a26c61658a | |
parent | b8662e8079b986630575aa088c402643a3bda628 (diff) | |
download | ti-rpc-514c713abc2ed83e551befa8e0273fb913030448.tar.gz |
Race condition in bindresvport
The function clnt_create is *not* thread safe . Race conditions in
the function bindresvport that accesses static data port and startport,
which are *not* protected by any mutex. When more than one thread
access them the variables become a nonlocal side effect. These race
conditions
can lead to undesired behaviour . By introducing the mutex port_lock
the function bindresvport is serialized.
Signed-off-by: Susant Sahani <ssahani@redhat.com>
Signed-off-by: Steve Dickson <steved@redhat.com>
-rw-r--r-- | src/bindresvport.c | 17 | ||||
-rw-r--r-- | src/mt_misc.c | 3 |
2 files changed, 17 insertions, 3 deletions
diff --git a/src/bindresvport.c b/src/bindresvport.c index 6ce3e81..d6d9c14 100644 --- a/src/bindresvport.c +++ b/src/bindresvport.c @@ -46,6 +46,9 @@ #include <rpc/rpc.h> #include <string.h> +#include <reentrant.h> + +extern pthread_mutex_t port_lock; /* * Bind a socket to a privileged IP port @@ -80,16 +83,21 @@ bindresvport_sa(sd, sa) static u_int16_t port; static short startport = STARTPORT; socklen_t salen; - int nports = ENDPORT - startport + 1; + int nports; int endport = ENDPORT; int i; + mutex_lock(&port_lock); + nports = ENDPORT - startport + 1; + if (sa == NULL) { salen = sizeof(myaddr); sa = (struct sockaddr *)&myaddr; - if (getsockname(sd, (struct sockaddr *)&myaddr, &salen) == -1) - return -1; /* errno is correctly set */ + if (getsockname(sd, (struct sockaddr *)&myaddr, &salen) == -1) { + mutex_unlock(&port_lock); + return -1; /* errno is correctly set */ + } af = myaddr.ss_family; } else @@ -112,6 +120,7 @@ bindresvport_sa(sd, sa) #endif default: errno = EPFNOSUPPORT; + mutex_unlock(&port_lock); return (-1); } sa->sa_family = af; @@ -137,6 +146,8 @@ bindresvport_sa(sd, sa) port = LOWPORT + port % (STARTPORT - LOWPORT); goto again; } + mutex_unlock(&port_lock); + return (res); } #else diff --git a/src/mt_misc.c b/src/mt_misc.c index b24c130..ddbb0a5 100644 --- a/src/mt_misc.c +++ b/src/mt_misc.c @@ -94,6 +94,9 @@ pthread_mutex_t serialize_pkey = PTHREAD_MUTEX_INITIALIZER; /* protects global variables ni and nc_file (getnetconfig.c) */ pthread_mutex_t nc_db_lock = PTHREAD_MUTEX_INITIALIZER; +/* protects static port and startport (bindresvport.c) */ +pthread_mutex_t port_lock = PTHREAD_MUTEX_INITIALIZER; + #undef rpc_createerr struct rpc_createerr rpc_createerr; |