From 4a0bd1020f28c97dd89a02e666e094c8d043d6aa Mon Sep 17 00:00:00 2001 From: Sjoerd Simons Date: Mon, 13 Apr 2015 22:54:25 +0200 Subject: [PATCH] pxe: Ensure all memory access is to mapped memory Properly map memory through map_sysmem so that pxe can be used from the sandbox. Tested in sandbox as well as on jetson-tk1, odroid-xu3, snow as peach-pi boards Signed-off-by: Sjoerd Simons Acked-by: Simon Glass --- common/cmd_pxe.c | 86 ++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 56 insertions(+), 30 deletions(-) diff --git a/common/cmd_pxe.c b/common/cmd_pxe.c index 5cde5b6..4cbb2b1 100644 --- a/common/cmd_pxe.c +++ b/common/cmd_pxe.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "menu.h" #include "cli.h" @@ -189,11 +190,12 @@ static int do_get_any(cmd_tbl_t *cmdtp, const char *file_path, char *file_addr) * * Returns 1 for success, or < 0 on error. */ -static int get_relfile(cmd_tbl_t *cmdtp, const char *file_path, void *file_addr) +static int get_relfile(cmd_tbl_t *cmdtp, const char *file_path, + unsigned long file_addr) { size_t path_len; char relfile[MAX_TFTP_PATH_LEN+1]; - char addr_buf[10]; + char addr_buf[18]; int err; err = get_bootfile_path(file_path, relfile, sizeof(relfile)); @@ -216,7 +218,7 @@ static int get_relfile(cmd_tbl_t *cmdtp, const char *file_path, void *file_addr) printf("Retrieving file: %s\n", relfile); - sprintf(addr_buf, "%p", file_addr); + sprintf(addr_buf, "%lx", file_addr); return do_getfile(cmdtp, relfile, addr_buf); } @@ -228,11 +230,13 @@ static int get_relfile(cmd_tbl_t *cmdtp, const char *file_path, void *file_addr) * * Returns 1 on success, or < 0 for error. */ -static int get_pxe_file(cmd_tbl_t *cmdtp, const char *file_path, void *file_addr) +static int get_pxe_file(cmd_tbl_t *cmdtp, const char *file_path, + unsigned long file_addr) { unsigned long config_file_size; char *tftp_filesize; int err; + char *buf; err = get_relfile(cmdtp, file_path, file_addr); @@ -251,7 +255,9 @@ static int get_pxe_file(cmd_tbl_t *cmdtp, const char *file_path, void *file_addr if (strict_strtoul(tftp_filesize, 16, &config_file_size) < 0) return -EINVAL; - *(char *)(file_addr + config_file_size) = '\0'; + buf = map_sysmem(file_addr + config_file_size, 1); + *buf = '\0'; + unmap_sysmem(buf); return 1; } @@ -267,7 +273,8 @@ static int get_pxe_file(cmd_tbl_t *cmdtp, const char *file_path, void *file_addr * * Returns 1 on success or < 0 on error. */ -static int get_pxelinux_path(cmd_tbl_t *cmdtp, const char *file, void *pxefile_addr_r) +static int get_pxelinux_path(cmd_tbl_t *cmdtp, const char *file, + unsigned long pxefile_addr_r) { size_t base_len = strlen(PXELINUX_DIR); char path[MAX_TFTP_PATH_LEN+1]; @@ -288,7 +295,7 @@ static int get_pxelinux_path(cmd_tbl_t *cmdtp, const char *file, void *pxefile_a * * Returns 1 on success or < 0 on error. */ -static int pxe_uuid_path(cmd_tbl_t *cmdtp, void *pxefile_addr_r) +static int pxe_uuid_path(cmd_tbl_t *cmdtp, unsigned long pxefile_addr_r) { char *uuid_str; @@ -306,7 +313,7 @@ static int pxe_uuid_path(cmd_tbl_t *cmdtp, void *pxefile_addr_r) * * Returns 1 on success or < 0 on error. */ -static int pxe_mac_path(cmd_tbl_t *cmdtp, void *pxefile_addr_r) +static int pxe_mac_path(cmd_tbl_t *cmdtp, unsigned long pxefile_addr_r) { char mac_str[21]; int err; @@ -326,7 +333,7 @@ static int pxe_mac_path(cmd_tbl_t *cmdtp, void *pxefile_addr_r) * * Returns 1 on success or < 0 on error. */ -static int pxe_ipaddr_paths(cmd_tbl_t *cmdtp, void *pxefile_addr_r) +static int pxe_ipaddr_paths(cmd_tbl_t *cmdtp, unsigned long pxefile_addr_r) { char ip_addr[9]; int mask_pos, err; @@ -385,9 +392,9 @@ do_pxe_get(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) * Keep trying paths until we successfully get a file we're looking * for. */ - if (pxe_uuid_path(cmdtp, (void *)pxefile_addr_r) > 0 || - pxe_mac_path(cmdtp, (void *)pxefile_addr_r) > 0 || - pxe_ipaddr_paths(cmdtp, (void *)pxefile_addr_r) > 0) { + if (pxe_uuid_path(cmdtp, pxefile_addr_r) > 0 || + pxe_mac_path(cmdtp, pxefile_addr_r) > 0 || + pxe_ipaddr_paths(cmdtp, pxefile_addr_r) > 0) { printf("Config file found\n"); return 0; @@ -395,7 +402,7 @@ do_pxe_get(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) while (pxe_default_paths[i]) { if (get_pxelinux_path(cmdtp, pxe_default_paths[i], - (void *)pxefile_addr_r) > 0) { + pxefile_addr_r) > 0) { printf("Config file found\n"); return 0; } @@ -428,7 +435,7 @@ static int get_relfile_envaddr(cmd_tbl_t *cmdtp, const char *file_path, const ch if (strict_strtoul(envaddr, 16, &file_addr) < 0) return -EINVAL; - return get_relfile(cmdtp, file_path, (void *)file_addr); + return get_relfile(cmdtp, file_path, file_addr); } /* @@ -791,6 +798,7 @@ static int label_boot(cmd_tbl_t *cmdtp, struct pxe_label *label) else do_bootz(cmdtp, 0, bootm_argc, bootm_argv); #endif + unmap_sysmem(buf); return 1; } @@ -1055,7 +1063,8 @@ static int parse_integer(char **c, int *dst) return 1; } -static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, struct pxe_menu *cfg, int nest_level); +static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, unsigned long base, + struct pxe_menu *cfg, int nest_level); /* * Parse an include statement, and retrieve and parse the file it mentions. @@ -1065,12 +1074,14 @@ static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, struct pxe_menu *cfg, in * include, nest_level has already been incremented and doesn't need to be * incremented here. */ -static int handle_include(cmd_tbl_t *cmdtp, char **c, char *base, +static int handle_include(cmd_tbl_t *cmdtp, char **c, unsigned long base, struct pxe_menu *cfg, int nest_level) { char *include_path; char *s = *c; int err; + char *buf; + int ret; err = parse_sliteral(c, &include_path); @@ -1087,20 +1098,25 @@ static int handle_include(cmd_tbl_t *cmdtp, char **c, char *base, return err; } - return parse_pxefile_top(cmdtp, base, cfg, nest_level); + buf = map_sysmem(base, 0); + ret = parse_pxefile_top(cmdtp, buf, base, cfg, nest_level); + unmap_sysmem(buf); + + return ret; } /* * Parse lines that begin with 'menu'. * - * b and nest are provided to handle the 'menu include' case. + * base and nest are provided to handle the 'menu include' case. * - * b should be the address where the file currently being parsed is stored. + * base should point to a location where it's safe to store the included file. * * nest_level should be 1 when parsing the top level pxe file, 2 when parsing * a file it includes, 3 when parsing a file included by that file, and so on. */ -static int parse_menu(cmd_tbl_t *cmdtp, char **c, struct pxe_menu *cfg, char *b, int nest_level) +static int parse_menu(cmd_tbl_t *cmdtp, char **c, struct pxe_menu *cfg, + unsigned long base, int nest_level) { struct token t; char *s = *c; @@ -1115,7 +1131,7 @@ static int parse_menu(cmd_tbl_t *cmdtp, char **c, struct pxe_menu *cfg, char *b, break; case T_INCLUDE: - err = handle_include(cmdtp, c, b + strlen(b) + 1, cfg, + err = handle_include(cmdtp, c, base, cfg, nest_level + 1); break; @@ -1282,7 +1298,8 @@ static int parse_label(char **c, struct pxe_menu *cfg) * * Returns 1 on success, < 0 on error. */ -static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, struct pxe_menu *cfg, int nest_level) +static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, unsigned long base, + struct pxe_menu *cfg, int nest_level) { struct token t; char *s, *b, *label_name; @@ -1304,7 +1321,9 @@ static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, struct pxe_menu *cfg, in switch (t.type) { case T_MENU: cfg->prompt = 1; - err = parse_menu(cmdtp, &p, cfg, b, nest_level); + err = parse_menu(cmdtp, &p, cfg, + base + ALIGN(strlen(b) + 1, 4), + nest_level); break; case T_TIMEOUT: @@ -1329,8 +1348,9 @@ static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, struct pxe_menu *cfg, in break; case T_INCLUDE: - err = handle_include(cmdtp, &p, b + ALIGN(strlen(b), 4), cfg, - nest_level + 1); + err = handle_include(cmdtp, &p, + base + ALIGN(strlen(b), 4), cfg, + nest_level + 1); break; case T_PROMPT: @@ -1386,9 +1406,11 @@ static void destroy_pxe_menu(struct pxe_menu *cfg) * files it includes). The resulting pxe_menu struct can be free()'d by using * the destroy_pxe_menu() function. */ -static struct pxe_menu *parse_pxefile(cmd_tbl_t *cmdtp, char *menucfg) +static struct pxe_menu *parse_pxefile(cmd_tbl_t *cmdtp, unsigned long menucfg) { struct pxe_menu *cfg; + char *buf; + int r; cfg = malloc(sizeof(struct pxe_menu)); @@ -1399,7 +1421,11 @@ static struct pxe_menu *parse_pxefile(cmd_tbl_t *cmdtp, char *menucfg) INIT_LIST_HEAD(&cfg->labels); - if (parse_pxefile_top(cmdtp, menucfg, cfg, 1) < 0) { + buf = map_sysmem(menucfg, 0); + r = parse_pxefile_top(cmdtp, buf, menucfg, cfg, 1); + unmap_sysmem(buf); + + if (r < 0) { destroy_pxe_menu(cfg); return NULL; } @@ -1557,7 +1583,7 @@ do_pxe_boot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return 1; } - cfg = parse_pxefile(cmdtp, (char *)(pxefile_addr_r)); + cfg = parse_pxefile(cmdtp, pxefile_addr_r); if (cfg == NULL) { printf("Error parsing config file\n"); @@ -1664,12 +1690,12 @@ static int do_sysboot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return 1; } - if (get_pxe_file(cmdtp, filename, (void *)pxefile_addr_r) < 0) { + if (get_pxe_file(cmdtp, filename, pxefile_addr_r) < 0) { printf("Error reading config file\n"); return 1; } - cfg = parse_pxefile(cmdtp, (char *)(pxefile_addr_r)); + cfg = parse_pxefile(cmdtp, pxefile_addr_r); if (cfg == NULL) { printf("Error parsing config file\n"); -- 2.7.4