Message ID | 20220201111455.52511-16-imp@bsdimp.com |
---|---|
State | New |
Headers | show |
Series | bsd-user: Start upstreaming the system calls. | expand |
On Tue, Feb 1, 2022 at 5:15 AM Warner Losh <imp@bsdimp.com> wrote: > > Releases the references to the iovec created by lock_iovec. > > Signed-off-by: Warner Losh <imp@bsdimp.com> > --- > bsd-user/freebsd/os-syscall.c | 23 +++++++++++++++++++++++ > 1 file changed, 23 insertions(+) > Reviewed-by: Kyle Evans <kevans@FreeBSD.org> > diff --git a/bsd-user/freebsd/os-syscall.c b/bsd-user/freebsd/os-syscall.c > index c21759ae7ce..d49945f0fcc 100644 > --- a/bsd-user/freebsd/os-syscall.c > +++ b/bsd-user/freebsd/os-syscall.c > @@ -167,6 +167,29 @@ struct iovec *lock_iovec(int type, abi_ulong target_addr, > return NULL; > } > > +void unlock_iovec(struct iovec *vec, abi_ulong target_addr, > + int count, int copy) > +{ > + struct target_iovec *target_vec; > + int i; > + > + target_vec = lock_user(VERIFY_READ, target_addr, > + count * sizeof(struct target_iovec), 1); > + if (target_vec) { > + for (i = 0; i < count; i++) { > + abi_ulong base = tswapal(target_vec[i].iov_base); > + abi_long len = tswapal(target_vec[i].iov_len); > + if (len < 0) { > + break; > + } > + unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0); > + } > + unlock_user(target_vec, target_addr, 0); > + } > + > + free(vec); > +} > + > /* > * do_syscall() should always have a single exit point at the end so that > * actions, such as logging of syscall results, can be performed. All errnos > -- > 2.33.1 >
On 2/1/22 22:14, Warner Losh wrote: > Releases the references to the iovec created by lock_iovec. > > Signed-off-by: Warner Losh <imp@bsdimp.com> > --- > bsd-user/freebsd/os-syscall.c | 23 +++++++++++++++++++++++ > 1 file changed, 23 insertions(+) > > diff --git a/bsd-user/freebsd/os-syscall.c b/bsd-user/freebsd/os-syscall.c > index c21759ae7ce..d49945f0fcc 100644 > --- a/bsd-user/freebsd/os-syscall.c > +++ b/bsd-user/freebsd/os-syscall.c > @@ -167,6 +167,29 @@ struct iovec *lock_iovec(int type, abi_ulong target_addr, > return NULL; > } > > +void unlock_iovec(struct iovec *vec, abi_ulong target_addr, > + int count, int copy) > +{ > + struct target_iovec *target_vec; > + int i; > + > + target_vec = lock_user(VERIFY_READ, target_addr, > + count * sizeof(struct target_iovec), 1); > + if (target_vec) { > + for (i = 0; i < count; i++) { > + abi_ulong base = tswapal(target_vec[i].iov_base); > + abi_long len = tswapal(target_vec[i].iov_len); > + if (len < 0) { > + break; > + } > + unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0); > + } > + unlock_user(target_vec, target_addr, 0); Not quite right. Any vec[i].iov_len == 0 ought to be skipped, as per the previous patch, where we force those values for bad_address and target_vec[i].iov_len == 0. r~
diff --git a/bsd-user/freebsd/os-syscall.c b/bsd-user/freebsd/os-syscall.c index c21759ae7ce..d49945f0fcc 100644 --- a/bsd-user/freebsd/os-syscall.c +++ b/bsd-user/freebsd/os-syscall.c @@ -167,6 +167,29 @@ struct iovec *lock_iovec(int type, abi_ulong target_addr, return NULL; } +void unlock_iovec(struct iovec *vec, abi_ulong target_addr, + int count, int copy) +{ + struct target_iovec *target_vec; + int i; + + target_vec = lock_user(VERIFY_READ, target_addr, + count * sizeof(struct target_iovec), 1); + if (target_vec) { + for (i = 0; i < count; i++) { + abi_ulong base = tswapal(target_vec[i].iov_base); + abi_long len = tswapal(target_vec[i].iov_len); + if (len < 0) { + break; + } + unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0); + } + unlock_user(target_vec, target_addr, 0); + } + + free(vec); +} + /* * do_syscall() should always have a single exit point at the end so that * actions, such as logging of syscall results, can be performed. All errnos
Releases the references to the iovec created by lock_iovec. Signed-off-by: Warner Losh <imp@bsdimp.com> --- bsd-user/freebsd/os-syscall.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)