summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaime Caamano Ruiz <jcaamano@suse.com>2020-06-25 11:27:58 -0400
committerSteve Dickson <steved@redhat.com>2020-06-25 11:27:58 -0400
commit57440adcd67be82720771999384420d00a7f94ea (patch)
treec3970b4d5e4b26e8f60fe19c4a82d6f78aefe70a
parente7c34df8f57331063b9d795812c62cec3ddfbc17 (diff)
downloadti-rpc-57440adcd67be82720771999384420d00a7f94ea.tar.gz
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>
-rw-r--r--src/clnt_dg.c9
-rw-r--r--src/clnt_fd_locks.h4
-rw-r--r--src/clnt_vc.c14
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);
}