diff options
Diffstat (limited to 'lib/hashtable.c')
| -rw-r--r-- | lib/hashtable.c | 27 | 
1 files changed, 24 insertions, 3 deletions
| diff --git a/lib/hashtable.c b/lib/hashtable.c index e8a59e2dcac..75c263b5053 100644 --- a/lib/hashtable.c +++ b/lib/hashtable.c @@ -221,11 +221,32 @@ static int  do_callback(const struct env_entry *e, const char *name, const char *value,  	    enum env_op op, int flags)  { +	int ret = 0; +  #ifndef CONFIG_XPL_BUILD -	if (e->callback) -		return e->callback(name, value, op, flags); +	static bool in_callback; + +	if (!e->callback || in_callback) +		return 0; + +	/* +	 * In case there are two variables which each implement env callback +	 * that performs env_set() on the other variable, the callbacks will +	 * call each other recursively until the stack runs out. Prevent such +	 * a recursion from happening. +	 * +	 * Example which triggers this behavior: +	 * static int on_foo(...) { env_set("bar", 0); ... } +	 * static int on_bar(...) { env_set("foo", 0); ... } +	 * U_BOOT_ENV_CALLBACK(foo, on_foo); +	 * U_BOOT_ENV_CALLBACK(bar, on_bar); +	 */ +	in_callback = true; +	ret = e->callback(name, value, op, flags); +	in_callback = false;  #endif -	return 0; + +	return ret;  }  /* | 
