Skip to content

Commit

Permalink
Make sure that argv[] argument pointers are not modified.
Browse files Browse the repository at this point in the history
The hush shell dynamically allocates (and re-allocates) memory for the
argument strings in the "char *argv[]" argument vector passed to
commands.  Any code that modifies these pointers will cause serious
corruption of the malloc data structures and crash U-Boot, so make
sure the compiler can check that no such modifications are being done
by changing the code into "char * const argv[]".

This modification is the result of debugging a strange crash caused
after adding a new command, which used the following argument
processing code which has been working perfectly fine in all Unix
systems since version 6 - but not so in U-Boot:

int main (int argc, char **argv)
{
	while (--argc > 0 && **++argv == '-') {
/* ====> */	while (*++*argv) {
			switch (**argv) {
			case 'd':
				debug++;
				break;
			...
			default:
				usage ();
			}
		}
	}
	...
}

The line marked "====>" will corrupt the malloc data structures and
usually cause U-Boot to crash when the next command gets executed by
the shell.  With the modification, the compiler will prevent this with
an
	error: increment of read-only location '*argv'

N.B.: The code above can be trivially rewritten like this:

	while (--argc > 0 && **++argv == '-') {
		char *arg = *argv;
		while (*++arg) {
			switch (*arg) {
			...

Signed-off-by: Wolfgang Denk <[email protected]>
Acked-by: Mike Frysinger <[email protected]>
  • Loading branch information
wdenx committed Jul 4, 2010
1 parent b218ccb commit 54841ab
Show file tree
Hide file tree
Showing 295 changed files with 671 additions and 670 deletions.
2 changes: 1 addition & 1 deletion api/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
#undef DEBUG

/* U-Boot routines needed */
extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);

/*****************************************************************************
*
Expand Down
2 changes: 1 addition & 1 deletion arch/arm/cpu/arm_cortexa8/mx51/clock.c
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ u32 imx_get_fecclk(void)
/*
* Dump some core clockes.
*/
int do_mx51_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
int do_mx51_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
u32 freq;

Expand Down
2 changes: 1 addition & 1 deletion arch/arm/cpu/arm_cortexa8/omap3/board.c
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ void abort(void)
/******************************************************************************
* OMAP3 specific command to switch between NAND HW and SW ecc
*****************************************************************************/
static int do_switch_ecc(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
static int do_switch_ecc(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
if (argc != 2)
goto usage;
Expand Down
2 changes: 1 addition & 1 deletion arch/arm/lib/bootm.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ static void setup_end_tag (bd_t *bd);
static struct tag *params;
#endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */

int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *images)
{
bd_t *bd = gd->bd;
char *s;
Expand Down
2 changes: 1 addition & 1 deletion arch/arm/lib/reset.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@

#include <common.h>

int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
puts ("resetting ...\n");

Expand Down
2 changes: 1 addition & 1 deletion arch/avr32/cpu/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ void prepare_to_boot(void)
"sync 0" : : "r"(0) : "memory");
}

int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
/* This will reset the CPU core, caches, MMU and all internal busses */
__builtin_mtdr(8, 1 << 13); /* set DC:DBE */
Expand Down
2 changes: 1 addition & 1 deletion arch/avr32/lib/bootm.c
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ static void setup_end_tag(struct tag *params)
params->hdr.size = 0;
}

int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *images)
{
void (*theKernel)(int magic, void *tagtable);
struct tag *params, *params_start;
Expand Down
2 changes: 1 addition & 1 deletion arch/blackfin/cpu/bootrom-asm-offsets.c.in
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@
#define _DEFINE(sym, val) asm volatile("\n->" #sym " %0 " #val : : "i" (val))
#define DEFINE(s, m) _DEFINE(offset_##s##_##m, offsetof(s, m))

int main(int argc, char *argv[])
int main(int argc, char * const argv[])
2 changes: 1 addition & 1 deletion arch/blackfin/cpu/reset.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ void bfin_reset_or_hang(void)
#endif
}

int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
bfin_reset_trampoline();
return 0;
Expand Down
2 changes: 1 addition & 1 deletion arch/blackfin/lib/boot.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ static char *make_command_line(void)

extern ulong bfin_poweron_retx;

