git: 18bce6e65cdf - main - tarfs: Fix length calculation for file read

From: Dag-Erling Smørgrav <des_at_FreeBSD.org>
Date: Mon, 02 Nov 2026 12:38:05 UTC
The branch main has been updated by des:

URL: https://cgit.FreeBSD.org/src/commit/?id=18bce6e65cdf059618ff12ace82a9f7334e1b610

commit 18bce6e65cdf059618ff12ace82a9f7334e1b610
Author:     Dag-Erling Smørgrav <des@FreeBSD.org>
AuthorDate: 2026-11-02 12:29:25 +0000
Commit:     Dag-Erling Smørgrav <des@FreeBSD.org>
CommitDate: 2026-11-02 12:29:25 +0000

    tarfs: Fix length calculation for file read
    
    When the offset is within a block rather than at its beginning, the
    length should be clamped to the remaining length of the block, not its
    total length.
    
    Reported by:    n0ps1ed
    MFC after:      1 week
    Reviewed by:    markj, emaste
    Differential Revision:  https://reviews.freebsd.org/D60904
---
 sys/fs/tarfs/tarfs_subr.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/sys/fs/tarfs/tarfs_subr.c b/sys/fs/tarfs/tarfs_subr.c
index 180e0a53f8b9..0cb5eec8c385 100644
--- a/sys/fs/tarfs/tarfs_subr.c
+++ b/sys/fs/tarfs/tarfs_subr.c
@@ -428,7 +428,7 @@ tarfs_read_file(struct tarfs_node *tnp, size_t len, struct uio *uiop)
 	TARFS_DPF(VNODE, "%s(%s, %zu, %zu)\n", __func__,
 	    tnp->name, uiop->uio_offset, resid);
 	for (i = 0; i < tnp->nblk && resid > 0; ++i) {
-		if (uiop->uio_offset > tnp->blk[i].o + tnp->blk[i].l) {
+		if (uiop->uio_offset >= tnp->blk[i].o + tnp->blk[i].l) {
 			/* skip this block */
 			continue;
 		}
@@ -456,7 +456,8 @@ tarfs_read_file(struct tarfs_node *tnp, size_t len, struct uio *uiop)
 		while (resid > 0 &&
 		    uiop->uio_offset < tnp->blk[i].o + tnp->blk[i].l) {
 			/* now actual data */
-			copylen = tnp->blk[i].l;
+			copylen = tnp->blk[i].l -
+			    (uiop->uio_offset - tnp->blk[i].o);
 			if (copylen > resid)
 				copylen = resid;
 			auio = *uiop;