From 456f05756bbdd818f7b2474faeef0d4d7baecd69 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Fri, 20 Jan 2023 08:45:35 +0200 Subject: [PATCH] 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 #include #include +#include #include #include #include @@ -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; }