diff --git a/autofs-5.0.3-expire-thread-create-cond-handling.patch b/autofs-5.0.3-expire-thread-create-cond-handling.patch new file mode 100644 index 0000000..2f01d56 --- /dev/null +++ b/autofs-5.0.3-expire-thread-create-cond-handling.patch @@ -0,0 +1,179 @@ +autofs-5.0.3 - fix incorrect pthreads condition handling for expire requests. + +From: Ian Kent + +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; + } diff --git a/autofs-5.0.3-fix-bad-alloca-usage.patch b/autofs-5.0.3-fix-bad-alloca-usage.patch new file mode 100644 index 0000000..df664e7 --- /dev/null +++ b/autofs-5.0.3-fix-bad-alloca-usage.patch @@ -0,0 +1,63 @@ +autofs-5.0.3 - fix bad alloca usage + +From: Ian Kent + +In the lookup_ghost() function alloca is used within a loop which can +lead to stack overflow. +--- + + CHANGELOG | 1 + + daemon/lookup.c | 6 +++++- + 2 files changed, 6 insertions(+), 1 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 879380e..07feb29 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -48,6 +48,7 @@ + - fix $mandir definition in Makefile.conf.in + - fix init script stop function. + - fix master map lexer eval order. ++- fix bad alloca usage. + + 14/01/2008 autofs-5.0.3 + ----------------------- +diff --git a/daemon/lookup.c b/daemon/lookup.c +index 2233ac8..49030e1 100644 +--- a/daemon/lookup.c ++++ b/daemon/lookup.c +@@ -608,7 +608,7 @@ int lookup_ghost(struct autofs_point *ap, const char *root) + goto next; + } + +- fullpath = alloca(strlen(me->key) + strlen(root) + 3); ++ fullpath = malloc(strlen(me->key) + strlen(root) + 3); + if (!fullpath) { + warn(ap->logopt, "failed to allocate full path"); + goto next; +@@ -619,6 +619,7 @@ int lookup_ghost(struct autofs_point *ap, const char *root) + if (ret == -1 && errno != ENOENT) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + warn(ap->logopt, "stat error %s", estr); ++ free(fullpath); + goto next; + } + +@@ -627,6 +628,7 @@ int lookup_ghost(struct autofs_point *ap, const char *root) + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + warn(ap->logopt, + "mkdir_path %s failed: %s", fullpath, estr); ++ free(fullpath); + goto next; + } + +@@ -634,6 +636,8 @@ int lookup_ghost(struct autofs_point *ap, const char *root) + me->dev = st.st_dev; + me->ino = st.st_ino; + } ++ ++ free(fullpath); + next: + me = cache_enumerate(mc, me); + } diff --git a/autofs-5.0.3-fix-master-map-lexer-eval-order.patch b/autofs-5.0.3-fix-master-map-lexer-eval-order.patch new file mode 100644 index 0000000..3db38e3 --- /dev/null +++ b/autofs-5.0.3-fix-master-map-lexer-eval-order.patch @@ -0,0 +1,48 @@ +autofs-5.0.3 - fix master map lexer eval order + +From: Ian Kent + +Two compound regular expressions in the master map lexical +analyser lack brackets which leads to an evaluation order +error in some versions of flex. +--- + + CHANGELOG | 1 + + lib/master_tok.l | 4 ++-- + 2 files changed, 3 insertions(+), 2 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 8cdaab2..879380e 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -47,6 +47,7 @@ + - fix incorrect pthreads condition handling for expire requests. + - fix $mandir definition in Makefile.conf.in + - fix init script stop function. ++- fix master map lexer eval order. + + 14/01/2008 autofs-5.0.3 + ----------------------- +diff --git a/lib/master_tok.l b/lib/master_tok.l +index d2c86bc..801aa6f 100644 +--- a/lib/master_tok.l ++++ b/lib/master_tok.l +@@ -99,7 +99,7 @@ DNSERVSTR1 ([[:alpha:]][[:alnum:]\-.]*(:[0-9]+)?:) + DNSERVSTR2 (\/\/[[:alpha:]][[:alnum:]\-.]*(:[0-9]+)?\/) + DNSERVSTR3 (([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}(:[0-9]+)?:) + DNSERVSTR4 (\/\/([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}(:[0-9]+)?\/) +-DNSERVERSTR {DNSERVSTR1}|{DNSERVSTR2}|{DNSERVSTR3}|{DNSERVSTR4} ++DNSERVERSTR ({DNSERVSTR1}|{DNSERVSTR2}|{DNSERVSTR3}|{DNSERVSTR4}) + + AT_CN ([cC][[nN]) + AT_NMN ([nN][iI][sS][Mm][aA][pP][Nn][aA][mM][eE]) +@@ -108,7 +108,7 @@ AT_OU ([oO][[uU]) + AT_DC ([dD][[cC]) + AT_O ([oO]) + AT_C ([cC]) +-DNATTRSTR {AT_CN}|{AT_NMN}|{AT_AMN}|{AT_OU}|{AT_DC}|{AT_O}|{AT_C} ++DNATTRSTR ({AT_CN}|{AT_NMN}|{AT_AMN}|{AT_OU}|{AT_DC}|{AT_O}|{AT_C}) + DNNAMESTR1 ([[:alnum:]_.\- ]+) + DNNAMESTR2 ([[:alnum:]_.\-]+) + diff --git a/autofs-5.0.3-library-reload-fix.patch b/autofs-5.0.3-library-reload-fix.patch new file mode 100644 index 0000000..01cc782 --- /dev/null +++ b/autofs-5.0.3-library-reload-fix.patch @@ -0,0 +1,164 @@ +autofs-5.0.3 - library reload fix + +From: Ian Kent + +During a map re-read autofs needs to re-open its lookup libraries but +dependent shared libraries can't handle being unloaded and then re-loaded +by the same process. This patch preventis dependent libraries from being +unloaded during this re-open. +--- + + daemon/automount.c | 1 - + daemon/lookup.c | 21 +++++++++------------ + daemon/state.c | 3 +++ + include/master.h | 17 +++-------------- + lib/master.c | 28 ++++++++++++++++++++++------ + 5 files changed, 37 insertions(+), 33 deletions(-) + + +--- autofs-5.0.3.orig/daemon/automount.c ++++ autofs-5.0.3/daemon/automount.c +@@ -85,7 +85,6 @@ int aquire_flag_file(void); + void release_flag_file(void); + static int umount_all(struct autofs_point *ap, int force); + +-extern pthread_mutex_t master_mutex; + extern struct master *master_list; + + static int do_mkdir(const char *parent, const char *path, mode_t mode) +--- autofs-5.0.3.orig/daemon/lookup.c ++++ autofs-5.0.3/daemon/lookup.c +@@ -267,17 +267,17 @@ static int do_read_map(struct autofs_poi + struct lookup_mod *lookup; + int status; + +- if (!map->lookup) { +- lookup = open_lookup(map->type, "", +- map->format, map->argc, map->argv); +- if (!lookup) { +- debug(ap->logopt, "lookup module %s failed", map->type); +- return NSS_STATUS_UNAVAIL; +- } +- map->lookup = lookup; ++ lookup = open_lookup(map->type, "", map->format, map->argc, map->argv); ++ if (!lookup) { ++ debug(ap->logopt, "lookup module %s failed", map->type); ++ return NSS_STATUS_UNAVAIL; + } + +- lookup = map->lookup; ++ master_source_writelock(ap->entry); ++ if (map->lookup) ++ close_lookup(map->lookup); ++ map->lookup = lookup; ++ master_source_unlock(ap->entry); + + /* If we don't need to create directories then there's no use + * reading the map. We just need to test that the map is valid +@@ -463,8 +463,6 @@ int lookup_nss_read_map(struct autofs_po + * point in the master map) do the nss lookup to + * locate the map and read it. + */ +- pthread_cleanup_push(master_source_lock_cleanup, entry); +- master_source_readlock(entry); + if (source) + map = source; + else +@@ -557,7 +555,6 @@ int lookup_nss_read_map(struct autofs_po + + map = map->next; + } +- pthread_cleanup_pop(1); + + if (!result || at_least_one) + return 1; +--- autofs-5.0.3.orig/daemon/state.c ++++ autofs-5.0.3/daemon/state.c +@@ -387,9 +387,12 @@ static void *do_readmap(void *arg) + + info(ap->logopt, "re-reading map for %s", ap->path); + ++ pthread_cleanup_push(master_mutex_lock_cleanup, NULL); ++ master_mutex_lock(); + status = lookup_nss_read_map(ap, NULL, now); + if (!status) + pthread_exit(NULL); ++ pthread_cleanup_pop(1); + + if (ap->type == LKP_INDIRECT) { + lookup_prune_cache(ap, now); +--- autofs-5.0.3.orig/include/master.h ++++ autofs-5.0.3/include/master.h +@@ -70,6 +70,9 @@ int master_parse_entry(const char *, uns + + /* From master.c master parser utility routines */ + ++void master_mutex_lock(void); ++void master_mutex_unlock(void); ++void master_mutex_lock_cleanup(void *); + void master_set_default_timeout(void); + void master_set_default_ghost_mode(void); + int master_add_autofs_point(struct master_mapent *, time_t, unsigned, unsigned, int); +@@ -108,18 +111,4 @@ extern inline unsigned int master_get_lo + int master_list_empty(struct master *); + int master_kill(struct master *); + +-#define master_mutex_lock() \ +-do { \ +- int status = pthread_mutex_lock(&master_mutex); \ +- if (status) \ +- fatal(status); \ +-} while (0) +- +-#define master_mutex_unlock() \ +-do { \ +- int status = pthread_mutex_unlock(&master_mutex); \ +- if (status) \ +- fatal(status); \ +-} while (0) +- + #endif +--- autofs-5.0.3.orig/lib/master.c ++++ autofs-5.0.3/lib/master.c +@@ -41,8 +41,28 @@ static struct map_source * + __master_find_map_source(struct master_mapent *, + const char *, const char *, int, const char **); + +-pthread_mutex_t master_mutex = PTHREAD_MUTEX_INITIALIZER; +-pthread_mutex_t instance_mutex = PTHREAD_MUTEX_INITIALIZER; ++static pthread_mutex_t master_mutex = PTHREAD_MUTEX_INITIALIZER; ++static pthread_mutex_t instance_mutex = PTHREAD_MUTEX_INITIALIZER; ++ ++void master_mutex_lock(void) ++{ ++ int status = pthread_mutex_lock(&master_mutex); ++ if (status) ++ fatal(status); ++} ++ ++void master_mutex_unlock(void) ++{ ++ int status = pthread_mutex_unlock(&master_mutex); ++ if (status) ++ fatal(status); ++} ++ ++void master_mutex_lock_cleanup(void *arg) ++{ ++ master_mutex_unlock(); ++ return; ++} + + int master_add_autofs_point(struct master_mapent *entry, + time_t timeout, unsigned logopt, unsigned ghost, int submount) +@@ -1109,10 +1129,6 @@ int master_mount_mounts(struct master *m + continue; + } + +- master_source_writelock(ap->entry); +- lookup_close_lookup(ap); +- master_source_unlock(ap->entry); +- + cache_readlock(nc); + ne = cache_lookup_distinct(nc, this->path); + if (ne && this->age > ne->age) { diff --git a/autofs.spec b/autofs.spec index 2d9ee9b..6d5ebb3 100644 --- a/autofs.spec +++ b/autofs.spec @@ -4,7 +4,7 @@ Summary: A tool for automatically mounting and unmounting filesystems Name: autofs Version: 5.0.3 -Release: 28 +Release: 30 Epoch: 1 License: GPLv2+ Group: System Environment/Daemons @@ -65,6 +65,10 @@ Patch52: autofs-5.0.3-nisplus-partial-and-free.patch Patch53: autofs-5.0.3-fix-rootless-direct-multi-mount-expire.patch Patch54: autofs-5.0.3-wait-submount-expire-complete.patch Patch55: autofs-5.0.3-add-missing-uris-list-locking.patch +Patch56: autofs-5.0.3-library-reload-fix.patch +Patch57: autofs-5.0.3-expire-thread-create-cond-handling.patch +Patch58: autofs-5.0.3-fix-master-map-lexer-eval-order.patch +Patch59: autofs-5.0.3-fix-bad-alloca-usage.patch Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRequires: autoconf, hesiod-devel, openldap-devel, bison, flex, libxml2-devel, cyrus-sasl-devel, openssl-devel module-init-tools util-linux nfs-utils e2fsprogs Requires: kernel >= 2.6.17 @@ -161,6 +165,10 @@ echo %{version}-%{release} > .version %patch53 -p1 %patch54 -p1 %patch55 -p1 +%patch56 -p1 +%patch57 -p1 +%patch58 -p1 +%patch59 -p1 %build #CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=/usr --libdir=%{_libdir} @@ -213,6 +221,12 @@ fi %{_libdir}/autofs/ %changelog +* Sun Nov 2 2008 Ian Kent - 5.0.3-30 +- fix segv during library re-open. +- fix incorrect pthreads condition handling for expire requests. +- fix master map lexer eval order. +- fix bad alloca usage. + * Thu Oct 23 2008 Ian Kent - 5.0.3-28 - don't close file handle for rootless direct mounti-mount at mount. - wait submount expire thread completion when expire successful.