Module Name: src Committed By: chs Date: Wed May 13 05:52:54 UTC 2020
Modified Files: src/external/cddl/osnet/dist/uts/common/fs/zfs: zfs_vnops.c Log Message: fix the handling in putpage of the page containing EOF. To generate a diff of this commit: cvs rdiff -u -r1.65 -r1.66 \ src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c diff -u src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c:1.65 src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c:1.66 --- src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c:1.65 Thu May 7 09:12:03 2020 +++ src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c Wed May 13 05:52:54 2020 @@ -6066,9 +6066,29 @@ zfs_putapage(vnode_t *vp, page_t **pp, i goto out_unbusy; } + /* + * Calculate the length and assert that no whole pages are past EOF. + * This check is equivalent to "off + len <= round_page(zp->z_size)", + * with gyrations to avoid signed integer overflow. + */ + off = pp[0]->offset; len = count * PAGESIZE; - KASSERT(off + len <= round_page(zp->z_size)); + KASSERT(off <= zp->z_size); + KASSERT(len <= round_page(zp->z_size)); + KASSERT(off <= round_page(zp->z_size) - len); + + /* + * If EOF is within the last page, reduce len to avoid writing past + * the file size in the ZFS buffer. Assert that + * "off + len <= zp->z_size", again avoiding signed integer overflow. + */ + + if (len > zp->z_size - off) { + len = zp->z_size - off; + } + KASSERT(len <= zp->z_size); + KASSERT(off <= zp->z_size - len); if (zfs_owner_overquota(zfsvfs, zp, B_FALSE) || zfs_owner_overquota(zfsvfs, zp, B_TRUE)) {