[PATCH 5] Fix error handling with malloc, memalign etc. Memalign() can't fail now.

Krzysztof Halasa khc at pm.waw.pl
Mon Dec 20 17:54:49 EST 2010


Fix error handling with malloc, memalign etc. Memalign() can't fail now.

The idea is to panic() when there is no memory available for normal
operation. Exception: code which can consume arbitrary amount of RAM
(example: files allocated in ramfs) must report error instead of
panic().

This patch also fixes code which didn't check for NULL from malloc()
etc.

Usage: malloc() returns NULL when out of RAM.
xmalloc(), memalign() always return non-NULL or panic().

Signed-off-by: Krzysztof Hałasa <khc at pm.waw.pl>

diff --git a/arch/arm/cpu/mmu.c b/arch/arm/cpu/mmu.c
index 08a57ce..fbaf627 100644
--- a/arch/arm/cpu/mmu.c
+++ b/arch/arm/cpu/mmu.c
@@ -95,13 +95,7 @@ void setup_dma_coherent(unsigned long offset)
 
 void *dma_alloc_coherent(size_t size)
 {
-	void *mem;
-
-	mem = memalign(4096, size);
-	if (mem)
-		return mem + dma_coherent_offset;
-
-	return NULL;
+	return memalign(4096, size) + dma_coherent_offset;
 }
 
 unsigned long virt_to_phys(void *virt)
diff --git a/arch/arm/include/asm/mmu.h b/arch/arm/include/asm/mmu.h
index fdd23b5..7789cc9 100644
--- a/arch/arm/include/asm/mmu.h
+++ b/arch/arm/include/asm/mmu.h
@@ -28,7 +28,7 @@ void *phys_to_virt(unsigned long phys);
 #else
 static inline void *dma_alloc_coherent(size_t size)
 {
-	return malloc(size);
+	return xmalloc(size);
 }
 
 static inline void dma_free_coherent(void *mem)
diff --git a/arch/sandbox/os/common.c b/arch/sandbox/os/common.c
index 287be0d..8409ca8 100644
--- a/arch/sandbox/os/common.c
+++ b/arch/sandbox/os/common.c
@@ -223,10 +223,7 @@ static int add_image(char *str, char *name)
 	struct stat s;
 	char *opt;
 	int fd, ret;
