From nobody Wed Nov 29 21:49:55 2023 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4SgXzl3j6wz52JBQ; Wed, 29 Nov 2023 21:49:55 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4SgXzl3CKRz4mjD; Wed, 29 Nov 2023 21:49:55 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1701294595; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=ow0kkl59qs/eODsDObjGOIjiAE1tlQmwevgzg+bOQr0=; b=InDZ62NoJd4EnOefWjOQ+II2AgDreycTdYJmiKBQeGR8L3rCZTkOP3GBgRzxY+S7uqQxQ1 sR7VgruhkAVuFrvEm9olakiVNopO6m/SjKMus6kKW2c965ahHea22vrDUfuP6ahxuiVgUP qjwqnbZs/EpsKeo0J3xhpsgvVBQ3QCPKiDoe3Keh4R8yuADEoH7xprDqNVom7tg8dP33Gd gHyyGWXv0kOZBVlUw5kq3uxlP5LRL6tnC6M+ZyXFJDlD1rV+mSwocjloHwsw6PPqMPb1Ee zo5oTMZNLoRuUFvrIGYDdnC8TK/Suq8BUyFZOb8HdIDDspgMqooYb9N6RKP05w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1701294595; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=ow0kkl59qs/eODsDObjGOIjiAE1tlQmwevgzg+bOQr0=; b=yOTqNbNmAOcegnC4GyoZJnMwjXm7T2lYyn5gDXv1t5oS5rA2JVA2ogUyyvHfCGIcC4lqqZ f1glVZFuQmc6z/eRZC2ZgjslNS3dEnxYf9xNJPFmkNh8UwVanQU/XEJoWVqUOlrNVLxCkT nJNBI29woz7Mmpurh7oY7mnAEEOfSvO2ggsmAK4DO6P/q0f/zBA2oXAjdFIjr1SY9GsA/S 4uWsFoweCPTuUsVB/uo0Wb8LfHeRlEZPv7Yu2h8HSSAPFTOdbJa5Lk0N9HgSsvolzQU52A Bld4g61Eqt9YRNmuSxP0LBlQDXlSJgCX3OIrIYoU/3RvrWjpdRtm+3x84EbnYQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1701294595; a=rsa-sha256; cv=none; b=wRHsUABhj3Ho960KZmW7aL8273+Q5zzkrY89BhjNDcdI20XfUzX7ITbTN7n9jctTkRMTb9 rL3xmQP4hCwx0knekEAQmdBJwrk+YfuC+Ha7F5NioNZ0uq7OhZyHmOAY/MkajETWZ51Xq2 nxpoyIY6731zqebZL/DvPF8/K73pcQ+k/dFuhZLbWYkqnTiSAcWPDWbOFwch/sV++LzXu9 PoKksjwC4ZB9qhYe+M3espqvZLOI7tW1WY/LZVvh1Jl8+8m6WLToFyWxmuuK0LGZMQziZ9 kON4rE/iEdhuuGaD012BhB5ctIm7cmfFoyd9vYxhjRWH02w0soJEFcqnlmL8ZA== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4SgXzl2G98z7qQ; Wed, 29 Nov 2023 21:49:55 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 3ATLntuc066799; Wed, 29 Nov 2023 21:49:55 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 3ATLntSC066796; Wed, 29 Nov 2023 21:49:55 GMT (envelope-from git) Date: Wed, 29 Nov 2023 21:49:55 GMT Message-Id: <202311292149.3ATLntSC066796@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Dag-Erling =?utf-8?Q?Sm=C3=B8rgrav?= Subject: git: 621f45532c58 - main - tail: Fix heap overflow in -F case. List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: des X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 621f45532c5887c96b708ce232c52878d0053325 Auto-Submitted: auto-generated The branch main has been updated by des: URL: https://cgit.FreeBSD.org/src/commit/?id=621f45532c5887c96b708ce232c52878d0053325 commit 621f45532c5887c96b708ce232c52878d0053325 Author: Dag-Erling Smørgrav AuthorDate: 2023-11-29 21:48:50 +0000 Commit: Dag-Erling Smørgrav CommitDate: 2023-11-29 21:49:38 +0000 tail: Fix heap overflow in -F case. The number of events we track can vary over time, but we only allocate enough space for the exact number of events we are tracking when we first begin, resulting in a trivially reproducable heap overflow. Fix this by allocating enough space for the greatest possible number of events (two per file) and clean up the code a bit. Also add a test case which triggers the aforementioned heap overflow, although we don't currently have a way to detect it. MFC after: 1 week Sponsored by: Klara, Inc. Reviewed by: allanjude, markj Differential Revision: https://reviews.freebsd.org/D42839 --- usr.bin/tail/forward.c | 39 ++++++++++++++++++--------------------- usr.bin/tail/tests/tail_test.sh | 21 ++++++++++++++++++++- 2 files changed, 38 insertions(+), 22 deletions(-) diff --git a/usr.bin/tail/forward.c b/usr.bin/tail/forward.c index e8e2cb89ab01..a8f52ed376c4 100644 --- a/usr.bin/tail/forward.c +++ b/usr.bin/tail/forward.c @@ -272,7 +272,7 @@ set_events(file_info_t *files) action = USE_KQUEUE; for (i = 0, file = files; i < no_files; i++, file++) { - if (! file->fp) + if (!file->fp) continue; if (fstatfs(fileno(file->fp), &sf) == 0 && @@ -304,27 +304,21 @@ set_events(file_info_t *files) void follow(file_info_t *files, enum STYLE style, off_t off) { - int active, ev_change, i, n = -1; + int active, ev_change, i, n; struct stat sb2; file_info_t *file; FILE *ftmp; struct timespec ts; /* Position each of the files */ - - file = files; active = 0; - n = 0; - for (i = 0; i < no_files; i++, file++) { - if (file->fp) { - active = 1; - n++; - if (vflag || (qflag == 0 && no_files > 1)) - printfn(file->file_name, 1); - forward(file->fp, file->file_name, style, off, &file->st); - if (Fflag && fileno(file->fp) != STDIN_FILENO) - n++; - } + for (i = 0, file = files; i < no_files; i++, file++) { + if (!file->fp) + continue; + active = 1; + if (vflag || (qflag == 0 && no_files > 1)) + printfn(file->file_name, 1); + forward(file->fp, file->file_name, style, off, &file->st); } if (!Fflag && !active) return; @@ -334,9 +328,14 @@ follow(file_info_t *files, enum STYLE style, off_t off) kq = kqueue(); if (kq < 0) err(1, "kqueue"); - ev = malloc(n * sizeof(struct kevent)); - if (! ev) - err(1, "Couldn't allocate memory for kevents."); + /* + * The number of kqueue events we track may vary over time and may + * even grow past its initial value in the -F case, but it will + * never exceed two per file, so just preallocate that. + */ + ev = malloc(no_files * 2 * sizeof(struct kevent)); + if (ev == NULL) + err(1, "Couldn't allocate memory for kevents."); set_events(files); for (;;) { @@ -410,9 +409,7 @@ follow(file_info_t *files, enum STYLE style, off_t off) */ do { n = kevent(kq, NULL, 0, ev, 1, Fflag ? &ts : NULL); - if (n < 0 && errno == EINTR) - continue; - if (n < 0) + if (n < 0 && errno != EINTR) err(1, "kevent"); } while (n < 0); if (n == 0) { diff --git a/usr.bin/tail/tests/tail_test.sh b/usr.bin/tail/tests/tail_test.sh index 8123a310fe67..9c941f8a2c2f 100755 --- a/usr.bin/tail/tests/tail_test.sh +++ b/usr.bin/tail/tests/tail_test.sh @@ -329,10 +329,28 @@ follow_stdin_body() atf_check kill $pid } +atf_test_case follow_create +follow_create_head() +{ + atf_set "descr" "Verify that -F works when a file is created" +} +follow_create_body() +{ + local pid + + rm -f infile + tail -F infile > outfile & + pid=$! + seq 1 5 >infile + sleep 2 + atf_check cmp infile outfile + atf_check kill $pid +} + atf_test_case follow_rename follow_rename_head() { - atf_set "descr" "Verify that -F works" + atf_set "descr" "Verify that -F works when a file is replaced" } follow_rename_body() { @@ -424,6 +442,7 @@ atf_init_test_cases() atf_add_test_case stdin atf_add_test_case follow atf_add_test_case follow_stdin + atf_add_test_case follow_create atf_add_test_case follow_rename atf_add_test_case silent_header atf_add_test_case verbose_header