int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *images)
{
int (*appl) (char *cmdline);
char *cmdline;
Expand Down
4 changes: 2 additions & 2 deletions arch/blackfin/lib/cmd_cache_dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ static int check_limit(const char *type, size_t start_limit, size_t end_limit, s
return 1;
}

int do_icache_dump(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
int do_icache_dump(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
int cache_status = icache_status();

Expand Down Expand Up @@ -97,7 +97,7 @@ U_BOOT_CMD(icache_dump, 4, 0, do_icache_dump,
"icache_dump - dump current instruction cache\n",
"[way] [subbank] [set]");

int do_dcache_dump(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
int do_dcache_dump(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
u32 way, bank, subbank, set;
u32 status, addr;
Expand Down
2 changes: 1 addition & 1 deletion arch/blackfin/lib/kgdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ void kgdb_putregs(struct pt_regs *regs, char *buf, int length)

}

void kgdb_breakpoint(int argc, char *argv[])
void kgdb_breakpoint(int argc, char * const argv[])
{
asm volatile ("excpt 0x1\n");
}
2 changes: 1 addition & 1 deletion arch/i386/cpu/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ int cpu_init_r(void)
return 0;
}

int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
printf ("resetting ...\n");
udelay(50000); /* wait 50 ms */
Expand Down
2 changes: 1 addition & 1 deletion arch/i386/lib/board.c
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@ void hang (void)
for (;;);
}

unsigned long do_go_exec (ulong (*entry)(int, char *[]), int argc, char *argv[])
unsigned long do_go_exec (ulong (*entry)(int, char *[]), int argc, char * const argv[])
{
/*
* x86 does not use a dedicated register to pass the pointer
Expand Down
2 changes: 1 addition & 1 deletion arch/i386/lib/bootm.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
#include <asm/zimage.h>

/*cmd_boot.c*/
int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *images)
{
void *base_ptr;
ulong os_data, os_len;
Expand Down
2 changes: 1 addition & 1 deletion arch/i386/lib/interrupts.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ void do_irq(int hw_irq)
}

#if defined(CONFIG_CMD_IRQ)
int do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
int do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
int irq;

Expand Down
2 changes: 1 addition & 1 deletion arch/i386/lib/zimage.c
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ void boot_zimage(void *setup_base)
enter_realmode(((u32)setup_base+SETUP_START_OFFSET)>>4, 0, &regs, &regs);
}

int do_zboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
int do_zboot (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
void *base_ptr;
void *bzImage_addr;
Expand Down
2 changes: 1 addition & 1 deletion arch/m68k/cpu/mcf5227x/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@

DECLARE_GLOBAL_DATA_PTR;

int do_reset(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char *argv[])
int do_reset(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char * const argv[])
{
volatile rcm_t *rcm = (rcm_t *) (MMAP_RCM);
udelay(1000);
Expand Down
2 changes: 1 addition & 1 deletion arch/m68k/cpu/mcf523x/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@

DECLARE_GLOBAL_DATA_PTR;

int do_reset(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char *argv[])
int do_reset(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char * const argv[])
{
volatile ccm_t *ccm = (ccm_t *) MMAP_CCM;

Expand Down
14 changes: 7 additions & 7 deletions arch/m68k/cpu/mcf52x2/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
DECLARE_GLOBAL_DATA_PTR;

#ifdef CONFIG_M5208
int do_reset(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
int do_reset(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char * const argv[])
{
volatile rcm_t *rcm = (rcm_t *)(MMAP_RCM);

Expand Down Expand Up @@ -142,7 +142,7 @@ int checkcpu(void)
return 0;
}

int do_reset(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char *argv[])
int do_reset(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char * const argv[])
{
/* Call the board specific reset actions first. */
if(board_reset) {
Expand Down Expand Up @@ -177,7 +177,7 @@ int watchdog_init(void)
#endif

#ifdef CONFIG_M5272
int do_reset(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char *argv[])
int do_reset(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char * const argv[])
{
volatile wdog_t *wdp = (wdog_t *) (MMAP_WDOG);

Expand Down Expand Up @@ -257,7 +257,7 @@ int watchdog_init(void)
#endif /* #ifdef CONFIG_M5272 */

#ifdef CONFIG_M5275
int do_reset(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
int do_reset(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char * const argv[])
{
volatile rcm_t *rcm = (rcm_t *)(MMAP_RCM);

Expand Down Expand Up @@ -337,7 +337,7 @@ int checkcpu(void)
return 0;
}

int do_reset(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char *argv[])
int do_reset(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char * const argv[])
{
MCFRESET_RCR = MCFRESET_RCR_SOFTRST;
return 0;
Expand All @@ -354,7 +354,7 @@ int checkcpu(void)
return 0;
}

int do_reset(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char *argv[])
int do_reset(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char * const argv[])
{
/* enable watchdog, set timeout to 0 and wait */
mbar_writeByte(MCFSIM_SYPCR, 0xc0);
Expand Down Expand Up @@ -384,7 +384,7 @@ int checkcpu(void)
return 0;
}

int do_reset(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char *argv[])
int do_reset(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char * const argv[])
{
/* enable watchdog, set timeout to 0 and wait */
mbar_writeByte(SIM_SYPCR, 0xc0);
Expand Down
2 changes: 1 addition & 1 deletion arch/m68k/cpu/mcf532x/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@

DECLARE_GLOBAL_DATA_PTR;

int do_reset(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char *argv[])
int do_reset(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char * const argv[])
{
volatile rcm_t *rcm = (rcm_t *) (MMAP_RCM);

Expand Down
2 changes: 1 addition & 1 deletion arch/m68k/cpu/mcf5445x/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@

DECLARE_GLOBAL_DATA_PTR;

int do_reset(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char *argv[])
int do_reset(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char * const argv[])
{
volatile rcm_t *rcm = (rcm_t *) (MMAP_RCM);
udelay(1000);
Expand Down
2 changes: 1 addition & 1 deletion arch/m68k/cpu/mcf547x_8x/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@

DECLARE_GLOBAL_DATA_PTR;

int do_reset(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char *argv[])
int do_reset(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char * const argv[])
{
volatile gptmr_t *gptmr = (gptmr_t *) (MMAP_GPTMR);

Expand Down
2 changes: 1 addition & 1 deletion arch/m68k/lib/bootm.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ void arch_lmb_reserve(struct lmb *lmb)
lmb_reserve(lmb, sp, (CONFIG_SYS_SDRAM_BASE + gd->ram_size - sp));
}

int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *images)
{
ulong rd_len;
ulong initrd_start, initrd_end;
Expand Down
4 changes: 2 additions & 2 deletions arch/microblaze/cpu/interrupts.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ void interrupt_handler (void)

#if defined(CONFIG_CMD_IRQ)
#ifdef CONFIG_SYS_INTC_0
int do_irqinfo (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
int do_irqinfo (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
int i;
struct irq_action *act = vecs;
Expand All @@ -193,7 +193,7 @@ int do_irqinfo (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
return (0);
}
#else
int do_irqinfo (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
int do_irqinfo (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
puts ("Undefined interrupt controller\n");
}
Expand Down
2 changes: 1 addition & 1 deletion arch/microblaze/lib/bootm.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@

DECLARE_GLOBAL_DATA_PTR;

int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *images)
{
/* First parameter is mapped to $r5 for kernel boot args */
void (*theKernel) (char *, ulong, ulong);
Expand Down
2 changes: 1 addition & 1 deletion arch/mips/cpu/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ void __attribute__((weak)) _machine_restart(void)
{
}

int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
_machine_restart();

Expand Down
2 changes: 1 addition & 1 deletion arch/mips/lib/bootm.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ static int linux_env_idx;
static void linux_params_init (ulong start, char * commandline);
static void linux_env_set (char * env_name, char * env_val);

int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *images)
{
void (*theKernel) (int, char **, char **, int *);
char *commandline = getenv ("bootargs");
Expand Down
2 changes: 1 addition & 1 deletion arch/mips/lib/bootm_qemu_mips.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

DECLARE_GLOBAL_DATA_PTR;

int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *images)
{
void (*theKernel) (int, char **, char **, int *);
char *bootargs = getenv ("bootargs");
Expand Down
14 changes: 7 additions & 7 deletions arch/nios2/cpu/epcs.c
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@ static int epcs_sect_erased (int sect, unsigned *offset,
* Commands
***********************************************************************/
static
void do_epcs_info (struct epcs_devinfo_t *dev, int argc, char *argv[])
void do_epcs_info (struct epcs_devinfo_t *dev, int argc, char * const argv[])
{
int i;
unsigned char stat;
Expand Down Expand Up @@ -519,7 +519,7 @@ void do_epcs_info (struct epcs_devinfo_t *dev, int argc, char *argv[])
}

static
void do_epcs_erase (struct epcs_devinfo_t *dev, int argc, char *argv[])
void do_epcs_erase (struct epcs_devinfo_t *dev, int argc, char * const argv[])
{
unsigned start,end;

Expand Down Expand Up @@ -549,7 +549,7 @@ void do_epcs_erase (struct epcs_devinfo_t *dev, int argc, char *argv[])
}

static
void do_epcs_protect (struct epcs_devinfo_t *dev, int argc, char *argv[])
void do_epcs_protect (struct epcs_devinfo_t *dev, int argc, char * const argv[])
{
unsigned char stat;

Expand Down Expand Up @@ -585,7 +585,7 @@ void do_epcs_protect (struct epcs_devinfo_t *dev, int argc, char *argv[])
}

static
void do_epcs_read (struct epcs_devinfo_t *dev, int argc, char *argv[])
void do_epcs_read (struct epcs_devinfo_t *dev, int argc, char * const argv[])
{
ulong addr,off,cnt;
ulong sz;
Expand Down Expand Up @@ -617,7 +617,7 @@ void do_epcs_read (struct epcs_devinfo_t *dev, int argc, char *argv[])
}

static
void do_epcs_write (struct epcs_devinfo_t *dev, int argc, char *argv[])
void do_epcs_write (struct epcs_devinfo_t *dev, int argc, char * const argv[])
{
ulong addr,off,cnt;
ulong sz;
Expand Down Expand Up @@ -656,7 +656,7 @@ void do_epcs_write (struct epcs_devinfo_t *dev, int argc, char *argv[])
}

static
void do_epcs_verify (struct epcs_devinfo_t *dev, int argc, char *argv[])
void do_epcs_verify (struct epcs_devinfo_t *dev, int argc, char * const argv[])
{
ulong addr,off,cnt;
ulong sz;
Expand Down Expand Up @@ -690,7 +690,7 @@ void do_epcs_verify (struct epcs_devinfo_t *dev, int argc, char *argv[])
}

/*-----------------------------------------------------------------------*/
int do_epcs (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
int do_epcs (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
int len;
struct epcs_devinfo_t *dev = epcs_dev_find ();
Expand Down
Loading

0 comments on commit 54841ab

Please sign in to comment.