mirror of
https://github.com/opnsense/src.git
synced 2026-06-09 00:32:25 -04:00
vfs_syscalls.c: Fix handling of offset args for copy_file_range
Commit197997abroke handling of the offset arguments to copy_file_range() when specified non-NULL. The code fails to update the offsets and, as such, a loop like: do { len = copy_file_range(infd, &inpos, outfd, &outpos, SSIZE_MAX, 0); } while (len > 0); becomes an infinite loop, just doing the same copy over and over again. This patch fixes it. The clause "(foffsets_locked || foffsets_set)" in the if is not actually needed for correctness, but I thought it made the code a little more readable and might avoid some static analyzer from throwing a "used before being set" for the savinoff and savoutoff variables. Reviewed by: markj Differential Revision: https://reviews.freebsd.org/D51845 MFC after: 2 weeks Fixes:197997a4c3("file: Fix offset handling in kern_copy_file_range()")
This commit is contained in:
parent
7a9834041c
commit
4046ad6bb0
1 changed files with 12 additions and 5 deletions
|
|
@ -5050,11 +5050,12 @@ kern_copy_file_range(struct thread *td, int infd, off_t *inoffp, int outfd,
|
|||
size_t retlen;
|
||||
void *rl_rcookie, *rl_wcookie;
|
||||
off_t inoff, outoff, savinoff, savoutoff;
|
||||
bool foffsets_locked;
|
||||
bool foffsets_locked, foffsets_set;
|
||||
|
||||
infp = outfp = NULL;
|
||||
rl_rcookie = rl_wcookie = NULL;
|
||||
foffsets_locked = false;
|
||||
foffsets_set = false;
|
||||
error = 0;
|
||||
retlen = 0;
|
||||
|
||||
|
|
@ -5122,6 +5123,8 @@ kern_copy_file_range(struct thread *td, int infd, off_t *inoffp, int outfd,
|
|||
}
|
||||
foffset_lock_pair(infp1, &inoff, outfp1, &outoff, 0);
|
||||
foffsets_locked = true;
|
||||
} else {
|
||||
foffsets_set = true;
|
||||
}
|
||||
savinoff = inoff;
|
||||
savoutoff = outoff;
|
||||
|
|
@ -5180,11 +5183,12 @@ out:
|
|||
vn_rangelock_unlock(invp, rl_rcookie);
|
||||
if (rl_wcookie != NULL)
|
||||
vn_rangelock_unlock(outvp, rl_wcookie);
|
||||
if ((foffsets_locked || foffsets_set) &&
|
||||
(error == EINTR || error == ERESTART)) {
|
||||
inoff = savinoff;
|
||||
outoff = savoutoff;
|
||||
}
|
||||
if (foffsets_locked) {
|
||||
if (error == EINTR || error == ERESTART) {
|
||||
inoff = savinoff;
|
||||
outoff = savoutoff;
|
||||
}
|
||||
if (inoffp == NULL)
|
||||
foffset_unlock(infp, inoff, 0);
|
||||
else
|
||||
|
|
@ -5193,6 +5197,9 @@ out:
|
|||
foffset_unlock(outfp, outoff, 0);
|
||||
else
|
||||
*outoffp = outoff;
|
||||
} else if (foffsets_set) {
|
||||
*inoffp = inoff;
|
||||
*outoffp = outoff;
|
||||
}
|
||||
if (outfp != NULL)
|
||||
fdrop(outfp, td);
|
||||
|
|
|
|||
Loading…
Reference in a new issue