summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2010-02-24 14:18:49 -0800
committerH. Peter Anvin <hpa@zytor.com>2010-02-24 14:18:49 -0800
commit8a4b35805fdc6651d288a3e1c2d98aa504cb9c05 (patch)
tree37c4bdef99996ab681e03c7a3f407563a9ff35d7
parent3ae1da98a68d2f719ce17766550f7e9682ba8ae7 (diff)
downloadsyslinux-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.h2
-rw-r--r--com32/lib/opendir.c17
-rw-r--r--com32/lib/sys/gpxe.c25
-rw-r--r--com32/lib/sys/open.c11
-rw-r--r--com32/lib/sys/vesa/initvesa.c52
-rw-r--r--com32/lib/syslinux/memscan.c9
-rw-r--r--com32/lib/syslinux/pxe_dns.c13
-rw-r--r--com32/lib/syslinux/pxe_get_cached.c37
-rw-r--r--com32/lib/syslinux/pxe_get_nic.c14
-rw-r--r--com32/lib/syslinux/run_command.c17
-rw-r--r--com32/lib/syslinux/runimage.c26
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, &regs, &regs);
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(&reg, 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, &reg, &reg);
+ 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, &regs, &regs);
+ 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(&regs, 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, &regs, &regs);
+ 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(&regs, 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, &regs, &regs);
- 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(&regs, 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, &regs, &regs);
- 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);
}