Author: rmacklem Date: Wed Sep 30 02:18:09 2020 New Revision: 366278 URL: https://svnweb.freebsd.org/changeset/base/366278
Log: Make copy_file_range(2) Linux compatible for overflow of offset + len. Without this patch, if a call to copy_file_range(2) specifies an input file offset + len that would wrap around, EINVAL is returned. I thought that was the Linux behaviour, but recent testing showed that Linux accepts this case and does the copy_file_range() to EOF. This patch changes the FreeBSD code to exhibit the same behaviour as Linux for this case. Reviewed by: asomers, kib Differential Revision: https://reviews.freebsd.org/D26569 Modified: head/sys/kern/vfs_vnops.c Modified: head/sys/kern/vfs_vnops.c ============================================================================== --- head/sys/kern/vfs_vnops.c Wed Sep 30 00:56:08 2020 (r366277) +++ head/sys/kern/vfs_vnops.c Wed Sep 30 02:18:09 2020 (r366278) @@ -2790,25 +2790,31 @@ vn_copy_file_range(struct vnode *invp, off_t *inoffp, { int error; size_t len; - uint64_t uvalin, uvalout; + uint64_t uval; len = *lenp; *lenp = 0; /* For error returns. */ error = 0; /* Do some sanity checks on the arguments. */ - uvalin = *inoffp; - uvalin += len; - uvalout = *outoffp; - uvalout += len; if (invp->v_type == VDIR || outvp->v_type == VDIR) error = EISDIR; - else if (*inoffp < 0 || uvalin > INT64_MAX || uvalin < - (uint64_t)*inoffp || *outoffp < 0 || uvalout > INT64_MAX || - uvalout < (uint64_t)*outoffp || invp->v_type != VREG || - outvp->v_type != VREG) + else if (*inoffp < 0 || *outoffp < 0 || + invp->v_type != VREG || outvp->v_type != VREG) error = EINVAL; if (error != 0) + goto out; + + /* Ensure offset + len does not wrap around. */ + uval = *inoffp; + uval += len; + if (uval > INT64_MAX) + len = INT64_MAX - *inoffp; + uval = *outoffp; + uval += len; + if (uval > INT64_MAX) + len = INT64_MAX - *outoffp; + if (len == 0) goto out; /* _______________________________________________ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"