|
|
1f3cc3 |
From 01ff7b67bfaad9b4f6cebc7c46ac9b1d99671d4f Mon Sep 17 00:00:00 2001
|
|
|
1f3cc3 |
From: Simo Sorce <simo@redhat.com>
|
|
|
1f3cc3 |
Date: Wed, 6 Mar 2019 10:31:13 -0500
|
|
|
1f3cc3 |
Subject: [PATCH] Close epoll fd within the lock
|
|
|
1f3cc3 |
|
|
|
1f3cc3 |
A race condition may happen where we close the epoll socket, after
|
|
|
1f3cc3 |
another thread grabbed the lock and is using epoll itself.
|
|
|
1f3cc3 |
On some kernels this may cause epoll to not fire any event leaving the
|
|
|
1f3cc3 |
thread stuck forever.
|
|
|
1f3cc3 |
|
|
|
1f3cc3 |
Signed-off-by: Simo Sorce <simo@redhat.com>
|
|
|
1f3cc3 |
[rharwood@redhat.com: cleanup commit message, adjusted function ordering]
|
|
|
1f3cc3 |
Reviewed-by: Robbie Harwood <rharwood@redhat.com>
|
|
|
1f3cc3 |
Merges: #241
|
|
|
1f3cc3 |
(cherry picked from commit 0ccfd32f8ef16caf65698c5319dfa251d43433af)
|
|
|
1f3cc3 |
|
|
|
1f3cc3 |
Squashed with:
|
|
|
1f3cc3 |
|
|
|
1f3cc3 |
Reorder functions
|
|
|
1f3cc3 |
|
|
|
1f3cc3 |
Keep related functions closer together like before
|
|
|
1f3cc3 |
|
|
|
1f3cc3 |
Signed-off-by: Simo Sorce <simo@redhat.com>
|
|
|
1f3cc3 |
Reviewed-by: Robbie Harwood <rharwood@redhat.com>
|
|
|
1f3cc3 |
Resolves: #242
|
|
|
1f3cc3 |
(cherry picked from commit 6accc0afead574e11447447c949f2abcb1a34826)
|
|
|
1f3cc3 |
(cherry picked from commit c33de0c213d570f370fd954869c2ad99901b2cf3)
|
|
|
1f3cc3 |
---
|
|
|
1f3cc3 |
src/client/gpm_common.c | 96 ++++++++++++++++++++++-------------------
|
|
|
1f3cc3 |
1 file changed, 51 insertions(+), 45 deletions(-)
|
|
|
1f3cc3 |
|
|
|
1f3cc3 |
diff --git a/src/client/gpm_common.c b/src/client/gpm_common.c
|
|
|
1f3cc3 |
index c254280..36df5cc 100644
|
|
|
1f3cc3 |
--- a/src/client/gpm_common.c
|
|
|
1f3cc3 |
+++ b/src/client/gpm_common.c
|
|
|
1f3cc3 |
@@ -139,43 +139,6 @@ static void gpm_close_socket(struct gpm_ctx *gpmctx)
|
|
|
1f3cc3 |
gpmctx->fd = -1;
|
|
|
1f3cc3 |
}
|
|
|
1f3cc3 |
|
|
|
1f3cc3 |
-static int gpm_grab_sock(struct gpm_ctx *gpmctx)
|
|
|
1f3cc3 |
-{
|
|
|
1f3cc3 |
- int ret;
|
|
|
1f3cc3 |
- pid_t p;
|
|
|
1f3cc3 |
- uid_t u;
|
|
|
1f3cc3 |
- gid_t g;
|
|
|
1f3cc3 |
-
|
|
|
1f3cc3 |
- ret = pthread_mutex_lock(&gpmctx->lock);
|
|
|
1f3cc3 |
- if (ret) {
|
|
|
1f3cc3 |
- return ret;
|
|
|
1f3cc3 |
- }
|
|
|
1f3cc3 |
-
|
|
|
1f3cc3 |
- /* Detect fork / setresuid and friends */
|
|
|
1f3cc3 |
- p = getpid();
|
|
|
1f3cc3 |
- u = geteuid();
|
|
|
1f3cc3 |
- g = getegid();
|
|
|
1f3cc3 |
-
|
|
|
1f3cc3 |
- if (gpmctx->fd != -1 &&
|
|
|
1f3cc3 |
- (p != gpmctx->pid || u != gpmctx->uid || g != gpmctx->gid)) {
|
|
|
1f3cc3 |
- gpm_close_socket(gpmctx);
|
|
|
1f3cc3 |
- }
|
|
|
1f3cc3 |
-
|
|
|
1f3cc3 |
- if (gpmctx->fd == -1) {
|
|
|
1f3cc3 |
- ret = gpm_open_socket(gpmctx);
|
|
|
1f3cc3 |
- }
|
|
|
1f3cc3 |
-
|
|
|
1f3cc3 |
- if (ret) {
|
|
|
1f3cc3 |
- pthread_mutex_unlock(&gpmctx->lock);
|
|
|
1f3cc3 |
- }
|
|
|
1f3cc3 |
- return ret;
|
|
|
1f3cc3 |
-}
|
|
|
1f3cc3 |
-
|
|
|
1f3cc3 |
-static int gpm_release_sock(struct gpm_ctx *gpmctx)
|
|
|
1f3cc3 |
-{
|
|
|
1f3cc3 |
- return pthread_mutex_unlock(&gpmctx->lock);
|
|
|
1f3cc3 |
-}
|
|
|
1f3cc3 |
-
|
|
|
1f3cc3 |
static void gpm_timer_close(struct gpm_ctx *gpmctx)
|
|
|
1f3cc3 |
{
|
|
|
1f3cc3 |
if (gpmctx->timerfd < 0) {
|
|
|
1f3cc3 |
@@ -253,6 +216,57 @@ static int gpm_epoll_setup(struct gpm_ctx *gpmctx)
|
|
|
1f3cc3 |
return ret;
|
|
|
1f3cc3 |
}
|
|
|
1f3cc3 |
|
|
|
1f3cc3 |
+static int gpm_release_sock(struct gpm_ctx *gpmctx)
|
|
|
1f3cc3 |
+{
|
|
|
1f3cc3 |
+ gpm_epoll_close(gpmctx);
|
|
|
1f3cc3 |
+ gpm_timer_close(gpmctx);
|
|
|
1f3cc3 |
+ return pthread_mutex_unlock(&gpmctx->lock);
|
|
|
1f3cc3 |
+}
|
|
|
1f3cc3 |
+
|
|
|
1f3cc3 |
+static int gpm_grab_sock(struct gpm_ctx *gpmctx)
|
|
|
1f3cc3 |
+{
|
|
|
1f3cc3 |
+ int ret;
|
|
|
1f3cc3 |
+ pid_t p;
|
|
|
1f3cc3 |
+ uid_t u;
|
|
|
1f3cc3 |
+ gid_t g;
|
|
|
1f3cc3 |
+
|
|
|
1f3cc3 |
+ ret = pthread_mutex_lock(&gpmctx->lock);
|
|
|
1f3cc3 |
+ if (ret) {
|
|
|
1f3cc3 |
+ return ret;
|
|
|
1f3cc3 |
+ }
|
|
|
1f3cc3 |
+
|
|
|
1f3cc3 |
+ /* Detect fork / setresuid and friends */
|
|
|
1f3cc3 |
+ p = getpid();
|
|
|
1f3cc3 |
+ u = geteuid();
|
|
|
1f3cc3 |
+ g = getegid();
|
|
|
1f3cc3 |
+
|
|
|
1f3cc3 |
+ if (gpmctx->fd != -1 &&
|
|
|
1f3cc3 |
+ (p != gpmctx->pid || u != gpmctx->uid || g != gpmctx->gid)) {
|
|
|
1f3cc3 |
+ gpm_close_socket(gpmctx);
|
|
|
1f3cc3 |
+ }
|
|
|
1f3cc3 |
+
|
|
|
1f3cc3 |
+ if (gpmctx->fd == -1) {
|
|
|
1f3cc3 |
+ ret = gpm_open_socket(gpmctx);
|
|
|
1f3cc3 |
+ if (ret) {
|
|
|
1f3cc3 |
+ goto done;
|
|
|
1f3cc3 |
+ }
|
|
|
1f3cc3 |
+ }
|
|
|
1f3cc3 |
+
|
|
|
1f3cc3 |
+ /* setup timer */
|
|
|
1f3cc3 |
+ ret = gpm_timer_setup(gpmctx, RESPONSE_TIMEOUT);
|
|
|
1f3cc3 |
+ if (ret) {
|
|
|
1f3cc3 |
+ goto done;
|
|
|
1f3cc3 |
+ }
|
|
|
1f3cc3 |
+ /* create epoll fd as well */
|
|
|
1f3cc3 |
+ ret = gpm_epoll_setup(gpmctx);
|
|
|
1f3cc3 |
+
|
|
|
1f3cc3 |
+done:
|
|
|
1f3cc3 |
+ if (ret) {
|
|
|
1f3cc3 |
+ gpm_release_sock(gpmctx);
|
|
|
1f3cc3 |
+ }
|
|
|
1f3cc3 |
+ return ret;
|
|
|
1f3cc3 |
+}
|
|
|
1f3cc3 |
+
|
|
|
1f3cc3 |
static int gpm_epoll_wait(struct gpm_ctx *gpmctx, uint32_t event_flags)
|
|
|
1f3cc3 |
{
|
|
|
1f3cc3 |
int ret;
|
|
|
1f3cc3 |
@@ -530,11 +544,6 @@ static int gpm_send_recv_loop(struct gpm_ctx *gpmctx, char *send_buffer,
|
|
|
1f3cc3 |
int ret;
|
|
|
1f3cc3 |
int retry_count;
|
|
|
1f3cc3 |
|
|
|
1f3cc3 |
- /* setup timer */
|
|
|
1f3cc3 |
- ret = gpm_timer_setup(gpmctx, RESPONSE_TIMEOUT);
|
|
|
1f3cc3 |
- if (ret)
|
|
|
1f3cc3 |
- return ret;
|
|
|
1f3cc3 |
-
|
|
|
1f3cc3 |
for (retry_count = 0; retry_count < MAX_TIMEOUT_RETRY; retry_count++) {
|
|
|
1f3cc3 |
/* send to proxy */
|
|
|
1f3cc3 |
ret = gpm_send_buffer(gpmctx, send_buffer, send_length);
|
|
|
1f3cc3 |
@@ -761,9 +770,6 @@ int gpm_make_call(int proc, union gp_rpc_arg *arg, union gp_rpc_res *res)
|
|
|
1f3cc3 |
}
|
|
|
1f3cc3 |
|
|
|
1f3cc3 |
done:
|
|
|
1f3cc3 |
- gpm_timer_close(gpmctx);
|
|
|
1f3cc3 |
- gpm_epoll_close(gpmctx);
|
|
|
1f3cc3 |
-
|
|
|
1f3cc3 |
if (sockgrab) {
|
|
|
1f3cc3 |
gpm_release_sock(gpmctx);
|
|
|
1f3cc3 |
}
|