libdvbv5: better handle memory errors
authorMauro Carvalho Chehab <m.chehab@samsung.com>
Fri, 15 Nov 2013 12:29:54 +0000 (10:29 -0200)
committerMauro Carvalho Chehab <m.chehab@samsung.com>
Wed, 27 Nov 2013 11:24:16 +0000 (09:24 -0200)
Avoid the risk of filling past of the buffers, by checking i
are there any space available before filling the buffers.

Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
lib/libdvbv5/descriptors.c
lib/libdvbv5/descriptors/nit.c

index 2ad138b..9790348 100644 (file)
@@ -92,6 +92,7 @@ void dvb_parse_descriptors(struct dvb_v5_fe_parms *parms, const uint8_t *buf, ui
                int desc_type = ptr[0];
                int desc_len  = ptr[1];
                size_t size;
+
                dvb_desc_init_func init = dvb_descriptors[desc_type].init;
                if (!init) {
                        init = dvb_desc_default_init;
@@ -103,8 +104,14 @@ void dvb_parse_descriptors(struct dvb_v5_fe_parms *parms, const uint8_t *buf, ui
                        dvb_logerr("descriptor type %d has no size defined", current->type);
                        size = 4096;
                }
-               current = (struct dvb_desc *) malloc(size);
+               current = malloc(size);
+               if (!current)
+                       dvb_perror("Out of memory");
                ptr += dvb_desc_init(ptr, current); /* the standard header was read */
+               if (ptr >=  buf + section_length) {
+                       dvb_logerr("descriptor is truncated");
+                       return;
+               }
                init(parms, ptr, current);
                if(!*head_desc)
                        *head_desc = current;
index f0e7714..d32be0b 100644 (file)
@@ -44,7 +44,11 @@ void dvb_table_nit_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf, ssize
                desc_length = t->desc_length;
 
        } else {
-               memcpy(table, p, sizeof(struct dvb_table_nit) - sizeof(nit->descriptor) - sizeof(nit->transport));
+               if (buflen < offsetof(struct dvb_table_nit, descriptor)) {
+                       dvb_logerr("NIT table was truncated");
+                       return;
+               }
+               memcpy(table, p, offsetof(struct dvb_table_nit, descriptor));
                *table_length = sizeof(struct dvb_table_nit);
 
                bswap16(nit->bitfield);
@@ -54,8 +58,11 @@ void dvb_table_nit_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf, ssize
                head = &nit->transport;
                desc_length = nit->desc_length;
        }
-       p += sizeof(struct dvb_table_nit) - sizeof(nit->descriptor) - sizeof(nit->transport);
-
+       p += offsetof(struct dvb_table_nit, descriptor);
+       if (buflen - (p - buf) < desc_length) {
+               dvb_logerr("NIT table was truncated");
+               return;
+       }
        dvb_parse_descriptors(parms, p, desc_length, head_desc);
        p += desc_length;
 
@@ -63,9 +70,11 @@ void dvb_table_nit_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf, ssize
 
        struct dvb_table_nit_transport *last = NULL;
        while ((uint8_t *) p < buf + buflen - 4) {
-               struct dvb_table_nit_transport *transport = (struct dvb_table_nit_transport *) malloc(sizeof(struct dvb_table_nit_transport));
-               memcpy(transport, p, sizeof(struct dvb_table_nit_transport) - sizeof(transport->descriptor) - sizeof(transport->next));
-               p += sizeof(struct dvb_table_nit_transport) - sizeof(transport->descriptor) - sizeof(transport->next);
+               struct dvb_table_nit_transport *transport = malloc(sizeof(struct dvb_table_nit_transport));
+               if (!transport)
+                       dvb_perror("Out of memory");
+               memcpy(transport, p, offsetof(struct dvb_table_nit_transport, descriptor));
+               p += offsetof(struct dvb_table_nit_transport, descriptor);
 
                bswap16(transport->transport_id);
                bswap16(transport->network_id);