|
|
4c520e |
From 27ae6c5b8b37a8086800cd1a4edbb01a7fddfad6 Mon Sep 17 00:00:00 2001
|
|
|
4c520e |
From: Simo Sorce <simo@redhat.com>
|
|
|
4c520e |
Date: Thu, 21 Nov 2013 11:59:40 -0500
|
|
|
4c520e |
Subject: [PATCH 1/2] Add Thread-safe implementation of strerror()
|
|
|
4c520e |
MIME-Version: 1.0
|
|
|
4c520e |
Content-Type: text/plain; charset=UTF-8
|
|
|
4c520e |
Content-Transfer-Encoding: 8bit
|
|
|
4c520e |
|
|
|
4c520e |
Unfortunately strerror() is not thread safe so we have to juggle with
|
|
|
4c520e |
strerror_r() which is a can of worms as 2 incompatible implementations
|
|
|
4c520e |
are available depending on what is defined at compile time.
|
|
|
4c520e |
|
|
|
4c520e |
Try to do something sane.
|
|
|
4c520e |
|
|
|
4c520e |
https://fedorahosted.org/gss-proxy/ticket/111
|
|
|
4c520e |
|
|
|
4c520e |
Reviewed-by: Günther Deschner <gdeschner@redhat.com>
|
|
|
4c520e |
---
|
|
|
4c520e |
proxy/src/gp_common.h | 3 +++
|
|
|
4c520e |
proxy/src/gp_util.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
4c520e |
2 files changed, 62 insertions(+)
|
|
|
4c520e |
|
|
|
4c520e |
diff --git a/proxy/src/gp_common.h b/proxy/src/gp_common.h
|
|
|
4c520e |
index b5c525f..f2b8c3e 100644
|
|
|
4c520e |
--- a/proxy/src/gp_common.h
|
|
|
4c520e |
+++ b/proxy/src/gp_common.h
|
|
|
4c520e |
@@ -69,6 +69,9 @@ bool gp_same(const char *a, const char *b);
|
|
|
4c520e |
bool gp_boolean_is_true(const char *s);
|
|
|
4c520e |
char *gp_getenv(const char *name);
|
|
|
4c520e |
|
|
|
4c520e |
+/* NOTE: read the note in gp_util.c before using gp_strerror() */
|
|
|
4c520e |
+char *gp_strerror(int errnum);
|
|
|
4c520e |
+
|
|
|
4c520e |
#include "rpcgen/gss_proxy.h"
|
|
|
4c520e |
|
|
|
4c520e |
union gp_rpc_arg {
|
|
|
4c520e |
diff --git a/proxy/src/gp_util.c b/proxy/src/gp_util.c
|
|
|
4c520e |
index a6c870f..4fbac4e 100644
|
|
|
4c520e |
--- a/proxy/src/gp_util.c
|
|
|
4c520e |
+++ b/proxy/src/gp_util.c
|
|
|
4c520e |
@@ -27,6 +27,8 @@
|
|
|
4c520e |
#include <stdbool.h>
|
|
|
4c520e |
#include <string.h>
|
|
|
4c520e |
#include <stdlib.h>
|
|
|
4c520e |
+#include <stdio.h>
|
|
|
4c520e |
+#include <errno.h>
|
|
|
4c520e |
|
|
|
4c520e |
bool gp_same(const char *a, const char *b)
|
|
|
4c520e |
{
|
|
|
4c520e |
@@ -66,3 +68,60 @@ char *gp_getenv(const char *name)
|
|
|
4c520e |
return NULL;
|
|
|
4c520e |
#endif
|
|
|
4c520e |
}
|
|
|
4c520e |
+
|
|
|
4c520e |
+/* NOTE: because strerror_r() is such a mess with glibc, we need to do some
|
|
|
4c520e |
+ * magic checking to find out what function prototype is being used of the
|
|
|
4c520e |
+ * two incompatible ones, and pray it doesn't change in the future.
|
|
|
4c520e |
+ * On top of that to avoid impacting the current code too much we've got to use
|
|
|
4c520e |
+ * thread-local storage to hold a buffer.
|
|
|
4c520e |
+ * gp_strerror() is basically a thread-safe version of strerror() that can
|
|
|
4c520e |
+ * never fail.
|
|
|
4c520e |
+ */
|
|
|
4c520e |
+const char gp_internal_err[] = "Internal strerror_r() error.";
|
|
|
4c520e |
+#define MAX_GP_STRERROR 1024
|
|
|
4c520e |
+char *gp_strerror(int errnum)
|
|
|
4c520e |
+{
|
|
|
4c520e |
+ static __thread char buf[MAX_GP_STRERROR];
|
|
|
4c520e |
+ int saved_errno = errno;
|
|
|
4c520e |
+
|
|
|
4c520e |
+#if ((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE)
|
|
|
4c520e |
+ /* XSI version */
|
|
|
4c520e |
+ int ret;
|
|
|
4c520e |
+
|
|
|
4c520e |
+ ret = strerror_r(errnum, buf, MAX_GP_STRERROR);
|
|
|
4c520e |
+ if (ret == -1) ret = errno;
|
|
|
4c520e |
+ switch (ret) {
|
|
|
4c520e |
+ case 0:
|
|
|
4c520e |
+ break;
|
|
|
4c520e |
+ case EINVAL:
|
|
|
4c520e |
+ ret = snprintf(buf, MAX_GP_STRERROR,
|
|
|
4c520e |
+ "Unknown error code: %d", errnum);
|
|
|
4c520e |
+ if (ret > 0) break;
|
|
|
4c520e |
+ /* fallthrough */
|
|
|
4c520e |
+ default:
|
|
|
4c520e |
+ ret = snprintf(buf, MAX_GP_STRERROR,
|
|
|
4c520e |
+ "Internal error describing error code: %d", errnum);
|
|
|
4c520e |
+ if (ret > 0) break;
|
|
|
4c520e |
+ memset(buf, 0, MAX_GP_STRERROR);
|
|
|
4c520e |
+ strncpy(buf, gp_internal_err, MAX_GP_STRERROR);
|
|
|
4c520e |
+ buf[MAX_GP_STRERROR -1] = '\0';
|
|
|
4c520e |
+ }
|
|
|
4c520e |
+#else
|
|
|
4c520e |
+ /* GNU-specific version */
|
|
|
4c520e |
+ char *ret;
|
|
|
4c520e |
+
|
|
|
4c520e |
+ ret = strerror_r(errnum, buf, MAX_GP_STRERROR);
|
|
|
4c520e |
+ if (ret == NULL) {
|
|
|
4c520e |
+ memset(buf, 0, MAX_GP_STRERROR);
|
|
|
4c520e |
+ strncpy(buf, gp_internal_err, MAX_GP_STRERROR);
|
|
|
4c520e |
+ buf[MAX_GP_STRERROR -1] = '\0';
|
|
|
4c520e |
+ } else if (ret != buf) {
|
|
|
4c520e |
+ memset(buf, 0, MAX_GP_STRERROR);
|
|
|
4c520e |
+ strncpy(buf, ret, MAX_GP_STRERROR);
|
|
|
4c520e |
+ buf[MAX_GP_STRERROR -1] = '\0';
|
|
|
4c520e |
+ }
|
|
|
4c520e |
+#endif
|
|
|
4c520e |
+
|
|
|
4c520e |
+ errno = saved_errno;
|
|
|
4c520e |
+ return buf;
|
|
|
4c520e |
+}
|
|
|
4c520e |
--
|
|
|
4c520e |
1.8.3.1
|
|
|
4c520e |
|
|
|
4c520e |
|
|
|
4c520e |
From db8099da53167ca4ebf3b9f5ef0c702ddfe8b366 Mon Sep 17 00:00:00 2001
|
|
|
4c520e |
From: Simo Sorce <simo@redhat.com>
|
|
|
4c520e |
Date: Thu, 21 Nov 2013 12:14:36 -0500
|
|
|
4c520e |
Subject: [PATCH 2/2] Use gp_strerror() everywhere instead of strerror()
|
|
|
4c520e |
MIME-Version: 1.0
|
|
|
4c520e |
Content-Type: text/plain; charset=UTF-8
|
|
|
4c520e |
Content-Transfer-Encoding: 8bit
|
|
|
4c520e |
|
|
|
4c520e |
https://fedorahosted.org/gss-proxy/ticket/111
|
|
|
4c520e |
|
|
|
4c520e |
Reviewed-by: Günther Deschner <gdeschner@redhat.com>
|
|
|
4c520e |
---
|
|
|
4c520e |
proxy/src/client/gpm_init_sec_context.c | 4 ++--
|
|
|
4c520e |
proxy/src/gp_config.c | 2 +-
|
|
|
4c520e |
proxy/src/gp_config_dinglibs.c | 4 ++--
|
|
|
4c520e |
proxy/src/gp_init.c | 10 +++++-----
|
|
|
4c520e |
proxy/src/gp_socket.c | 14 +++++++-------
|
|
|
4c520e |
5 files changed, 17 insertions(+), 17 deletions(-)
|
|
|
4c520e |
|
|
|
4c520e |
diff --git a/proxy/src/client/gpm_init_sec_context.c b/proxy/src/client/gpm_init_sec_context.c
|
|
|
4c520e |
index f6dfe53..bd88055 100644
|
|
|
4c520e |
--- a/proxy/src/client/gpm_init_sec_context.c
|
|
|
4c520e |
+++ b/proxy/src/client/gpm_init_sec_context.c
|
|
|
4c520e |
@@ -90,7 +90,7 @@ OM_uint32 gpm_init_sec_context(OM_uint32 *minor_status,
|
|
|
4c520e |
/* execute proxy request */
|
|
|
4c520e |
ret = gpm_make_call(GSSX_INIT_SEC_CONTEXT, &uarg, &ures);
|
|
|
4c520e |
if (ret) {
|
|
|
4c520e |
- gpm_save_internal_status(ret, strerror(ret));
|
|
|
4c520e |
+ gpm_save_internal_status(ret, gp_strerror(ret));
|
|
|
4c520e |
goto done;
|
|
|
4c520e |
}
|
|
|
4c520e |
|
|
|
4c520e |
@@ -114,7 +114,7 @@ OM_uint32 gpm_init_sec_context(OM_uint32 *minor_status,
|
|
|
4c520e |
if (res->output_token) {
|
|
|
4c520e |
ret = gp_conv_gssx_to_buffer_alloc(res->output_token, &outbuf);
|
|
|
4c520e |
if (ret) {
|
|
|
4c520e |
- gpm_save_internal_status(ret, strerror(ret));
|
|
|
4c520e |
+ gpm_save_internal_status(ret, gp_strerror(ret));
|
|
|
4c520e |
goto done;
|
|
|
4c520e |
}
|
|
|
4c520e |
}
|
|
|
4c520e |
diff --git a/proxy/src/gp_config.c b/proxy/src/gp_config.c
|
|
|
4c520e |
index 63f264e..2fc4a6f 100644
|
|
|
4c520e |
--- a/proxy/src/gp_config.c
|
|
|
4c520e |
+++ b/proxy/src/gp_config.c
|
|
|
4c520e |
@@ -464,7 +464,7 @@ int load_config(struct gp_config *cfg)
|
|
|
4c520e |
|
|
|
4c520e |
done:
|
|
|
4c520e |
if (ret != 0) {
|
|
|
4c520e |
- GPERROR("Error reading configuration %d: %s", ret, strerror(ret));
|
|
|
4c520e |
+ GPERROR("Error reading configuration %d: %s", ret, gp_strerror(ret));
|
|
|
4c520e |
}
|
|
|
4c520e |
gp_config_close(ctx);
|
|
|
4c520e |
safefree(ctx);
|
|
|
4c520e |
diff --git a/proxy/src/gp_config_dinglibs.c b/proxy/src/gp_config_dinglibs.c
|
|
|
4c520e |
index 8716b91..515b951 100644
|
|
|
4c520e |
--- a/proxy/src/gp_config_dinglibs.c
|
|
|
4c520e |
+++ b/proxy/src/gp_config_dinglibs.c
|
|
|
4c520e |
@@ -238,7 +238,7 @@ int gp_dinglibs_init(const char *config_file,
|
|
|
4c520e |
&file_ctx);
|
|
|
4c520e |
if (ret) {
|
|
|
4c520e |
GPDEBUG("Failed to open config file: %d (%s)\n",
|
|
|
4c520e |
- ret, strerror(ret));
|
|
|
4c520e |
+ ret, gp_strerror(ret));
|
|
|
4c520e |
ini_config_destroy(ini_config);
|
|
|
4c520e |
return ret;
|
|
|
4c520e |
}
|
|
|
4c520e |
@@ -255,7 +255,7 @@ int gp_dinglibs_init(const char *config_file,
|
|
|
4c520e |
char **errors = NULL;
|
|
|
4c520e |
/* we had a parsing failure */
|
|
|
4c520e |
GPDEBUG("Failed to parse config file: %d (%s)\n",
|
|
|
4c520e |
- ret, strerror(ret));
|
|
|
4c520e |
+ ret, gp_strerror(ret));
|
|
|
4c520e |
if (ini_config_error_count(ini_config)) {
|
|
|
4c520e |
ini_config_get_errors(ini_config, &errors);
|
|
|
4c520e |
if (errors) {
|
|
|
4c520e |
diff --git a/proxy/src/gp_init.c b/proxy/src/gp_init.c
|
|
|
4c520e |
index 92c0a47..7e29c59 100644
|
|
|
4c520e |
--- a/proxy/src/gp_init.c
|
|
|
4c520e |
+++ b/proxy/src/gp_init.c
|
|
|
4c520e |
@@ -158,7 +158,7 @@ void init_proc_nfsd(struct gp_config *cfg)
|
|
|
4c520e |
ret = errno;
|
|
|
4c520e |
GPDEBUG("Failed to open %s: %d (%s)\n",
|
|
|
4c520e |
LINUX_PROC_USE_GSS_PROXY_FILE,
|
|
|
4c520e |
- ret, strerror(ret));
|
|
|
4c520e |
+ ret, gp_strerror(ret));
|
|
|
4c520e |
return;
|
|
|
4c520e |
}
|
|
|
4c520e |
|
|
|
4c520e |
@@ -167,7 +167,7 @@ void init_proc_nfsd(struct gp_config *cfg)
|
|
|
4c520e |
ret = errno;
|
|
|
4c520e |
GPDEBUG("Failed to write to %s: %d (%s)\n",
|
|
|
4c520e |
LINUX_PROC_USE_GSS_PROXY_FILE,
|
|
|
4c520e |
- ret, strerror(ret));
|
|
|
4c520e |
+ ret, gp_strerror(ret));
|
|
|
4c520e |
}
|
|
|
4c520e |
|
|
|
4c520e |
ret = close(fd);
|
|
|
4c520e |
@@ -175,7 +175,7 @@ void init_proc_nfsd(struct gp_config *cfg)
|
|
|
4c520e |
ret = errno;
|
|
|
4c520e |
GPDEBUG("Failed to close %s: %d (%s)\n",
|
|
|
4c520e |
LINUX_PROC_USE_GSS_PROXY_FILE,
|
|
|
4c520e |
- ret, strerror(ret));
|
|
|
4c520e |
+ ret, gp_strerror(ret));
|
|
|
4c520e |
}
|
|
|
4c520e |
}
|
|
|
4c520e |
|
|
|
4c520e |
@@ -191,7 +191,7 @@ void write_pid(void)
|
|
|
4c520e |
if (!f) {
|
|
|
4c520e |
ret = errno;
|
|
|
4c520e |
GPDEBUG("Failed to open %s: %d (%s)\n",
|
|
|
4c520e |
- GP_PID_FILE, ret, strerror(ret));
|
|
|
4c520e |
+ GP_PID_FILE, ret, gp_strerror(ret));
|
|
|
4c520e |
return;
|
|
|
4c520e |
}
|
|
|
4c520e |
|
|
|
4c520e |
@@ -204,6 +204,6 @@ void write_pid(void)
|
|
|
4c520e |
if (ret != 0) {
|
|
|
4c520e |
ret = errno;
|
|
|
4c520e |
GPDEBUG("Failed to close %s: %d (%s)\n",
|
|
|
4c520e |
- GP_PID_FILE, ret, strerror(ret));
|
|
|
4c520e |
+ GP_PID_FILE, ret, gp_strerror(ret));
|
|
|
4c520e |
}
|
|
|
4c520e |
}
|
|
|
4c520e |
diff --git a/proxy/src/gp_socket.c b/proxy/src/gp_socket.c
|
|
|
4c520e |
index b1851a2..3e8afc5 100644
|
|
|
4c520e |
--- a/proxy/src/gp_socket.c
|
|
|
4c520e |
+++ b/proxy/src/gp_socket.c
|
|
|
4c520e |
@@ -184,7 +184,7 @@ struct gp_sock_ctx *init_unix_socket(struct gssproxy_ctx *gpctx,
|
|
|
4c520e |
fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
|
|
4c520e |
if (fd == -1) {
|
|
|
4c520e |
ret = errno;
|
|
|
4c520e |
- GPDEBUG("Failed to init socket! (%d: %s)\n", ret, strerror(ret));
|
|
|
4c520e |
+ GPDEBUG("Failed to init socket! (%d: %s)\n", ret, gp_strerror(ret));
|
|
|
4c520e |
goto done;
|
|
|
4c520e |
}
|
|
|
4c520e |
|
|
|
4c520e |
@@ -192,14 +192,14 @@ struct gp_sock_ctx *init_unix_socket(struct gssproxy_ctx *gpctx,
|
|
|
4c520e |
if (ret == -1) {
|
|
|
4c520e |
ret = errno;
|
|
|
4c520e |
GPDEBUG("Failed to bind socket %s! (%d: %s)\n", addr.sun_path,
|
|
|
4c520e |
- ret, strerror(ret));
|
|
|
4c520e |
+ ret, gp_strerror(ret));
|
|
|
4c520e |
goto done;
|
|
|
4c520e |
}
|
|
|
4c520e |
|
|
|
4c520e |
ret = listen(fd, 10);
|
|
|
4c520e |
if (ret == -1) {
|
|
|
4c520e |
ret = errno;
|
|
|
4c520e |
- GPDEBUG("Failed to listen! (%d: %s)\n", ret, strerror(ret));
|
|
|
4c520e |
+ GPDEBUG("Failed to listen! (%d: %s)\n", ret, gp_strerror(ret));
|
|
|
4c520e |
goto done;
|
|
|
4c520e |
}
|
|
|
4c520e |
|
|
|
4c520e |
@@ -218,7 +218,7 @@ struct gp_sock_ctx *init_unix_socket(struct gssproxy_ctx *gpctx,
|
|
|
4c520e |
done:
|
|
|
4c520e |
if (ret) {
|
|
|
4c520e |
GPERROR("Failed to create Unix Socket! (%d:%s)",
|
|
|
4c520e |
- ret, strerror(ret));
|
|
|
4c520e |
+ ret, gp_strerror(ret));
|
|
|
4c520e |
if (fd != -1) {
|
|
|
4c520e |
close(fd);
|
|
|
4c520e |
fd = -1;
|
|
|
4c520e |
@@ -245,7 +245,7 @@ static int get_peercred(int fd, struct gp_conn *conn)
|
|
|
4c520e |
if (ret == -1) {
|
|
|
4c520e |
ret = errno;
|
|
|
4c520e |
GPDEBUG("Failed to get SO_PEERCRED options! (%d:%s)\n",
|
|
|
4c520e |
- ret, strerror(ret));
|
|
|
4c520e |
+ ret, gp_strerror(ret));
|
|
|
4c520e |
return ret;
|
|
|
4c520e |
}
|
|
|
4c520e |
if (len != sizeof(struct ucred)) {
|
|
|
4c520e |
@@ -262,7 +262,7 @@ static int get_peercred(int fd, struct gp_conn *conn)
|
|
|
4c520e |
} else {
|
|
|
4c520e |
ret = errno;
|
|
|
4c520e |
GPDEBUG("Failed to get peer's SELinux context (%d:%s)\n",
|
|
|
4c520e |
- ret, strerror(ret));
|
|
|
4c520e |
+ ret, gp_strerror(ret));
|
|
|
4c520e |
/* consider thisnot fatal, selinux may be disabled */
|
|
|
4c520e |
}
|
|
|
4c520e |
|
|
|
4c520e |
@@ -579,7 +579,7 @@ void accept_sock_conn(verto_ctx *vctx, verto_ev *ev)
|
|
|
4c520e |
done:
|
|
|
4c520e |
if (ret) {
|
|
|
4c520e |
GPERROR("Error connecting client: (%d:%s)",
|
|
|
4c520e |
- ret, strerror(ret));
|
|
|
4c520e |
+ ret, gp_strerror(ret));
|
|
|
4c520e |
gp_conn_free(conn);
|
|
|
4c520e |
}
|
|
|
4c520e |
}
|
|
|
4c520e |
--
|
|
|
4c520e |
1.8.3.1
|
|
|
4c520e |
|