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
f45feecfb2 '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
This commit is contained in:
Konstantin Belousov 2023-01-20 08:45:35 +02:00
parent 5657f49ef3
commit 456f05756b
2 changed files with 8 additions and 5 deletions

View file

@ -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);
}

View file

@ -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;
}