- fix incorrect pthreads condition handling for expire requests. - fix master map lexer eval order. - fix bad alloca usage.
180 lines
4.8 KiB
Diff
180 lines
4.8 KiB
Diff
autofs-5.0.3 - fix incorrect pthreads condition handling for expire requests.
|
|
|
|
From: Ian Kent <raven@themaw.net>
|
|
|
|
Occassionally, when starting an expire thread we can attempt to use the
|
|
structure for parameter communication after it has been freed. This patch
|
|
resolves this issue.
|
|
---
|
|
|
|
daemon/direct.c | 40 +++++++++++++++++++++-------------------
|
|
daemon/indirect.c | 28 +++++++++++++++-------------
|
|
2 files changed, 36 insertions(+), 32 deletions(-)
|
|
|
|
|
|
--- autofs-5.0.3.orig/daemon/direct.c
|
|
+++ autofs-5.0.3/daemon/direct.c
|
|
@@ -1033,55 +1033,53 @@ static void expire_mutex_unlock(void *ar
|
|
|
|
static void *do_expire_direct(void *arg)
|
|
{
|
|
- struct pending_args *mt;
|
|
+ struct pending_args *args, mt;
|
|
struct autofs_point *ap;
|
|
size_t len;
|
|
int status, state;
|
|
|
|
- mt = (struct pending_args *) arg;
|
|
+ args = (struct pending_args *) arg;
|
|
|
|
status = pthread_mutex_lock(&ea_mutex);
|
|
if (status)
|
|
fatal(status);
|
|
|
|
- ap = mt->ap;
|
|
+ memcpy(&mt, args, sizeof(struct pending_args));
|
|
+
|
|
+ ap = mt.ap;
|
|
|
|
- mt->signaled = 1;
|
|
- status = pthread_cond_signal(&mt->cond);
|
|
+ args->signaled = 1;
|
|
+ status = pthread_cond_signal(&args->cond);
|
|
if (status)
|
|
fatal(status);
|
|
|
|
expire_mutex_unlock(NULL);
|
|
|
|
- pthread_cleanup_push(free_pending_args, mt);
|
|
- pthread_cleanup_push(pending_cond_destroy, mt);
|
|
- pthread_cleanup_push(expire_send_fail, mt);
|
|
+ pthread_cleanup_push(expire_send_fail, &mt);
|
|
|
|
- len = _strlen(mt->name, KEY_MAX_LEN);
|
|
+ len = _strlen(mt.name, KEY_MAX_LEN);
|
|
if (!len) {
|
|
- warn(ap->logopt, "direct key path too long %s", mt->name);
|
|
+ warn(ap->logopt, "direct key path too long %s", mt.name);
|
|
/* TODO: force umount ?? */
|
|
pthread_exit(NULL);
|
|
}
|
|
|
|
- status = do_expire(ap, mt->name, len);
|
|
+ status = do_expire(ap, mt.name, len);
|
|
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
|
|
if (status)
|
|
- send_fail(ap->logopt, mt->ioctlfd, mt->wait_queue_token);
|
|
+ send_fail(ap->logopt, mt.ioctlfd, mt.wait_queue_token);
|
|
else {
|
|
struct mapent *me;
|
|
- cache_readlock(mt->mc);
|
|
- me = cache_lookup_distinct(mt->mc, mt->name);
|
|
+ cache_readlock(mt.mc);
|
|
+ me = cache_lookup_distinct(mt.mc, mt.name);
|
|
me->ioctlfd = -1;
|
|
- cache_unlock(mt->mc);
|
|
- send_ready(ap->logopt, mt->ioctlfd, mt->wait_queue_token);
|
|
- close(mt->ioctlfd);
|
|
+ cache_unlock(mt.mc);
|
|
+ send_ready(ap->logopt, mt.ioctlfd, mt.wait_queue_token);
|
|
+ close(mt.ioctlfd);
|
|
}
|
|
pthread_setcancelstate(state, NULL);
|
|
|
|
pthread_cleanup_pop(0);
|
|
- pthread_cleanup_pop(1);
|
|
- pthread_cleanup_pop(1);
|
|
|
|
return NULL;
|
|
}
|
|
@@ -1198,6 +1196,8 @@ int handle_packet_expire_direct(struct a
|
|
cache_unlock(mc);
|
|
master_source_unlock(ap->entry);
|
|
|
|
+ pthread_cleanup_push(free_pending_args, mt);
|
|
+ pthread_cleanup_push(pending_cond_destroy, mt);
|
|
pthread_cleanup_push(expire_mutex_unlock, NULL);
|
|
pthread_setcancelstate(state, NULL);
|
|
|
|
@@ -1212,6 +1212,8 @@ int handle_packet_expire_direct(struct a
|
|
}
|
|
|
|
pthread_cleanup_pop(1);
|
|
+ pthread_cleanup_pop(1);
|
|
+ pthread_cleanup_pop(1);
|
|
|
|
return 0;
|
|
}
|
|
--- autofs-5.0.3.orig/daemon/indirect.c
|
|
+++ autofs-5.0.3/daemon/indirect.c
|
|
@@ -596,40 +596,38 @@ static void expire_mutex_unlock(void *ar
|
|
|
|
static void *do_expire_indirect(void *arg)
|
|
{
|
|
- struct pending_args *mt;
|
|
+ struct pending_args *args, mt;
|
|
struct autofs_point *ap;
|
|
int status, state;
|
|
|
|
- mt = (struct pending_args *) arg;
|
|
+ args = (struct pending_args *) arg;
|
|
|
|
status = pthread_mutex_lock(&ea_mutex);
|
|
if (status)
|
|
fatal(status);
|
|
|
|
- ap = mt->ap;
|
|
+ memcpy(&mt, args, sizeof(struct pending_args));
|
|
|
|
- mt->signaled = 1;
|
|
- status = pthread_cond_signal(&mt->cond);
|
|
+ ap = mt.ap;
|
|
+
|
|
+ args->signaled = 1;
|
|
+ status = pthread_cond_signal(&args->cond);
|
|
if (status)
|
|
fatal(status);
|
|
|
|
expire_mutex_unlock(NULL);
|
|
|
|
- pthread_cleanup_push(free_pending_args, mt);
|
|
- pthread_cleanup_push(pending_cond_destroy, mt);
|
|
- pthread_cleanup_push(expire_send_fail, mt);
|
|
+ pthread_cleanup_push(expire_send_fail, &mt);
|
|
|
|
- status = do_expire(mt->ap, mt->name, mt->len);
|
|
+ status = do_expire(mt.ap, mt.name, mt.len);
|
|
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
|
|
if (status)
|
|
- send_fail(ap->logopt, ap->ioctlfd, mt->wait_queue_token);
|
|
+ send_fail(ap->logopt, ap->ioctlfd, mt.wait_queue_token);
|
|
else
|
|
- send_ready(ap->logopt, ap->ioctlfd, mt->wait_queue_token);
|
|
+ send_ready(ap->logopt, ap->ioctlfd, mt.wait_queue_token);
|
|
pthread_setcancelstate(state, NULL);
|
|
|
|
pthread_cleanup_pop(0);
|
|
- pthread_cleanup_pop(1);
|
|
- pthread_cleanup_pop(1);
|
|
|
|
return NULL;
|
|
}
|
|
@@ -682,6 +680,8 @@ int handle_packet_expire_indirect(struct
|
|
return 1;
|
|
}
|
|
|
|
+ pthread_cleanup_push(free_pending_args, mt);
|
|
+ pthread_cleanup_push(pending_cond_destroy, mt);
|
|
pthread_cleanup_push(expire_mutex_unlock, NULL);
|
|
pthread_setcancelstate(state, NULL);
|
|
|
|
@@ -696,6 +696,8 @@ int handle_packet_expire_indirect(struct
|
|
}
|
|
|
|
pthread_cleanup_pop(1);
|
|
+ pthread_cleanup_pop(1);
|
|
+ pthread_cleanup_pop(1);
|
|
|
|
return 0;
|
|
}
|