From: Matthew Dillon Date: Sat, 8 Mar 2014 05:49:30 +0000 (-0800) Subject: hammer2 - Fix stack blowout in lookup iteration X-Git-Tag: v3.9.0~409 X-Git-Url: https://gitweb.dragonflybsd.org/~tuxillo/dragonfly.git/commitdiff_plain/c9bda9e78d9ed14cd9268f2914f8a39f2f09180c hammer2 - Fix stack blowout in lookup iteration * hammer2_chain_lookup()->hammer2_chain_next()->hammer2_chain_lookup() stacking could blow out the kernel stack. * Inline the iteration within hammer2_chain_lookup() when the lookup runs out of blockrefs without finding anything at the current level, instead of having it call hammer2_chain_next(). --- diff --git a/sys/vfs/hammer2/hammer2_chain.c b/sys/vfs/hammer2/hammer2_chain.c index 42ab8a8455..0f232da52a 100644 --- a/sys/vfs/hammer2/hammer2_chain.c +++ b/sys/vfs/hammer2/hammer2_chain.c @@ -2063,9 +2063,25 @@ again: spin_unlock(&above->cst.spin); if (key_beg == key_end) /* short cut single-key case */ return (NULL); - return (hammer2_chain_next(parentp, NULL, key_nextp, - key_beg, key_end, - cache_indexp, flags)); + + /* + * Stop if we reached the end of the iteration. + */ + if (parent->bref.type != HAMMER2_BREF_TYPE_INDIRECT && + parent->bref.type != HAMMER2_BREF_TYPE_FREEMAP_NODE) { + return (NULL); + } + + /* + * Calculate next key, stop if we reached the end of the + * iteration, otherwise go up one level and loop. + */ + key_beg = parent->bref.key + + ((hammer2_key_t)1 << parent->bref.keybits); + if (key_beg == 0 || key_beg > key_end) + return (NULL); + parent = hammer2_chain_getparent(parentp, how_maybe); + goto again; } /*