-	struct hf_platform_data *hf = malloc(sizeof(struct hf_platform_data));
-
-	if (!hf)
-		return -1;
+	struct hf_platform_data *hf = xmalloc(sizeof(struct hf_platform_data));
 
 	file = strtok(str, ",");
 	while ((opt = strtok(NULL, ","))) {
@@ -285,11 +282,7 @@ int main(int argc, char *argv[])
 	char str[6];
 	int fdno = 0, envno = 0;
 
-	ram = malloc(malloc_size);
-	if (!ram) {
-		printf("unable to get malloc space\n");
-		exit(1);
-	}
+	ram = xmalloc(malloc_size);
 	mem_malloc_init(ram, ram + malloc_size);
 
 	while (1) {
diff --git a/commands/edit.c b/commands/edit.c
index ca40d59..3519b09 100644
--- a/commands/edit.c
+++ b/commands/edit.c
@@ -184,10 +184,8 @@ static struct line *line_realloc(int len, struct line *line)
 {
 	int size = 32;
 
-	if (!line) {
+	if (!line)
 		line = xzalloc(sizeof(struct line));
-		line->data = malloc(32);
-	}
 
 	while (size < len)
 		size <<= 1;
diff --git a/common/dlmalloc.c b/common/dlmalloc.c
index ff63fbe..383c1d8 100644
--- a/common/dlmalloc.c
+++ b/common/dlmalloc.c
@@ -1,9 +1,9 @@
-
+#include <common.h>
 #include <config.h>
 #include <malloc.h>
 #include <string.h>
 #include <mem_malloc.h>
-
+#include <xfuncs.h>
 #include <stdio.h>
 #include <module.h>
 
@@ -1696,12 +1696,12 @@ void *memalign(size_t alignment, size_t bytes)
 	long remainder_size;	/* its size */
 
 	if ((long) bytes < 0)
-		return NULL;
+		panic("memalign: requested %i bytes\n", bytes);
 
 	/* If need less alignment than we give anyway, just relay to malloc */
 
 	if (alignment <= MALLOC_ALIGNMENT)
-		return malloc(bytes);
+		return xmalloc(bytes);
 
 	/* Otherwise, ensure that it is at least a minimum chunk size */
 
@@ -1711,10 +1711,7 @@ void *memalign(size_t alignment, size_t bytes)
 	/* Call malloc with worst case padding to hit alignment. */
 
 	nb = request2size(bytes);
-	m = (char*)(malloc (nb + alignment + MINSIZE));
-
-	if (!m)
-		return NULL;	/* propagate failure */
+	m = (char*)(xmalloc(nb + alignment + MINSIZE));
 
 	p = mem2chunk(m);
 
diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index 717fea5..9d52beb 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -116,9 +116,7 @@ struct clk_lookup *clkdev_alloc(struct clk *clk, const char *con_id,
 {
 	struct clk_lookup_alloc *cla;
 
-	cla = kzalloc(sizeof(*cla), GFP_KERNEL);
-	if (!cla)
-		return NULL;
+	cla = xzalloc(sizeof(*cla), GFP_KERNEL);
 
 	cla->cl.clk = clk;
 	if (con_id) {
@@ -150,8 +148,6 @@ int clk_add_alias(const char *alias, const char *alias_dev_name, char *id,
 
 	l = clkdev_alloc(r, alias, alias_dev_name);
 	clk_put(r);
-	if (!l)
-		return -ENODEV;
 	clkdev_add(l);
 	return 0;
 }
diff --git a/drivers/mci/mci-core.c b/drivers/mci/mci-core.c
index 04a1e4c..f1bfba7 100644
--- a/drivers/mci/mci-core.c
+++ b/drivers/mci/mci-core.c
@@ -1334,9 +1334,6 @@ static struct driver_d mci_driver = {
 static int mci_init(void)
 {
 	sector_buf = memalign(32, 512);
-	if (!sector_buf)
-		return -ENOMEM;
-
 	return register_driver(&mci_driver);
 }
 
diff --git a/drivers/net/at91_ether.c b/drivers/net/at91_ether.c
index 4563ff3..d5e26a1 100644
--- a/drivers/net/at91_ether.c
+++ b/drivers/net/at91_ether.c
@@ -263,7 +263,7 @@ static int at91rm9200_eth_init (struct device_d *dev)
 	struct eth_device *edev;
 	int i;
 
-	edev = malloc(sizeof(struct eth_device));
+	edev = xmalloc(sizeof(struct eth_device));
 	dev->priv = edev;
 
 	edev->open = at91rm9200_eth_open;
diff --git a/drivers/net/cs8900.c b/drivers/net/cs8900.c
index 8120877..187c0fb 100644
--- a/drivers/net/cs8900.c
+++ b/drivers/net/cs8900.c
@@ -440,14 +440,14 @@ static int cs8900_probe(struct device_d *dev)
 
 	debug("cs8900_init()\n");
 
-	priv = (struct cs8900_priv *)malloc(sizeof(*priv));
+	priv = (struct cs8900_priv *)xmalloc(sizeof(*priv));
 	priv->regs = (u16 *)dev->map_base;
 	if (cs8900_check_id(priv)) {
 		free(priv);
 		return -1;
 	}
 
-	edev = (struct eth_device *)malloc(sizeof(struct eth_device));
+	edev = (struct eth_device *)xmalloc(sizeof(struct eth_device));
 	dev->type_data = edev;
 	edev->priv = priv;
 
diff --git a/drivers/net/fec_mpc5200.c b/drivers/net/fec_mpc5200.c
index 8b2cb4d..7528316 100644
--- a/drivers/net/fec_mpc5200.c
+++ b/drivers/net/fec_mpc5200.c
@@ -661,9 +661,9 @@ int mpc5xxx_fec_probe(struct device_d *dev)
         struct eth_device *edev;
 	mpc5xxx_fec_priv *fec;
 
-        edev = (struct eth_device *)malloc(sizeof(struct eth_device));
+        edev = (struct eth_device *)xmalloc(sizeof(struct eth_device));
         dev->type_data = edev;
-	fec = (mpc5xxx_fec_priv *)malloc(sizeof(*fec));
+	fec = (mpc5xxx_fec_priv *)xmalloc(sizeof(*fec));
         edev->priv = fec;
 	edev->open = mpc5xxx_fec_open,
 	edev->init = mpc5xxx_fec_init,
diff --git a/drivers/net/tap.c b/drivers/net/tap.c
index 522a9f1..a30a9c8 100644
--- a/drivers/net/tap.c
+++ b/drivers/net/tap.c
@@ -79,7 +79,7 @@ int tap_probe(struct device_d *dev)
 	struct tap_priv *priv;
 	int ret = 0;
 
-	priv = malloc(sizeof(struct tap_priv));
+	priv = xmalloc(sizeof(struct tap_priv));
 	priv->name = "barebox";
 
 	priv->fd = tap_alloc(priv->name);
@@ -88,7 +88,7 @@ int tap_probe(struct device_d *dev)
 		goto out;
 	}
 
-	edev = malloc(sizeof(struct eth_device));
+	edev = xmalloc(sizeof(struct eth_device));
 	dev->type_data = edev;
 	edev->priv = priv;
 
diff --git a/drivers/nor/cfi_flash.c b/drivers/nor/cfi_flash.c
index 4af0370..f7eeb2a 100644
--- a/drivers/nor/cfi_flash.c
+++ b/drivers/nor/cfi_flash.c
@@ -326,7 +326,7 @@ static ulong flash_get_size (struct flash_info *info, ulong base)
 #endif
 
 	/* first only malloc space for the first sector */
-	info->start = malloc(sizeof(ulong));
+	info->start = xmalloc(sizeof(ulong));
 
 	info->start[0] = base;
 	info->protect = 0;
@@ -415,8 +415,8 @@ static ulong flash_get_size (struct flash_info *info, ulong base)
 			cur_offset += erase_region_size * erase_region_count;
 
 			/* increase the space malloced for the sector start addresses */
-			info->start = realloc(info->start, sizeof(ulong) * (erase_region_count + sect_cnt));
-			info->protect = realloc(info->protect, sizeof(uchar) * (erase_region_count + sect_cnt));
+			info->start = xrealloc(info->start, sizeof(ulong) * (erase_region_count + sect_cnt));
+			info->protect = xrealloc(info->protect, sizeof(uchar) * (erase_region_count + sect_cnt));
 
 			for (j = 0; j < erase_region_count; j++) {
 				info->start[sect_cnt] = sector;
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c
index bc9b0de..442dbc4 100644
--- a/drivers/serial/amba-pl011.c
+++ b/drivers/serial/amba-pl011.c
@@ -157,8 +157,7 @@ static int pl011_probe(struct device_d *dev)
 	struct amba_uart_port *uart;
 	struct console_device *cdev;
 
-	uart = malloc(sizeof(struct amba_uart_port));
-
+	uart = xmalloc(sizeof(struct amba_uart_port));
 	uart->clk = clk_get(dev, NULL);
 
 	if (IS_ERR(uart->clk))
diff --git a/drivers/serial/atmel.c b/drivers/serial/atmel.c
index b99ec4d..1098952 100644
--- a/drivers/serial/atmel.c
+++ b/drivers/serial/atmel.c
@@ -398,8 +398,7 @@ static int atmel_serial_probe(struct device_d *dev)
 	struct atmel_uart_port *uart;
 	struct console_device *cdev;
 
-	uart = malloc(sizeof(struct atmel_uart_port));
-
+	uart = xmalloc(sizeof(struct atmel_uart_port));
 	cdev = &uart->uart;
 	dev->type_data = cdev;
 	cdev->dev = dev;
diff --git a/drivers/serial/serial_blackfin.c b/drivers/serial/serial_blackfin.c
index 2101b7e..59b2fbb 100644
--- a/drivers/serial/serial_blackfin.c
+++ b/drivers/serial/serial_blackfin.c
@@ -115,7 +115,7 @@ static int blackfin_serial_probe(struct device_d *dev)
 {
 	struct console_device *cdev;
 
-	cdev = malloc(sizeof(struct console_device));
+	cdev = xmalloc(sizeof(struct console_device));
 	dev->type_data = cdev;
 	cdev->dev = dev;
 	cdev->f_caps = CONSOLE_STDIN | CONSOLE_STDOUT | CONSOLE_STDERR;
diff --git a/drivers/serial/serial_imx.c b/drivers/serial/serial_imx.c
index a7562f9..984d7f2 100644
--- a/drivers/serial/serial_imx.c
+++ b/drivers/serial/serial_imx.c
@@ -319,7 +319,7 @@ static int imx_serial_probe(struct device_d *dev)
 	struct imx_serial_priv *priv;
 	uint32_t val;
 
-	priv = malloc(sizeof(*priv));
+	priv = xmalloc(sizeof(*priv));
 	cdev = &priv->cdev;
 
 	priv->regs = (void __force __iomem *)dev->map_base;
diff --git a/drivers/serial/serial_netx.c b/drivers/serial/serial_netx.c
index 7c09519..9d4b29e 100644
--- a/drivers/serial/serial_netx.c
+++ b/drivers/serial/serial_netx.c
@@ -140,7 +140,7 @@ static int netx_serial_probe(struct device_d *dev)
 {
 	struct console_device *cdev;
 
-	cdev = malloc(sizeof(struct console_device));
+	cdev = xmalloc(sizeof(struct console_device));
 	dev->type_data = cdev;
 	cdev->dev = dev;
 	cdev->f_caps = CONSOLE_STDIN | CONSOLE_STDOUT | CONSOLE_STDERR;
diff --git a/drivers/serial/serial_pl010.c b/drivers/serial/serial_pl010.c
index 1a6366f..7923ebb 100644
--- a/drivers/serial/serial_pl010.c
+++ b/drivers/serial/serial_pl010.c
@@ -141,7 +141,7 @@ static int pl010_probe(struct device_d *dev)
 {
 	struct console_device *cdev;
 
-	cdev = malloc(sizeof(struct console_device));
+	cdev = xmalloc(sizeof(struct console_device));
 	dev->type_data = cdev;
 	cdev->dev = dev;
 	cdev->f_caps = CONSOLE_STDIN | CONSOLE_STDOUT | CONSOLE_STDERR;
diff --git a/drivers/serial/serial_s3c24x0.c b/drivers/serial/serial_s3c24x0.c
index d7eac8f..0a17967 100644
--- a/drivers/serial/serial_s3c24x0.c
+++ b/drivers/serial/serial_s3c24x0.c
@@ -121,8 +121,7 @@ static int s3c24x0_serial_probe(struct device_d *dev)
 {
 	struct console_device *cdev;
 
-	cdev = malloc(sizeof(struct console_device));
-
+	cdev = xmalloc(sizeof(struct console_device));
 	dev->type_data = cdev;
 	cdev->dev = dev;
 	cdev->f_caps = CONSOLE_STDIN | CONSOLE_STDOUT | CONSOLE_STDERR;
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index 978fdd1..fd70e62 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -903,9 +903,6 @@ static int __init composite_bind(struct usb_gadget *gadget)
 	int				status = -ENOMEM;
 
 	cdev = xzalloc(sizeof *cdev);
-	if (!cdev)
-		return status;
-
 	cdev->gadget = gadget;
 	set_gadget_data(gadget, cdev);
 	INIT_LIST_HEAD(&cdev->configs);
diff --git a/drivers/usb/gadget/fsl_udc.c b/drivers/usb/gadget/fsl_udc.c
index 48fd0b5..20a5064 100644
--- a/drivers/usb/gadget/fsl_udc.c
+++ b/drivers/usb/gadget/fsl_udc.c
@@ -1016,8 +1016,6 @@ fsl_alloc_request(struct usb_ep *_ep)
 	struct fsl_req *req;
 
 	req = xzalloc(sizeof *req);
-	if (!req)
-		return NULL;
 
 	INIT_LIST_HEAD(&req->queue);
 
@@ -2095,7 +2093,7 @@ static int struct_udc_setup(struct fsl_udc *udc,
 	udc->status_req = container_of(fsl_alloc_request(NULL),
 			struct fsl_req, req);
 	/* allocate a small amount of memory to get valid address */
-	udc->status_req->req.buf = kmalloc(8, GFP_KERNEL);
+	udc->status_req->req.buf = xmalloc(8);
 	udc->resume_state = USB_STATE_NOTATTACHED;
 	udc->usb_state = USB_STATE_POWERED;
 	udc->ep0_dir = 0;
diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c
index cb65b19..edcb3f2 100644
--- a/drivers/usb/gadget/u_serial.c
+++ b/drivers/usb/gadget/u_serial.c
@@ -206,10 +206,6 @@ gs_alloc_req(struct usb_ep *ep, unsigned len)
 	if (req != NULL) {
 		req->length = len;
 		req->buf = memalign(32, len);
-		if (req->buf == NULL) {
-			usb_ep_free_request(ep, req);
-			return NULL;
-		}
 	}
 
 	return req;
diff --git a/scripts/basic/docproc.c b/scripts/basic/docproc.c
index 0d4f5e7..9f6535d 100644
--- a/scripts/basic/docproc.c
+++ b/scripts/basic/docproc.c
@@ -122,8 +122,11 @@ int symfilecnt = 0;
 
 void add_new_symbol(struct symfile *sym, char * symname)
 {
-	sym->symbollist =
-          realloc(sym->symbollist, (sym->symbolcnt + 1) * sizeof(char *));
+	sym->symbollist = realloc(sym->symbollist, (sym->symbolcnt + 1) * sizeof(char *));
+	if (!sym->symbollist) {
+		fprintf(stderr, "docproc: out of memory\n");
+		exit(1);
+	}
 	sym->symbollist[sym->symbolcnt++].name = strdup(symname);
 }
 
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 4075c35..08b75b6 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -1317,7 +1317,7 @@ void buf_write(struct buffer *buf, const char *s, int len)
 {
 	if (buf->size - buf->pos < len) {
 		buf->size += len + SZ;
-		buf->p = realloc(buf->p, buf->size);
+		buf->p = NOFAIL(realloc(buf->p, buf->size));
 	}
 	strncpy(buf->p + buf->pos, s, len);
 	buf->pos += len;



More information about the barebox mailing list