diff options
author | H. Peter Anvin <hpa@zytor.com> | 2010-02-24 14:18:49 -0800 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2010-02-24 14:18:49 -0800 |
commit | 8a4b35805fdc6651d288a3e1c2d98aa504cb9c05 (patch) | |
tree | 37c4bdef99996ab681e03c7a3f407563a9ff35d7 | |
parent | 3ae1da98a68d2f719ce17766550f7e9682ba8ae7 (diff) | |
download | syslinux-8a4b35805fdc6651d288a3e1c2d98aa504cb9c05.tar.gz |
com32: replace hard-coded bounce buffer use in com32/libsyslinux-4.00-pre25
Replace hard-coded bounce buffer uses in com32/lib with lmalloc/lfree.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r-- | com32/include/syslinux/boot.h | 2 | ||||
-rw-r--r-- | com32/lib/opendir.c | 17 | ||||
-rw-r--r-- | com32/lib/sys/gpxe.c | 25 | ||||
-rw-r--r-- | com32/lib/sys/open.c | 11 | ||||
-rw-r--r-- | com32/lib/sys/vesa/initvesa.c | 52 | ||||
-rw-r--r-- | com32/lib/syslinux/memscan.c | 9 | ||||
-rw-r--r-- | com32/lib/syslinux/pxe_dns.c | 13 | ||||
-rw-r--r-- | com32/lib/syslinux/pxe_get_cached.c | 37 | ||||
-rw-r--r-- | com32/lib/syslinux/pxe_get_nic.c | 14 | ||||
-rw-r--r-- | com32/lib/syslinux/run_command.c | 17 | ||||
-rw-r--r-- | com32/lib/syslinux/runimage.c | 26 |
11 files changed, 149 insertions, 74 deletions
diff --git a/com32/include/syslinux/boot.h b/com32/include/syslinux/boot.h index 87c05e99..21bea01a 100644 --- a/com32/include/syslinux/boot.h +++ b/com32/include/syslinux/boot.h @@ -37,7 +37,7 @@ #include <stdint.h> #include <klibc/compiler.h> -__noreturn syslinux_run_command(const char *); +int syslinux_run_command(const char *); __noreturn syslinux_run_default(void); void syslinux_local_boot(uint16_t flags); diff --git a/com32/lib/opendir.c b/com32/lib/opendir.c index c5e9aa05..e3c35ce8 100644 --- a/com32/lib/opendir.c +++ b/com32/lib/opendir.c @@ -16,21 +16,26 @@ DIR *opendir(const char *pathname) { DIR *newdir = NULL; com32sys_t regs; - - strlcpy(__com32.cs_bounce, pathname, __com32.cs_bounce_size); + char *lm_pathname; + + lm_pathname = lstrdup(pathname); + if (!lm_pathname) + return NULL; regs.eax.w[0] = 0x0020; - regs.esi.w[0] = OFFS(__com32.cs_bounce); - regs.es = SEG(__com32.cs_bounce); + regs.esi.w[0] = OFFS(lm_pathname); + regs.es = SEG(lm_pathname); __com32.cs_intcall(0x22, ®s, ®s); if (!(regs.eflags.l & EFLAGS_CF)) { /* Initialization: malloc() then zero */ - newdir = calloc(1, sizeof(DIR)); + newdir = zalloc(sizeof(DIR)); newdir->dd_dir = (struct file *)regs.eax.l; } - + + lfree(lm_pathname); + /* We're done */ return newdir; } diff --git a/com32/lib/sys/gpxe.c b/com32/lib/sys/gpxe.c index fae03f8f..d86da42a 100644 --- a/com32/lib/sys/gpxe.c +++ b/com32/lib/sys/gpxe.c @@ -7,39 +7,44 @@ bool is_gpxe(void) const struct syslinux_version *sv; com32sys_t reg; struct s_PXENV_FILE_CHECK_API *fca; + bool gpxe; sv = syslinux_version(); if (sv->filesystem != SYSLINUX_FS_PXELINUX) return false; /* Not PXELINUX */ - fca = __com32.cs_bounce; - memset(fca, 0, sizeof *fca); + fca = lzalloc(sizeof *fca); + if (!fca) + return false; fca->Size = sizeof *fca; fca->Magic = 0x91d447b2; memset(®, 0, sizeof reg); reg.eax.w[0] = 0x0009; reg.ebx.w[0] = 0x00e6; /* PXENV_FILE_API_CHECK */ - reg.edi.w[0] = OFFS(fca); + /* reg.edi.w[0] = OFFS(fca); */ reg.es = SEG(fca); __intcall(0x22, ®, ®); + gpxe = true; + if (reg.eflags.l & EFLAGS_CF) - return false; /* Cannot invoke PXE stack */ + gpxe = false; /* Cannot invoke PXE stack */ if (reg.eax.w[0] || fca->Status) - return false; /* PXE failure */ + gpxe = false; /* PXE failure */ if (fca->Magic != 0xe9c17b20) - return false; /* Incorrect magic */ + gpxe = false; /* Incorrect magic */ if (fca->Size < sizeof *fca) - return false; /* Short return */ + gpxe = false; /* Short return */ + /* XXX: The APIs to test for should be a passed-in option */ if (!(fca->APIMask & (1 << 5))) - return false; /* No FILE EXEC */ + gpxe = false; /* No FILE EXEC */ - return true; + lfree(fca); + return gpxe; } - diff --git a/com32/lib/sys/open.c b/com32/lib/sys/open.c index 0bd490c7..94465925 100644 --- a/com32/lib/sys/open.c +++ b/com32/lib/sys/open.c @@ -55,6 +55,7 @@ int open(const char *pathname, int flags, ...) com32sys_t regs; int fd; struct file_info *fp; + char *lm_pathname; fd = opendev(&__file_dev, NULL, flags); @@ -63,14 +64,18 @@ int open(const char *pathname, int flags, ...) fp = &__file_info[fd]; - strlcpy(__com32.cs_bounce, pathname, __com32.cs_bounce_size); + lm_pathname = lstrdup(pathname); + if (!lm_pathname) + return -1; regs.eax.w[0] = 0x0006; - regs.esi.w[0] = OFFS(__com32.cs_bounce); - regs.es = SEG(__com32.cs_bounce); + regs.esi.w[0] = OFFS(lm_pathname); + regs.es = SEG(lm_pathname); __com32.cs_intcall(0x22, ®s, ®s); + lfree(lm_pathname); + if ((regs.eflags.l & EFLAGS_CF) || regs.esi.w[0] == 0) { close(fd); errno = ENOENT; diff --git a/com32/lib/sys/vesa/initvesa.c b/com32/lib/sys/vesa/initvesa.c index 0a436f4c..9a1ae384 100644 --- a/com32/lib/sys/vesa/initvesa.c +++ b/com32/lib/sys/vesa/initvesa.c @@ -95,9 +95,13 @@ static int vesacon_set_mode(int x, int y) com32sys_t rm; uint8_t *rom_font; uint16_t mode, bestmode, *mode_ptr; + struct vesa_info *vi; struct vesa_general_info *gi; struct vesa_mode_info *mi; enum vesa_pixel_format pxf, bestpxf; + int err = 0; + + debug("Hello, World!\r\n"); /* Free any existing data structures */ if (__vesacon_background) { @@ -110,13 +114,15 @@ static int vesacon_set_mode(int x, int y) } /* Allocate space in the bounce buffer for these structures */ - gi = &((struct vesa_info *)__com32.cs_bounce)->gi; - mi = &((struct vesa_info *)__com32.cs_bounce)->mi; - - debug("Hello, World!\r\n"); + vi = lzalloc(sizeof *vi); + if (!vi) { + err = 10; /* Out of memory */ + goto exit; + } + gi = &vi->gi; + mi = &vi->mi; memset(&rm, 0, sizeof rm); - memset(gi, 0, sizeof *gi); gi->signature = VBE2_MAGIC; /* Get VBE2 extended data */ rm.eax.w[0] = 0x4F00; /* Get SVGA general information */ @@ -124,12 +130,18 @@ static int vesacon_set_mode(int x, int y) rm.es = SEG(gi); __intcall(0x10, &rm, &rm); - if (rm.eax.w[0] != 0x004F) - return 1; /* Function call failed */ - if (gi->signature != VESA_MAGIC) - return 2; /* No magic */ - if (gi->version < 0x0102) - return 3; /* VESA 1.2+ required */ + if (rm.eax.w[0] != 0x004F) { + err = 1; /* Function call failed */ + goto exit; + } + if (gi->signature != VESA_MAGIC) { + err = 2; /* No magic */ + goto exit; + } + if (gi->version < 0x0102) { + err = 3; /* VESA 1.2+ required */ + goto exit; + } /* Copy general info */ memcpy(&__vesa_info.gi, gi, sizeof *gi); @@ -232,8 +244,10 @@ static int vesacon_set_mode(int x, int y) } } - if (bestpxf == PXF_NONE) - return 4; /* No mode found */ + if (bestpxf == PXF_NONE) { + err = 4; /* No mode found */ + goto exit; + } mi = &__vesa_info.mi; mode = bestmode; @@ -260,8 +274,10 @@ static int vesacon_set_mode(int x, int y) mode |= 0x4000; /* Request linear framebuffer if supported */ rm.ebx.w[0] = mode; __intcall(0x10, &rm, &rm); - if (rm.eax.w[0] != 0x004F) - return 9; /* Failed to set mode */ + if (rm.eax.w[0] != 0x004F) { + err = 9; /* Failed to set mode */ + goto exit; + } __vesacon_background = calloc(mi->h_res*mi->v_res, 4); __vesacon_shadowfb = calloc(mi->h_res*mi->v_res, 4); @@ -279,7 +295,11 @@ static int vesacon_set_mode(int x, int y) __vesacon_pixel_format = bestpxf; - return 0; +exit: + if (vi) + lfree(vi); + + return err; } static int init_text_display(void) diff --git a/com32/lib/syslinux/memscan.c b/com32/lib/syslinux/memscan.c index 95580257..fc676cbf 100644 --- a/com32/lib/syslinux/memscan.c +++ b/com32/lib/syslinux/memscan.c @@ -51,7 +51,7 @@ int syslinux_scan_memory(scan_memory_callback_t callback, void *data) { static com32sys_t ireg; com32sys_t oreg; - struct e820_entry *e820buf = __com32.cs_bounce; + struct e820_entry *e820buf; uint64_t start, len, maxlen; int memfound = 0; int rv; @@ -74,13 +74,16 @@ int syslinux_scan_memory(scan_memory_callback_t callback, void *data) return rv; /* First try INT 15h AX=E820h */ + e820buf = lzalloc(sizeof *e820buf); + if (!e820buf) + return -1; + ireg.eax.l = 0xe820; ireg.edx.l = 0x534d4150; ireg.ebx.l = 0; ireg.ecx.l = sizeof(*e820buf); ireg.es = SEG(e820buf); ireg.edi.w[0] = OFFS(e820buf); - memset(e820buf, 0, sizeof *e820buf); do { __intcall(0x15, &ireg, &oreg); @@ -120,6 +123,8 @@ int syslinux_scan_memory(scan_memory_callback_t callback, void *data) ireg.ebx.l = oreg.ebx.l; } while (oreg.ebx.l); + lfree(e820buf); + if (memfound) return 0; diff --git a/com32/lib/syslinux/pxe_dns.c b/com32/lib/syslinux/pxe_dns.c index 9ab95137..6620396f 100644 --- a/com32/lib/syslinux/pxe_dns.c +++ b/com32/lib/syslinux/pxe_dns.c @@ -48,21 +48,26 @@ uint32_t pxe_dns(const char *hostname) unsigned char b[4]; uint32_t ip; } q; + char *lm_hostname; /* Is this a dot-quad? */ if (sscanf(hostname, "%hhu.%hhu.%hhu.%hhu", &q.b[0], &q.b[1], &q.b[2], &q.b[3]) == 4) return q.ip; + lm_hostname = lstrdup(hostname); + if (!lm_hostname) + return 0; + memset(®s, 0, sizeof regs); regs.eax.w[0] = 0x0010; - regs.es = SEG(__com32.cs_bounce); - regs.ebx.w[0] = OFFS(__com32.cs_bounce); - - strcpy((char *)__com32.cs_bounce, hostname); + regs.es = SEG(lm_hostname); + /* regs.ebx.w[0] = OFFS(lm_hostname); */ __intcall(0x22, ®s, ®s); + lfree(lm_hostname); + if (regs.eflags.l & EFLAGS_CF) return 0; diff --git a/com32/lib/syslinux/pxe_get_cached.c b/com32/lib/syslinux/pxe_get_cached.c index 2e8349fe..47040378 100644 --- a/com32/lib/syslinux/pxe_get_cached.c +++ b/com32/lib/syslinux/pxe_get_cached.c @@ -42,40 +42,55 @@ or -1 on invocation failure */ int pxe_get_cached_info(int level, void **buf, size_t * len) { + const int max_dhcp_packet = 2048; com32sys_t regs; - t_PXENV_GET_CACHED_INFO *gci = __com32.cs_bounce; + t_PXENV_GET_CACHED_INFO *gci; void *bbuf, *nbuf; + int err; + + gci = lmalloc(sizeof *gci + max_dhcp_packet); + if (!gci) + return -1; memset(®s, 0, sizeof regs); regs.eax.w[0] = 0x0009; regs.ebx.w[0] = PXENV_GET_CACHED_INFO; regs.es = SEG(gci); - regs.edi.w[0] = OFFS(gci); + /* regs.edi.w[0] = OFFS(gci); */ bbuf = &gci[1]; gci->Status = PXENV_STATUS_FAILURE; gci->PacketType = level; - gci->BufferSize = gci->BufferLimit = 65536 - sizeof(*gci); + gci->BufferSize = gci->BufferLimit = max_dhcp_packet; gci->Buffer.seg = SEG(bbuf); gci->Buffer.offs = OFFS(bbuf); __intcall(0x22, ®s, ®s); - if (regs.eflags.l & EFLAGS_CF) - return -1; + if (regs.eflags.l & EFLAGS_CF) { + err = -1; + goto exit; + } - if (gci->Status) - return gci->Status; + if (gci->Status) { + err = gci->Status; + goto exit; + } - nbuf = malloc(gci->BufferSize); /* malloc() does not use the bounce buffer */ - if (!nbuf) - return -1; + nbuf = malloc(gci->BufferSize); + if (!nbuf) { + err = -1; + goto exit; + } memcpy(nbuf, bbuf, gci->BufferSize); *buf = nbuf; *len = gci->BufferSize; + err = 0; - return 0; +exit: + lfree(gci); + return err; } diff --git a/com32/lib/syslinux/pxe_get_nic.c b/com32/lib/syslinux/pxe_get_nic.c index 704a0d79..b301a75a 100644 --- a/com32/lib/syslinux/pxe_get_nic.c +++ b/com32/lib/syslinux/pxe_get_nic.c @@ -40,19 +40,25 @@ /* Returns the status code from PXE (0 on success), or -1 on invocation failure */ -int pxe_get_nic_type(t_PXENV_UNDI_GET_NIC_TYPE * gnt) +int pxe_get_nic_type(t_PXENV_UNDI_GET_NIC_TYPE *gnt) { com32sys_t regs; + t_PXENV_UNDI_GET_NIC_TYPE *lgnt; + + lgnt = lzalloc(sizeof *lgnt); + if (!lgnt) + return -1; memset(®s, 0, sizeof regs); regs.eax.w[0] = 0x0009; regs.ebx.w[0] = PXENV_UNDI_GET_NIC_TYPE; - regs.es = SEG(__com32.cs_bounce); - regs.edi.w[0] = OFFS(__com32.cs_bounce); + regs.es = SEG(lgnt); + /* regs.edi.w[0] = OFFS(lgnt); */ __intcall(0x22, ®s, ®s); - memcpy(gnt, __com32.cs_bounce, sizeof(t_PXENV_UNDI_GET_NIC_TYPE)); + memcpy(gnt, lgnt, sizeof(t_PXENV_UNDI_GET_NIC_TYPE)); + lfree(lgnt); if (regs.eflags.l & EFLAGS_CF) return -1; diff --git a/com32/lib/syslinux/run_command.c b/com32/lib/syslinux/run_command.c index 4693e16d..a0ac9a0d 100644 --- a/com32/lib/syslinux/run_command.c +++ b/com32/lib/syslinux/run_command.c @@ -30,18 +30,21 @@ #include <string.h> #include <com32.h> -__noreturn syslinux_run_command(const char *command) +int syslinux_run_command(const char *command) { static com32sys_t ireg; + char *lm_command = lstrdup(command); - strcpy(__com32.cs_bounce, command); - + if (!lm_command) + return -1; + ireg.eax.w[0] = 0x0003; - ireg.es = SEG(__com32.cs_bounce); - ireg.ebx.w[0] = OFFS(__com32.cs_bounce); + ireg.es = SEG(lm_command); + /* ireg.ebx.w[0] = OFFS(lm_command); */ __intcall(0x22, &ireg, NULL); - /* Should not return even on failure */ - for (;;) ; + /* Should not return even on failure, but in case... */ + lfree(lm_command); + return -1; } diff --git a/com32/lib/syslinux/runimage.c b/com32/lib/syslinux/runimage.c index 0184df37..29e9aadd 100644 --- a/com32/lib/syslinux/runimage.c +++ b/com32/lib/syslinux/runimage.c @@ -40,26 +40,32 @@ void syslinux_run_kernel_image(const char *filename, const char *cmdline, uint32_t ipappend_flags, uint32_t type) { static com32sys_t ireg; - char *bbfilename, *bbcmdline, *bbptr; + char *bbfilename = NULL; + char *bbcmdline = NULL; int bytes; - bbptr = __com32.cs_bounce; + bbfilename = lstrdup(filename); + if (!bbfilename) + goto fail; - bytes = strlen(filename) + 1; - memcpy(bbfilename = bbptr, filename, bytes); - bbptr += bytes; + bbcmdline = lstrdup(cmdline); + if (!bbcmdline) + goto fail; - bytes = strlen(cmdline) + 1; - memcpy(bbcmdline = bbptr, filename, bytes); - bbptr += bytes; ireg.eax.w[0] = 0x0016; ireg.ds = SEG(bbfilename); - ireg.esi.w[0] = OFFS(bbfilename); + /* ireg.esi.w[0] = OFFS(bbfilename); */ ireg.es = SEG(bbcmdline); - ireg.ebx.w[0] = OFFS(bbcmdline); + /* ireg.ebx.w[0] = OFFS(bbcmdline); */ ireg.ecx.l = ipappend_flags; ireg.edx.l = type; __intcall(0x22, &ireg, 0); + +fail: + if (bbcmdline) + lfree(bbcmdline); + if (bbfilename) + lfree(bbfilename); } |