Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.bin/vndcompress Fix some more integer overflow/truncatio...



details:   https://anonhg.NetBSD.org/src/rev/ae20a75d43ce
branches:  trunk
changeset: 326314:ae20a75d43ce
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Sat Jan 25 15:31:06 2014 +0000

description:
Fix some more integer overflow/truncation issues.

Arithmetic in C is hard.  Let's go shopping!

diffstat:

 usr.bin/vndcompress/offtab.c        |  58 +++++++++++++++++++-----------------
 usr.bin/vndcompress/vndcompress.c   |  10 +++--
 usr.bin/vndcompress/vnduncompress.c |   7 ++-
 3 files changed, 40 insertions(+), 35 deletions(-)

diffs (194 lines):

diff -r 2be887533ff7 -r ae20a75d43ce usr.bin/vndcompress/offtab.c
--- a/usr.bin/vndcompress/offtab.c      Sat Jan 25 15:20:55 2014 +0000
+++ b/usr.bin/vndcompress/offtab.c      Sat Jan 25 15:31:06 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: offtab.c,v 1.10 2014/01/23 14:17:05 joerg Exp $        */
+/*     $NetBSD: offtab.c,v 1.11 2014/01/25 15:31:06 riastradh Exp $    */
 
 /*-
  * Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: offtab.c,v 1.10 2014/01/23 14:17:05 joerg Exp $");
+__RCSID("$NetBSD: offtab.c,v 1.11 2014/01/25 15:31:06 riastradh Exp $");
 
 #include <sys/types.h>
 #include <sys/endian.h>
@@ -104,28 +104,27 @@
        __CTASSERT(MAX_WINDOW_SIZE <= (SIZE_MAX / sizeof(uint64_t)));
        __CTASSERT(MAX_N_OFFSETS <= (OFF_MAX / sizeof(uint64_t)));
        assert(window_start < offtab->ot_n_offsets);
-       assert(offtab->ot_fdpos <=
-           (OFF_MAX - (off_t)(window_start * sizeof(uint64_t))));
+       const off_t window_offset = ((off_t)window_start *
+           (off_t)sizeof(uint64_t));
+       assert(offtab->ot_fdpos <= (OFF_MAX - window_offset));
+       const off_t window_pos = (offtab->ot_fdpos + window_offset);
        assert(ISSET(read_flags, OFFTAB_READ_SEEK) ||
            (lseek(offtab->ot_fd, 0, SEEK_CUR) == offtab->ot_fdpos) ||
            ((lseek(offtab->ot_fd, 0, SEEK_CUR) == -1) && (errno == ESPIPE)));
        const size_t n_req = (window_size * sizeof(uint64_t));
        const ssize_t n_read = (ISSET(read_flags, OFFTAB_READ_SEEK)
-           ? pread_block(offtab->ot_fd, offtab->ot_window, n_req,
-               (offtab->ot_fdpos + (window_start * sizeof(uint64_t))))
+           ? pread_block(offtab->ot_fd, offtab->ot_window, n_req, window_pos)
            : read_block(offtab->ot_fd, offtab->ot_window, n_req));
        if (n_read == -1) {
                (*offtab->ot_report)("read offset table at %"PRIuMAX,
-                   (uintmax_t)(offtab->ot_fdpos +
-                       (window_start * sizeof(uint64_t))));
+                   (uintmax_t)window_pos);
                return false;
        }
        assert(n_read >= 0);
        if ((size_t)n_read != (window_size * sizeof(uint64_t))) {
                (*offtab->ot_reportx)("partial read of offset table"
                    " at %"PRIuMAX": %zu != %zu",
-                   (uintmax_t)(offtab->ot_fdpos +
-                       (window_start * sizeof(uint64_t))),
+                   (uintmax_t)window_pos,
                    (size_t)n_read,
                    (size_t)(window_size * sizeof(uint64_t)));
                return false;
@@ -160,12 +159,13 @@
        __CTASSERT(MAX_WINDOW_SIZE <= (SIZE_MAX / sizeof(uint64_t)));
        __CTASSERT(MAX_N_OFFSETS <= (OFF_MAX / sizeof(uint64_t)));
        assert(offtab->ot_window_start < offtab->ot_n_offsets);
-       assert(offtab->ot_fdpos <=
-           (OFF_MAX - (off_t)(offtab->ot_window_start * sizeof(uint64_t))));
+       const off_t window_offset = ((off_t)offtab->ot_window_start *
+           (off_t)sizeof(uint64_t));
+       assert(offtab->ot_fdpos <= (OFF_MAX - window_offset));
+       const off_t window_pos = (offtab->ot_fdpos + window_offset);
        const ssize_t n_written = pwrite(offtab->ot_fd, offtab->ot_window,
            (window_size * sizeof(uint64_t)),
-           (offtab->ot_fdpos +
-               (offtab->ot_window_start * sizeof(uint64_t))));
+           window_pos);
        if (n_written == -1)
                err_ss(1, "write initial offset table");
        assert(n_written >= 0);
@@ -283,10 +283,10 @@
 
        if (offtab->ot_window_size < offtab->ot_n_offsets) {
                __CTASSERT(MAX_N_OFFSETS <= (OFF_MAX / sizeof(uint64_t)));
-               assert(offtab->ot_fdpos <= (OFF_MAX -
-                       (off_t)(offtab->ot_n_offsets * sizeof(uint64_t))));
-               const off_t first_offset = (offtab->ot_fdpos +
-                   (offtab->ot_n_offsets * sizeof(uint64_t)));
+               const off_t offtab_bytes = ((off_t)offtab->ot_n_offsets *
+                   (off_t)sizeof(uint64_t));
+               assert(offtab->ot_fdpos <= (OFF_MAX - offtab_bytes));
+               const off_t first_offset = (offtab->ot_fdpos + offtab_bytes);
                if (lseek(offtab->ot_fd, first_offset, SEEK_SET) == -1) {
                        (*offtab->ot_report)("lseek to first offset 0x%"PRIx64,
                            first_offset);
@@ -371,13 +371,15 @@
        }
 
        offtab->ot_window_start = 0;
-       __CTASSERT(MAX_N_OFFSETS <= (OFF_MAX / sizeof(uint64_t)));
+       __CTASSERT(MAX_N_OFFSETS <=
+           (MIN(OFF_MAX, UINT64_MAX) / sizeof(uint64_t)));
+       const off_t offtab_bytes = ((off_t)offtab->ot_n_offsets *
+           sizeof(uint64_t));
        assert(offtab->ot_fdpos <=
-           (OFF_MAX - (off_t)(offtab->ot_n_offsets * sizeof(uint64_t))));
-       const uint64_t first_offset = (offtab->ot_fdpos +
-           (offtab->ot_n_offsets * sizeof(uint64_t)));
-       assert(first_offset <= OFF_MAX);
-       offtab->ot_window[0] = htobe64(first_offset);
+           ((off_t)MIN(OFF_MAX, UINT64_MAX) - offtab_bytes));
+       const off_t first_offset = (offtab->ot_fdpos + offtab_bytes);
+       assert(first_offset <= (off_t)MIN(OFF_MAX, UINT64_MAX));
+       offtab->ot_window[0] = htobe64((uint64_t)first_offset);
        offtab_write_window(offtab);
 
        if (lseek(offtab->ot_fd, first_offset, SEEK_SET) == -1)
@@ -412,11 +414,11 @@
 
        if (ISSET(flags, OFFTAB_CHECKPOINT_SYNC)) {
                __CTASSERT(MAX_N_OFFSETS <= (OFF_MAX / sizeof(uint64_t)));
-               assert(offtab->ot_fdpos
-                   <= (OFF_MAX - (off_t)(n_offsets * sizeof(uint64_t))));
+               const off_t sync_bytes = ((off_t)n_offsets *
+                   (off_t)sizeof(uint64_t));
+               assert(offtab->ot_fdpos <= (OFF_MAX - sync_bytes));
                if (fsync_range(offtab->ot_fd, (FFILESYNC | FDISKSYNC),
-                       offtab->ot_fdpos,
-                       (offtab->ot_fdpos + (n_offsets * sizeof(uint64_t))))
+                       offtab->ot_fdpos, (offtab->ot_fdpos + sync_bytes))
                    == -1)
                        warn_ss("fsync of offset table failed");
        }
diff -r 2be887533ff7 -r ae20a75d43ce usr.bin/vndcompress/vndcompress.c
--- a/usr.bin/vndcompress/vndcompress.c Sat Jan 25 15:20:55 2014 +0000
+++ b/usr.bin/vndcompress/vndcompress.c Sat Jan 25 15:31:06 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: vndcompress.c,v 1.23 2014/01/24 17:30:18 christos Exp $        */
+/*     $NetBSD: vndcompress.c,v 1.24 2014/01/25 15:31:06 riastradh Exp $       */
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: vndcompress.c,v 1.23 2014/01/24 17:30:18 christos Exp $");
+__RCSID("$NetBSD: vndcompress.c,v 1.24 2014/01/25 15:31:06 riastradh Exp $");
 
 #include <sys/endian.h>
 
