git: 456f05756bbd - main - Handle int rank issues in in vn_getsize_locked() and vn_seek()

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Fri, 20 Jan 2023 21:56:41 UTC
The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=456f05756bbdd818f7b2474faeef0d4d7baecd69

commit 456f05756bbdd818f7b2474faeef0d4d7baecd69
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2023-01-20 06:45:35 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2023-01-20 21:56:29 +0000

    Handle int rank issues in in vn_getsize_locked() and vn_seek()
    
    In vn_getsize_locked(), when storing vattr.va_size of type u_quad_t into
    off_t size, we must avoid overflow.
    
    Then, the check for fsize < 0, introduced in the commit
    f45feecfb27ca51067d6789eaa43547cadc4990b 'vfs: add vn_getsize', is nop [1].
    
    Reported and reviewed by:       jhb
    Coverity CID:   1502346
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D38133
---
 sys/kern/vfs_subr.c  | 9 +++++++--
 sys/kern/vfs_vnops.c | 4 +---
 2 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index a1a73f2ddf38..008e646f2b7f 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -66,6 +66,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/kernel.h>
 #include <sys/kthread.h>
 #include <sys/ktr.h>
+#include <sys/limits.h>
 #include <sys/lockf.h>
 #include <sys/malloc.h>
 #include <sys/mount.h>
@@ -7128,8 +7129,12 @@ vn_getsize_locked(struct vnode *vp, off_t *size, struct ucred *cred)
 
 	ASSERT_VOP_LOCKED(vp, __func__);
 	error = VOP_GETATTR(vp, &vattr, cred);
-	if (__predict_true(error == 0))
-		*size = vattr.va_size;
+	if (__predict_true(error == 0)) {
+		if (vattr.va_size <= OFF_MAX)
+			*size = vattr.va_size;
+		else
+			error = EFBIG;
+	}
 	return (error);
 }
 
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
index f3a6360eb250..48d15ce6ab25 100644
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -2656,9 +2656,7 @@ vn_seek(struct file *fp, off_t offset, int whence, struct thread *td)
 		if (fsize == 0 && vp->v_type == VCHR &&
 		    fo_ioctl(fp, DIOCGMEDIASIZE, &size, cred, td) == 0)
 			fsize = size;
-		if (noneg &&
-		    (fsize > OFF_MAX ||
-		    (offset > 0 && fsize > OFF_MAX - offset))) {
+		if (noneg && offset > 0 && fsize > OFF_MAX - offset) {
 			error = EOVERFLOW;
 			break;
 		}