120 lines
3.6 KiB
Diff
120 lines
3.6 KiB
Diff
From 57440adcd67be82720771999384420d00a7f94ea Mon Sep 17 00:00:00 2001
|
|
From: Jaime Caamano Ruiz <jcaamano@suse.com>
|
|
Date: Thu, 25 Jun 2020 11:27:58 -0400
|
|
Subject: [PATCH] Fix memory management issues of fd locks
|
|
|
|
Fix the use of an fd_lock referenced from private client data after it
|
|
was freed.
|
|
|
|
Signed-off-by: Steve Dickson <steved@redhat.com>
|
|
---
|
|
src/clnt_dg.c | 9 +++++----
|
|
src/clnt_fd_locks.h | 4 +++-
|
|
src/clnt_vc.c | 14 ++++++--------
|
|
3 files changed, 14 insertions(+), 13 deletions(-)
|
|
|
|
diff --git a/src/clnt_dg.c b/src/clnt_dg.c
|
|
index df402ec..abc09f1 100644
|
|
--- a/src/clnt_dg.c
|
|
+++ b/src/clnt_dg.c
|
|
@@ -725,14 +725,15 @@ clnt_dg_destroy(cl)
|
|
{
|
|
struct cu_data *cu = (struct cu_data *)cl->cl_private;
|
|
int cu_fd = cu->cu_fd;
|
|
+ fd_lock_t *cu_fd_lock = cu->cu_fd_lock;
|
|
sigset_t mask;
|
|
sigset_t newmask;
|
|
|
|
sigfillset(&newmask);
|
|
thr_sigsetmask(SIG_SETMASK, &newmask, &mask);
|
|
mutex_lock(&clnt_fd_lock);
|
|
- while (cu->cu_fd_lock->active)
|
|
- cond_wait(&cu->cu_fd_lock->cv, &clnt_fd_lock);
|
|
+ while (cu_fd_lock->active)
|
|
+ cond_wait(&cu_fd_lock->cv, &clnt_fd_lock);
|
|
if (cu->cu_closeit)
|
|
(void)close(cu_fd);
|
|
XDR_DESTROY(&(cu->cu_outxdrs));
|
|
@@ -742,8 +743,8 @@ clnt_dg_destroy(cl)
|
|
if (cl->cl_tp && cl->cl_tp[0])
|
|
mem_free(cl->cl_tp, strlen(cl->cl_tp) +1);
|
|
mem_free(cl, sizeof (CLIENT));
|
|
- cond_signal(&cu->cu_fd_lock->cv);
|
|
- fd_lock_destroy(cu_fd, cu->cu_fd_lock, dg_fd_locks);
|
|
+ cond_signal(&cu_fd_lock->cv);
|
|
+ fd_lock_destroy(cu_fd, cu_fd_lock, dg_fd_locks);
|
|
mutex_unlock(&clnt_fd_lock);
|
|
thr_sigsetmask(SIG_SETMASK, &mask, NULL);
|
|
}
|
|
diff --git a/src/clnt_fd_locks.h b/src/clnt_fd_locks.h
|
|
index 8263071..359f995 100644
|
|
--- a/src/clnt_fd_locks.h
|
|
+++ b/src/clnt_fd_locks.h
|
|
@@ -114,6 +114,7 @@ fd_locks_t* fd_locks_init() {
|
|
}
|
|
|
|
if ( (size_t) fd_locks_prealloc > SIZE_MAX/sizeof(fd_lock_t)) {
|
|
+ mem_free(fd_locks, sizeof (*fd_locks));
|
|
errno = EOVERFLOW;
|
|
return (NULL);
|
|
}
|
|
@@ -121,6 +122,7 @@ fd_locks_t* fd_locks_init() {
|
|
fd_lock_arraysz = fd_locks_prealloc * sizeof (fd_lock_t);
|
|
fd_locks->fd_lock_array = (fd_lock_t *) mem_alloc(fd_lock_arraysz);
|
|
if (fd_locks->fd_lock_array == (fd_lock_t *) NULL) {
|
|
+ mem_free(fd_locks, sizeof (*fd_locks));
|
|
errno = ENOMEM;
|
|
return (NULL);
|
|
}
|
|
@@ -162,7 +164,7 @@ fd_lock_t* fd_lock_create(int fd, fd_locks_t *fd_locks) {
|
|
return &fd_locks->fd_lock_array[fd];
|
|
}
|
|
#endif
|
|
- fd_lock_item_t* item;
|
|
+ fd_lock_item_t *item;
|
|
fd_lock_list_t *list = to_fd_lock_list(fd_locks);
|
|
|
|
for (item = TAILQ_FIRST(list);
|
|
diff --git a/src/clnt_vc.c b/src/clnt_vc.c
|
|
index 2f3dde6..6f7f7da 100644
|
|
--- a/src/clnt_vc.c
|
|
+++ b/src/clnt_vc.c
|
|
@@ -632,20 +632,18 @@ static void
|
|
clnt_vc_destroy(cl)
|
|
CLIENT *cl;
|
|
{
|
|
+ assert(cl != NULL);
|
|
struct ct_data *ct = (struct ct_data *) cl->cl_private;
|
|
int ct_fd = ct->ct_fd;
|
|
+ fd_lock_t *ct_fd_lock = ct->ct_fd_lock;
|
|
sigset_t mask;
|
|
sigset_t newmask;
|
|
|
|
- assert(cl != NULL);
|
|
-
|
|
- ct = (struct ct_data *) cl->cl_private;
|
|
-
|
|
sigfillset(&newmask);
|
|
thr_sigsetmask(SIG_SETMASK, &newmask, &mask);
|
|
mutex_lock(&clnt_fd_lock);
|
|
- while (ct->ct_fd_lock->active)
|
|
- cond_wait(&ct->ct_fd_lock->cv, &clnt_fd_lock);
|
|
+ while (ct_fd_lock->active)
|
|
+ cond_wait(&ct_fd_lock->cv, &clnt_fd_lock);
|
|
if (ct->ct_closeit && ct->ct_fd != -1) {
|
|
(void)close(ct->ct_fd);
|
|
}
|
|
@@ -658,8 +656,8 @@ clnt_vc_destroy(cl)
|
|
if (cl->cl_tp && cl->cl_tp[0])
|
|
mem_free(cl->cl_tp, strlen(cl->cl_tp) +1);
|
|
mem_free(cl, sizeof(CLIENT));
|
|
- cond_signal(&ct->ct_fd_lock->cv);
|
|
- fd_lock_destroy(ct_fd, ct->ct_fd_lock, vc_fd_locks);
|
|
+ cond_signal(&ct_fd_lock->cv);
|
|
+ fd_lock_destroy(ct_fd, ct_fd_lock, vc_fd_locks);
|
|
mutex_unlock(&clnt_fd_lock);
|
|
thr_sigsetmask(SIG_SETMASK, &(mask), NULL);
|
|
}
|
|
--
|
|
1.8.3.1
|