tdb: add overflow/ENOSPC handling to tdb_expand_file()
authorStefan Metzmacher <metze@samba.org>
Tue, 28 May 2013 10:59:32 +0000 (12:59 +0200)
committerVolker Lendecke <vl@samba.org>
Mon, 3 Jun 2013 08:21:27 +0000 (10:21 +0200)
Pair-Programmed-With: Volker Lendecke <vl@samba.org>

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Rusty Russell <rusty@rustcorp.com.au>
lib/tdb/common/io.c

index 44ef7289a6395c10a64ec3cfb9b12e2587b261d6..d17764008f613be9111411427d70f25c9a2dbf26 100644 (file)
@@ -294,7 +294,14 @@ static int tdb_expand_file(struct tdb_context *tdb, tdb_off_t size, tdb_off_t ad
                return -1;
        }
 
-       new_size = size + addition;
+       if (!tdb_add_off_t(size, addition, &new_size)) {
+               tdb->ecode = TDB_ERR_OOM;
+               TDB_LOG((tdb, TDB_DEBUG_FATAL, "expand_file write "
+                       "overflow detected current size[%u] addition[%u]!\n",
+                       (unsigned)size, (unsigned)addition));
+               errno = ENOSPC;
+               return -1;
+       }
 
        if (ftruncate(tdb->fd, new_size) == -1) {
                char b = 0;
@@ -308,6 +315,7 @@ static int tdb_expand_file(struct tdb_context *tdb, tdb_off_t size, tdb_off_t ad
                        errno = ENOSPC;
                }
                if (written != 1) {
+                       tdb->ecode = TDB_ERR_OOM;
                        TDB_LOG((tdb, TDB_DEBUG_FATAL, "expand_file to %u failed (%s)\n",
                                 (unsigned)new_size, strerror(errno)));
                        return -1;
@@ -327,12 +335,14 @@ static int tdb_expand_file(struct tdb_context *tdb, tdb_off_t size, tdb_off_t ad
                }
                if (written == 0) {
                        /* give up, trying to provide a useful errno */
+                       tdb->ecode = TDB_ERR_OOM;
                        TDB_LOG((tdb, TDB_DEBUG_FATAL, "expand_file write "
                                "returned 0 twice: giving up!\n"));
                        errno = ENOSPC;
                        return -1;
                }
                if (written == -1) {
+                       tdb->ecode = TDB_ERR_OOM;
                        TDB_LOG((tdb, TDB_DEBUG_FATAL, "expand_file write of "
                                 "%u bytes failed (%s)\n", (int)n,
                                 strerror(errno)));