@@ -307,10 +307,12 @@
        const uint64_t nread = ((uint64_t)S->blkno * (uint64_t)S->blocksize);
 
        assert(S->n_blocks > 0);
+       __CTASSERT(CLOOP2_OFFSET_TABLE_OFFSET <=
+           (UINT64_MAX / sizeof(uint64_t)));
        __CTASSERT(MAX_N_BLOCKS <= ((UINT64_MAX / sizeof(uint64_t)) -
                CLOOP2_OFFSET_TABLE_OFFSET));
        const uint64_t nwritten = (S->offset <= (CLOOP2_OFFSET_TABLE_OFFSET +
-               (S->n_blocks * sizeof(uint64_t)))?
+               ((uint64_t)S->n_blocks * sizeof(uint64_t)))?
            0 : S->offset);
 
        /* snprintf_ss can't do floating-point, so do fixed-point instead.  */
@@ -533,7 +535,7 @@
        /* Start at the beginning of the image.  */
        S->blkno = 0;
        S->offset = (sizeof(struct cloop2_header) +
-           (S->n_offsets * sizeof(uint64_t)));
+           ((uint64_t)S->n_offsets * sizeof(uint64_t)));
        S->n_checkpointed_blocks = 0;
 
        /* Good to go and ready for interruption by a signal.  */
