diff options
| author | Rob Herring <rob.herring@calxeda.com> | 2013-03-22 11:26:21 +0000 | 
|---|---|---|
| committer | Tom Rini <trini@ti.com> | 2013-04-02 16:23:34 -0400 | 
| commit | 60d7d5a63189c9f77a190c9965861dc15482c2d0 (patch) | |
| tree | 68bf7c543f8f282142eb7a10c700b3a3d86341fb /common/env_nvram.c | |
| parent | c17b94ec5ec89c63070dd385b6c3a6645761c405 (diff) | |
| download | olio-uboot-2014.01-60d7d5a63189c9f77a190c9965861dc15482c2d0.tar.xz olio-uboot-2014.01-60d7d5a63189c9f77a190c9965861dc15482c2d0.zip | |
env: fix potential stack overflow in environment functions
Most of the various environment functions create CONFIG_ENV_SIZE buffers on
the stack. At least on ARM and PPC which have 4KB stacks, this can overflow
the stack if we have large environment sizes. So move all the buffers off
the stack to static buffers.
Signed-off-by: Rob Herring <rob.herring@calxeda.com>
Diffstat (limited to 'common/env_nvram.c')
| -rw-r--r-- | common/env_nvram.c | 26 | 
1 files changed, 16 insertions, 10 deletions
| diff --git a/common/env_nvram.c b/common/env_nvram.c index eab0e7be0..ff74a6c2c 100644 --- a/common/env_nvram.c +++ b/common/env_nvram.c @@ -60,6 +60,10 @@ env_t *env_ptr = (env_t *)CONFIG_ENV_ADDR;  char *env_name_spec = "NVRAM";  #ifdef CONFIG_SYS_NVRAM_ACCESS_ROUTINE +static char env_buf[CONFIG_ENV_SIZE]; +#endif + +#ifdef CONFIG_SYS_NVRAM_ACCESS_ROUTINE  uchar env_get_char_spec(int index)  {  	uchar c; @@ -72,36 +76,38 @@ uchar env_get_char_spec(int index)  void env_relocate_spec(void)  { -	char buf[CONFIG_ENV_SIZE]; +	char *buf;  #if defined(CONFIG_SYS_NVRAM_ACCESS_ROUTINE) +	buf = env_buf;  	nvram_read(buf, CONFIG_ENV_ADDR, CONFIG_ENV_SIZE);  #else -	memcpy(buf, (void *)CONFIG_ENV_ADDR, CONFIG_ENV_SIZE); +	buf = (void *)CONFIG_ENV_ADDR;  #endif  	env_import(buf, 1);  }  int saveenv(void)  { -	env_t	env_new; +#ifdef CONFIG_SYS_NVRAM_ACCESS_ROUTINE +	env_t	*env_new = (env_t *)env_buf; +#else +	env_t	*env_new = (env_t *)CONFIG_ENV_ADDR; +#endif  	ssize_t	len;  	char	*res;  	int	rcode = 0; -	res = (char *)&env_new.data; +	res = (char *)env_new->data;  	len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);  	if (len < 0) {  		error("Cannot export environment: errno = %d\n", errno);  		return 1;  	} -	env_new.crc = crc32(0, env_new.data, ENV_SIZE); +	env_new->crc = crc32(0, env_new->data, ENV_SIZE);  #ifdef CONFIG_SYS_NVRAM_ACCESS_ROUTINE -	nvram_write(CONFIG_ENV_ADDR, &env_new, CONFIG_ENV_SIZE); -#else -	if (memcpy((char *)CONFIG_ENV_ADDR, &env_new, CONFIG_ENV_SIZE) == NULL) -		rcode = 1; +	nvram_write(CONFIG_ENV_ADDR, env_new, CONFIG_ENV_SIZE);  #endif  	return rcode;  } @@ -115,7 +121,7 @@ int env_init(void)  {  #if defined(CONFIG_SYS_NVRAM_ACCESS_ROUTINE)  	ulong crc; -	uchar data[ENV_SIZE]; +	uchar *data = env_buf;  	nvram_read(&crc, CONFIG_ENV_ADDR, sizeof(ulong));  	nvram_read(data, CONFIG_ENV_ADDR + sizeof(ulong), ENV_SIZE); |