From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: X-Spam-Status: No, score=-4.2 required=3.0 tests=ALL_TRUSTED,AWL,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF, T_SCC_BODY_TEXT_LINE shortcircuit=no autolearn=ham autolearn_force=no version=3.4.6 Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id 7AEE01F461 for ; Mon, 27 Nov 2023 21:57:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=80x24.org; s=selector1; t=1701122234; bh=CaFL7pQ1DGRfftyk3uS5CWw3wMmtq79U3W+U9HYBLYs=; h=From:To:Subject:Date:In-Reply-To:References:From; b=UlUkIUYM6CJz9+qfWDWOaisBDrJwc24OvCZ/Q3tLoHtKJFcvZtsZxDv66uyoyH14I 3D1RZoLki7rHmywgZAUmFE9iOwUgrbZTXNK5rdl7uccQNvQmr6BohLm8xtIvnlmI76 MaJKWKQR4KRkNADOmUBNYovzR7IlzQa1+m3MKCEI= From: Eric Wong To: meta@public-inbox.org Subject: [PATCH 2/2] xap_helper.h: avoid some off_t vs size_t problems Date: Mon, 27 Nov 2023 21:54:39 +0000 Message-ID: <20231127215439.91487-3-e@80x24.org> In-Reply-To: <20231127215439.91487-1-e@80x24.org> References: <20231127215439.91487-1-e@80x24.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit List-Id: We'll introduce a helper to cast off_t to size_t consistently for mmap/munmap/calloc calls which require size_t. Also, an extra check for multiplication overflow can be helpful just in case we end up with a gigantic file roots file. --- lib/PublicInbox/xap_helper.h | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/lib/PublicInbox/xap_helper.h b/lib/PublicInbox/xap_helper.h index 1d8437c9..5816c24c 100644 --- a/lib/PublicInbox/xap_helper.h +++ b/lib/PublicInbox/xap_helper.h @@ -360,6 +360,13 @@ static void xclose(int fd) EABORT("BUG: close"); } +static size_t off2size(off_t n) +{ + if (n < 0 || (uintmax_t)n > SIZE_MAX) + ABORT("off_t out of size_t range: %lld\n", (long long)n); + return (size_t)n; +} + #define CLEANUP_DUMP_ROOTS __attribute__((__cleanup__(dump_roots_ensure))) static void dump_roots_ensure(void *ptr) { @@ -367,8 +374,9 @@ static void dump_roots_ensure(void *ptr) if (drt->root2off_fd >= 0) xclose(drt->root2off_fd); hdestroy(); // idempotent - if (drt->mm_ptr && munmap(drt->mm_ptr, drt->sb.st_size)) - EABORT("BUG: munmap(%p, %zu)", drt->mm_ptr, drt->sb.st_size); + size_t size = off2size(drt->sb.st_size); + if (drt->mm_ptr && munmap(drt->mm_ptr, size)) + EABORT("BUG: munmap(%p, %zu)", drt->mm_ptr, size); free(drt->entries); fbuf_ensure(&drt->wbuf); } @@ -516,20 +524,18 @@ static bool cmd_dump_roots(struct req *req) // each entry is at least 43 bytes ({OIDHEX}\0{INT}\0), // so /32 overestimates the number of expected entries by // ~%25 (as recommended by Linux hcreate(3) manpage) - size_t est = (drt.sb.st_size / 32) + 1; //+1 for "\0" termination - if ((uint64_t)drt.sb.st_size > (uint64_t)SIZE_MAX) - err(EXIT_FAILURE, "%s size too big (%lld bytes > %zu)", - root2off_file, (long long)drt.sb.st_size, SIZE_MAX); - drt.mm_ptr = mmap(NULL, drt.sb.st_size, PROT_READ, + size_t size = off2size(drt.sb.st_size); + size_t est = (size / 32) + 1; //+1 for "\0" termination + drt.mm_ptr = mmap(NULL, size, PROT_READ, MAP_PRIVATE, drt.root2off_fd, 0); if (drt.mm_ptr == MAP_FAILED) - err(EXIT_FAILURE, "mmap(%zu, %s)", - drt.sb.st_size, root2off_file); - drt.entries = (char **)calloc(est * 2, sizeof(char *)); + err(EXIT_FAILURE, "mmap(%zu, %s)", size, root2off_file); + size_t asize = est * 2; + if (asize < est) ABORT("too many entries: %zu", est); + drt.entries = (char **)calloc(asize, sizeof(char *)); if (!drt.entries) err(EXIT_FAILURE, "calloc(%zu * 2, %zu)", est, sizeof(char *)); - size_t tot = split2argv(drt.entries, (char *)drt.mm_ptr, - drt.sb.st_size, est * 2); + size_t tot = split2argv(drt.entries, (char *)drt.mm_ptr, size, asize); if (tot <= 0) return false; // split2argv already warned on error if (!hcreate(est)) err(EXIT_FAILURE, "hcreate(%zu)", est);