diff -r 2be887533ff7 -r ae20a75d43ce usr.bin/vndcompress/vnduncompress.c
--- a/usr.bin/vndcompress/vnduncompress.c       Sat Jan 25 15:20:55 2014 +0000
+++ b/usr.bin/vndcompress/vnduncompress.c       Sat Jan 25 15:31:06 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: vnduncompress.c,v 1.10 2014/01/22 06:18:00 riastradh Exp $     */
+/*     $NetBSD: vnduncompress.c,v 1.11 2014/01/25 15:31:06 riastradh Exp $     */
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: vnduncompress.c,v 1.10 2014/01/22 06:18:00 riastradh Exp $");
+__RCSID("$NetBSD: vnduncompress.c,v 1.11 2014/01/25 15:31:06 riastradh Exp $");
 
 #include <sys/endian.h>
 
@@ -158,7 +158,8 @@
        __CTASSERT(sizeof(header) <=
            (OFF_MAX - (MAX_N_OFFSETS * sizeof(uint64_t))));
        __CTASSERT(OFF_MAX <= UINT64_MAX);
-       uint64_t offset = (sizeof(header) + (n_offsets * sizeof(uint64_t)));
+       uint64_t offset = (sizeof(header) +
+           ((uint64_t)n_offsets * sizeof(uint64_t)));
        uint32_t blkno;
        (void)offtab_prepare_get(&offtab, 0);
        uint64_t last = offtab_get(&offtab, 0);



Home | Main Index | Thread Index | Old Index