From 53c6a09b93fc272d0816a11997a02ffb7d0017e5 Mon Sep 17 00:00:00 2001 From: Syrone Wong Date: Fri, 15 Apr 2016 23:35:16 +0800 Subject: [PATCH] Reset errno to 0 before checking it errno is never set to zero by any system call or library function, and it's programmer's resposibility to reset it before doing checks. Otherwise the error might be misleading. Signed-off-by: Syrone Wong --- src/local.c | 10 +++++++--- src/manager.c | 2 ++ src/redir.c | 6 ++++++ src/server.c | 8 ++++++++ src/tunnel.c | 6 ++++++ src/utils.c | 6 ++++++ 6 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/local.c b/src/local.c index 61036b6e..239caffb 100644 --- a/src/local.c +++ b/src/local.c @@ -222,7 +222,7 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents) } ssize_t r; - + errno = 0; r = recv(server->fd, buf->array, BUF_SIZE, 0); if (r == 0) { @@ -312,6 +312,7 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents) s = send(remote->fd, remote->buf->array, remote->buf->len, 0); } #else + errno = 0; int s = sendto(remote->fd, remote->buf->array, remote->buf->len, MSG_FASTOPEN, (struct sockaddr *)&(remote->addr), remote->addr_len); #endif @@ -349,6 +350,7 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents) #endif } } else { + errno = 0; int s = send(remote->fd, remote->buf->array, remote->buf->len, 0); if (s == -1) { if (errno == EAGAIN || errno == EWOULDBLOCK) { @@ -581,6 +583,7 @@ static void server_send_cb(EV_P_ ev_io *w, int revents) return; } else { // has data to send + errno = 0; ssize_t s = send(server->fd, server->buf->array + server->buf->idx, server->buf->len, 0); if (s < 0) { @@ -644,7 +647,7 @@ static void remote_recv_cb(EV_P_ ev_io *w, int revents) #ifdef ANDROID stat_update_cb(loop); #endif - + errno = 0; ssize_t r = recv(remote->fd, server->buf->array, BUF_SIZE, 0); if (r == 0) { @@ -679,7 +682,7 @@ static void remote_recv_cb(EV_P_ ev_io *w, int revents) return; } } - + errno = 0; int s = send(server->fd, server->buf->array, server->buf->len, 0); if (s == -1) { @@ -742,6 +745,7 @@ static void remote_send_cb(EV_P_ ev_io *w, int revents) return; } else { // has data to send + errno = 0; ssize_t s = send(remote->fd, remote->buf->array + remote->buf->idx, remote->buf->len, 0); if (s < 0) { diff --git a/src/manager.c b/src/manager.c index 650effa8..8bd72e12 100644 --- a/src/manager.c +++ b/src/manager.c @@ -758,6 +758,7 @@ int main(int argc, char **argv) const char *homedir = pw->pw_dir; snprintf(working_dir, PATH_MAX, "%s/.shadowsocks", homedir); + errno = 0; int err = mkdir(working_dir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); if (err != 0 && errno != EEXIST) { ERROR("mkdir"); @@ -788,6 +789,7 @@ int main(int argc, char **argv) setnonblocking(sfd); + errno = 0; if (remove(manager_address) == -1 && errno != ENOENT) { ERROR("bind"); exit(EXIT_FAILURE); diff --git a/src/redir.c b/src/redir.c index 93bab5ec..9a6d81e5 100644 --- a/src/redir.c +++ b/src/redir.c @@ -171,6 +171,7 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents) server_t *server = server_recv_ctx->server; remote_t *remote = server->remote; + errno = 0; ssize_t r = recv(server->fd, remote->buf->array, BUF_SIZE, 0); if (r == 0) { @@ -212,6 +213,7 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents) return; } + errno = 0; int s = send(remote->fd, remote->buf->array, remote->buf->len, 0); if (s == -1) { @@ -248,6 +250,7 @@ static void server_send_cb(EV_P_ ev_io *w, int revents) return; } else { // has data to send + errno = 0; ssize_t s = send(server->fd, server->buf->array + server->buf->idx, server->buf->len, 0); if (s < 0) { @@ -291,6 +294,7 @@ static void remote_recv_cb(EV_P_ ev_io *w, int revents) remote_t *remote = remote_recv_ctx->remote; server_t *server = remote->server; + errno = 0; ssize_t r = recv(remote->fd, server->buf->array, BUF_SIZE, 0); if (r == 0) { @@ -320,6 +324,7 @@ static void remote_recv_cb(EV_P_ ev_io *w, int revents) close_and_free_server(EV_A_ server); return; } + errno = 0; int s = send(server->fd, server->buf->array, server->buf->len, 0); if (s == -1) { @@ -424,6 +429,7 @@ static void remote_send_cb(EV_P_ ev_io *w, int revents) return; } else { // has data to send + errno = 0; ssize_t s = send(remote->fd, remote->buf->array + remote->buf->idx, remote->buf->len, 0); if (s < 0) { diff --git a/src/server.c b/src/server.c index f26a8696..15aead4b 100644 --- a/src/server.c +++ b/src/server.c @@ -273,6 +273,7 @@ int setfastopen(int fd) #else int opt = 5; #endif + errno = 0; s = setsockopt(fd, IPPROTO_TCP, TCP_FASTOPEN, &opt, sizeof(opt)); if (s == -1) { if (errno == EPROTONOSUPPORT || errno == ENOPROTOOPT) { @@ -452,6 +453,7 @@ static remote_t *connect_to_remote(struct addrinfo *res, s = len; } #else + errno = 0; ssize_t s = sendto(sockfd, server->buf->array + server->buf->idx, server->buf->len, MSG_FASTOPEN, res->ai_addr, res->ai_addrlen); @@ -501,6 +503,7 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents) len = 0; } + errno = 0; ssize_t r = recv(server->fd, buf->array + len, BUF_SIZE - len, 0); if (r == 0) { @@ -563,6 +566,7 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents) close_and_free_remote(EV_A_ remote); return; } + errno = 0; int s = send(remote->fd, remote->buf->array, remote->buf->len, 0); if (s == -1) { if (errno == EAGAIN || errno == EWOULDBLOCK) { @@ -833,6 +837,7 @@ static void server_send_cb(EV_P_ ev_io *w, int revents) return; } else { // has data to send + errno = 0; ssize_t s = send(server->fd, server->buf->array + server->buf->idx, server->buf->len, 0); if (s < 0) { @@ -948,6 +953,7 @@ static void remote_recv_cb(EV_P_ ev_io *w, int revents) ev_timer_again(EV_A_ & server->recv_ctx->watcher); + errno = 0; ssize_t r = recv(remote->fd, server->buf->array, BUF_SIZE, 0); if (r == 0) { @@ -983,6 +989,7 @@ static void remote_recv_cb(EV_P_ ev_io *w, int revents) return; } + errno = 0; int s = send(server->fd, server->buf->array, server->buf->len, 0); if (s == -1) { @@ -1055,6 +1062,7 @@ static void remote_send_cb(EV_P_ ev_io *w, int revents) return; } else { // has data to send + errno = 0; ssize_t s = send(remote->fd, remote->buf->array + remote->buf->idx, remote->buf->len, 0); if (s == -1) { diff --git a/src/tunnel.c b/src/tunnel.c index f581e096..892390f3 100644 --- a/src/tunnel.c +++ b/src/tunnel.c @@ -186,6 +186,7 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents) return; } + errno = 0; ssize_t r = recv(server->fd, remote->buf->array, BUF_SIZE, 0); if (r == 0) { @@ -221,6 +222,7 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents) return; } + errno = 0; int s = send(remote->fd, remote->buf->array, remote->buf->len, 0); if (s == -1) { @@ -257,6 +259,7 @@ static void server_send_cb(EV_P_ ev_io *w, int revents) return; } else { // has data to send + errno = 0; ssize_t s = send(server->fd, server->buf->array + server->buf->idx, server->buf->len, 0); if (s < 0) { @@ -310,6 +313,7 @@ static void remote_recv_cb(EV_P_ ev_io *w, int revents) remote_t *remote = remote_recv_ctx->remote; server_t *server = remote->server; + errno = 0; ssize_t r = recv(remote->fd, server->buf->array, BUF_SIZE, 0); if (r == 0) { @@ -341,6 +345,7 @@ static void remote_recv_cb(EV_P_ ev_io *w, int revents) return; } + errno = 0; int s = send(server->fd, server->buf->array, server->buf->len, 0); if (s == -1) { @@ -471,6 +476,7 @@ static void remote_send_cb(EV_P_ ev_io *w, int revents) return; } else { // has data to send + errno = 0; ssize_t s = send(remote->fd, remote->buf->array + remote->buf->idx, remote->buf->len, 0); if (s < 0) { diff --git a/src/utils.c b/src/utils.c index cff3c6c7..2c07bcda 100644 --- a/src/utils.c +++ b/src/utils.c @@ -102,16 +102,19 @@ int run_as(const char *user) /* Note that we use getpwnam_r() instead of getpwnam(), * which returns its result in a statically allocated buffer and * cannot be considered thread safe. */ + errno = 0; err = getpwnam_r(user, &pwdbuf, buf, buflen, &pwd); if (err == 0 && pwd) { /* setgid first, because we may not be allowed to do it anymore after setuid */ + errno = 0; if (setgid(pwd->pw_gid) != 0) { LOGE( "Could not change group id to that of run_as user '%s': %s", user, strerror(errno)); return 0; } + errno = 0; if (setuid(pwd->pw_uid) != 0) { LOGE( @@ -147,11 +150,13 @@ int run_as(const char *user) return 0; } /* setgid first, because we may not allowed to do it anymore after setuid */ + errno = 0; if (setgid(pwd->pw_gid) != 0) { LOGE("Could not change group id to that of run_as user '%s': %s", user, strerror(errno)); return 0; } + errno = 0; if (setuid(pwd->pw_uid) != 0) { LOGE("Could not change user id to that of run_as user '%s': %s", user, strerror(errno)); @@ -351,6 +356,7 @@ int set_nofile(int nofile) if (nofile <= 0) { FATAL("nofile must be greater than 0\n"); } + errno = 0; if (setrlimit(RLIMIT_NOFILE, &limit) < 0) { if (errno == EPERM) {