On Wed, 2012-03-28 at 11:42 -0400, Leonardo Chiquitto wrote: > On Tue, Mar 27, 2012 at 8:48 PM, Ian Kent <raven@xxxxxxxxxx> wrote: > > On Wed, 2012-03-28 at 08:26 +0800, Ian Kent wrote: > >> On Thu, 2012-03-15 at 23:15 -0400, Leonardo Chiquitto wrote: > >> > > >> > Fix segfault in get_query_dn() > >> > > >> > Automount will segfault when two threads run get_query_dn() > >> > simultaneously and $SEARCH_BASE is defined in sysconfig. > >> > This happens because a thread tries to dereference ctxt->sdns > >> > while another thread running the same function frees the > >> > memory. > >> > > >> > I believe we don't need to reread $SEARCH_BASE every time > >> > get_query_dn() is called. > >> > > >> > diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c > >> > index b6875fe..6ed3e17 100644 > >> > --- a/modules/lookup_ldap.c > >> > +++ b/modules/lookup_ldap.c > >> > @@ -281,7 +281,6 @@ static int get_query_dn(unsigned logopt, LDAP > >> > *ldap, struct lookup_context *ctxt > >> > char buf[MAX_ERR_BUF]; > >> > char *query, *dn, *qdn; > >> > LDAPMessage *result = NULL, *e; > >> > - struct ldap_searchdn *sdns = NULL; > >> > char *attrs[2]; > >> > struct berval **value; > >> > int scope; > >> > @@ -330,14 +329,8 @@ static int get_query_dn(unsigned logopt, LDAP > >> > *ldap, struct lookup_context *ctxt > >> > scope = LDAP_SCOPE_SUBTREE; > >> > } > >> > > >> > - if (!ctxt->base) { > >> > - sdns = defaults_get_searchdns(); > >> > - if (sdns) { > >> > - if (ctxt->sdns) > >> > - defaults_free_searchdns(ctxt->sdns); > >> > - ctxt->sdns = sdns; > >> > - } > >> > - } > >> > + if (!ctxt->base && !ctxt->sdns) > >> > + ctxt->sdns = defaults_get_searchdns(); > >> > >> While this narrows the race window and should prevent the fault, it > >> still has a problem since ctxt->sdns can change while it is in use. The > >> above two lines are a non-atomic read then update which can (at the > >> least) lead to a memory leak when the if (...) is evaluated while > >> another thread is executing defaults_get_searchdns(). > >> > >> So a mutex is still needed around these two lines. > >> > > > > An even better approach would be to move the read of the search dns to > > the lookup_init() module function. That should still do what is needed > > and reduce the code executed at lookup a little. > > > > autofs-5.0.6 - fix segfault in get_query_dn() > > > > From: Leonardo Chiquitto <leonardo.lists@xxxxxxxxx> > > > > Automount will segfault when two threads run get_query_dn() > > simultaneously and $SEARCH_BASE is defined in sysconfig. > > This happens because a thread tries to dereference ctxt->sdns > > while another thread running the same function frees the > > memory. > > > > I believe we don't need to reread $SEARCH_BASE every time > > get_query_dn() is called. > > > > edit: Ian Kent <raven@xxxxxxxxxx> > > move the read of configured search dns to lookup_init(). > > edit end > > --- > > Thanks for the updated patch, Ian. I verified that it also resolves > the problem (I know it's obvious but, as the test case is trivial, > I wanted to verify). Ha, disregard my last comment, I'm still half asleep, I'll actually commit this. > > Leonardo > > > modules/lookup_ldap.c | 13 +++---------- > > 1 files changed, 3 insertions(+), 10 deletions(-) > > > > > > diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c > > index b6875fe..8d12920 100644 > > --- a/modules/lookup_ldap.c > > +++ b/modules/lookup_ldap.c > > @@ -281,7 +281,6 @@ static int get_query_dn(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt > > char buf[MAX_ERR_BUF]; > > char *query, *dn, *qdn; > > LDAPMessage *result = NULL, *e; > > - struct ldap_searchdn *sdns = NULL; > > char *attrs[2]; > > struct berval **value; > > int scope; > > @@ -330,15 +329,6 @@ static int get_query_dn(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt > > scope = LDAP_SCOPE_SUBTREE; > > } > > > > - if (!ctxt->base) { > > - sdns = defaults_get_searchdns(); > > - if (sdns) { > > - if (ctxt->sdns) > > - defaults_free_searchdns(ctxt->sdns); > > - ctxt->sdns = sdns; > > - } > > - } > > - > > dn = NULL; > > if (!ctxt->sdns) { > > rv = ldap_search_s(ldap, ctxt->base, > > @@ -1467,6 +1457,9 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co > > return 1; > > } > > > > + if (!ctxt->base) > > + ctxt->sdns = defaults_get_searchdns(); > > + > > ctxt->timeout = defaults_get_ldap_timeout(); > > ctxt->network_timeout = defaults_get_ldap_network_timeout(); > > -- To unsubscribe from this list: send the line "unsubscribe autofs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html