summaryrefslogtreecommitdiffstats
path: root/sys/tmpfs
diff options
context:
space:
mode:
authorguenther <guenther@openbsd.org>2014-02-25 17:31:15 +0000
committerguenther <guenther@openbsd.org>2014-02-25 17:31:15 +0000
commit081a143f78a0882f199199ccea134228ca36de50 (patch)
treee2052809c04ea95646d1bff2a26ed5b1e0cdbc70 /sys/tmpfs
parentif a specific pattern of failures/success happen, we can end up not (diff)
downloadwireguard-openbsd-081a143f78a0882f199199ccea134228ca36de50.tar.xz
wireguard-openbsd-081a143f78a0882f199199ccea134228ca36de50.zip
Check for offset wraparound and enforce RLIMIT_FSIZE.
problem reported by brad@ ok kettenis@ millert@
Diffstat (limited to 'sys/tmpfs')
-rw-r--r--sys/tmpfs/tmpfs_vnops.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/sys/tmpfs/tmpfs_vnops.c b/sys/tmpfs/tmpfs_vnops.c
index 9c822305111..d576e6b1b54 100644
--- a/sys/tmpfs/tmpfs_vnops.c
+++ b/sys/tmpfs/tmpfs_vnops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tmpfs_vnops.c,v 1.13 2014/01/22 18:28:16 tedu Exp $ */
+/* $OpenBSD: tmpfs_vnops.c,v 1.14 2014/02/25 17:31:15 guenther Exp $ */
/* $NetBSD: tmpfs_vnops.c,v 1.100 2012/11/05 17:27:39 dholland Exp $ */
/*
@@ -596,6 +596,7 @@ tmpfs_write(void *v)
const int ioflag = ap->a_ioflag;
tmpfs_node_t *node;
off_t oldsize;
+ ssize_t overrun;
int extended;
int error;
@@ -616,6 +617,14 @@ tmpfs_write(void *v)
uio->uio_offset = node->tn_size;
}
+ if (uio->uio_offset < 0 ||
+ (u_int64_t)uio->uio_offset + uio->uio_resid > LLONG_MAX)
+ return (EFBIG);
+
+ /* do the filesize rlimit check */
+ if ((error = vn_fsizechk(vp, uio, ioflag, &overrun)))
+ return (error);
+
extended = uio->uio_offset + uio->uio_resid > node->tn_size;
if (extended) {
error = tmpfs_reg_resize(vp, uio->uio_offset + uio->uio_resid);
@@ -648,6 +657,10 @@ out:
KASSERT(oldsize == node->tn_size);
} else {
KASSERT(uio->uio_resid == 0);
+
+ /* correct the result for writes clamped by vn_fsizechk() */
+ uio->uio_resid += overrun;
+
}
return error;
}