[syslinux:pathbased] com32: replace hard-coded bounce buffer use in com32/lib

syslinux-bot for H. Peter Anvin hpa at zytor.com
Wed Feb 24 14:21:20 PST 2010


Commit-ID:  8a4b35805fdc6651d288a3e1c2d98aa504cb9c05
Gitweb:     http://syslinux.zytor.com/commit/8a4b35805fdc6651d288a3e1c2d98aa504cb9c05
Author:     H. Peter Anvin <hpa at zytor.com>
AuthorDate: Wed, 24 Feb 2010 14:18:49 -0800
Committer:  H. Peter Anvin <hpa at zytor.com>
CommitDate: Wed, 24 Feb 2010 14:18:49 -0800

com32: replace hard-coded bounce buffer use in com32/lib

Replace hard-coded bounce buffer uses in com32/lib with lmalloc/lfree.

Signed-off-by: H. Peter Anvin <hpa at zytor.com>


---
 com32/include/syslinux/boot.h       |    2 +-
 com32/lib/opendir.c                 |   17 +++++++----
 com32/lib/sys/gpxe.c                |   25 ++++++++++-------
 com32/lib/sys/open.c                |   11 +++++--
 com32/lib/sys/vesa/initvesa.c       |   52 ++++++++++++++++++++++++-----------
 com32/lib/syslinux/memscan.c        |    9 +++++-
 com32/lib/syslinux/pxe_dns.c        |   13 ++++++---
 com32/lib/syslinux/pxe_get_cached.c |   37 +++++++++++++++++-------
 com32/lib/syslinux/pxe_get_nic.c    |   14 +++++++---
 com32/lib/syslinux/run_command.c    |   17 +++++++-----
 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 87c05e9..21bea01 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 c5e9aa0..e3c35ce 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 fae03f8..d86da42 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 0bd490c..9446592 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 0a436f4..9a1ae38 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 9558025..fc676cb 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 9ab9513..6620396 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 2e8349f..4704037 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 704a0d7..b301a75 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 4693e16..a0ac9a0 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 0184df3..29e9aad 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);
 }



More information about the Syslinux-commits mailing list