Fix iovec32 for linux32/amd64.
Add a custom version of copyiniov() to deal with the 32-bit iovec pointers from userland (to be used later). Adjust prototypes for linux_readv() and linux_writev() to use new l_iovec32 definition and to match actual linux code. In particular, use ulong for fd (why ?). Submitted by: dchagin
This commit is contained in:
parent
7a6d0a128f
commit
bfe2c8cb22
@ -885,6 +885,16 @@ struct l_user_desc {
|
||||
(LINUX_CLONE_VM | LINUX_CLONE_FS | LINUX_CLONE_FILES | \
|
||||
LINUX_CLONE_SIGHAND | LINUX_CLONE_THREAD)
|
||||
|
||||
struct iovec;
|
||||
|
||||
struct l_iovec32 {
|
||||
uint32_t iov_base;
|
||||
l_size_t iov_len;
|
||||
};
|
||||
|
||||
int linux32_copyiniov(struct l_iovec32 *iovp32, l_ulong iovcnt,
|
||||
struct iovec **iovp, int error);
|
||||
|
||||
/* robust futexes */
|
||||
struct linux_robust_list {
|
||||
l_uintptr_t next;
|
||||
|
@ -232,20 +232,15 @@ linux_execve(struct thread *td, struct linux_execve_args *args)
|
||||
return (error);
|
||||
}
|
||||
|
||||
struct iovec32 {
|
||||
u_int32_t iov_base;
|
||||
int iov_len;
|
||||
};
|
||||
|
||||
CTASSERT(sizeof(struct iovec32) == 8);
|
||||
CTASSERT(sizeof(struct l_iovec32) == 8);
|
||||
|
||||
static int
|
||||
linux32_copyinuio(struct iovec32 *iovp, u_int iovcnt, struct uio **uiop)
|
||||
linux32_copyinuio(struct l_iovec32 *iovp, l_ulong iovcnt, struct uio **uiop)
|
||||
{
|
||||
struct iovec32 iov32;
|
||||
struct l_iovec32 iov32;
|
||||
struct iovec *iov;
|
||||
struct uio *uio;
|
||||
u_int iovlen;
|
||||
uint32_t iovlen;
|
||||
int error, i;
|
||||
|
||||
*uiop = NULL;
|
||||
@ -255,7 +250,7 @@ linux32_copyinuio(struct iovec32 *iovp, u_int iovcnt, struct uio **uiop)
|
||||
uio = malloc(iovlen + sizeof(*uio), M_IOV, M_WAITOK);
|
||||
iov = (struct iovec *)(uio + 1);
|
||||
for (i = 0; i < iovcnt; i++) {
|
||||
error = copyin(&iovp[i], &iov32, sizeof(struct iovec32));
|
||||
error = copyin(&iovp[i], &iov32, sizeof(struct l_iovec32));
|
||||
if (error) {
|
||||
free(uio, M_IOV);
|
||||
return (error);
|
||||
@ -280,6 +275,34 @@ linux32_copyinuio(struct iovec32 *iovp, u_int iovcnt, struct uio **uiop)
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
linux32_copyiniov(struct l_iovec32 *iovp32, l_ulong iovcnt, struct iovec **iovp,
|
||||
int error)
|
||||
{
|
||||
struct l_iovec32 iov32;
|
||||
struct iovec *iov;
|
||||
uint32_t iovlen;
|
||||
int i;
|
||||
|
||||
*iovp = NULL;
|
||||
if (iovcnt > UIO_MAXIOV)
|
||||
return (error);
|
||||
iovlen = iovcnt * sizeof(struct iovec);
|
||||
iov = malloc(iovlen, M_IOV, M_WAITOK);
|
||||
for (i = 0; i < iovcnt; i++) {
|
||||
error = copyin(&iovp32[i], &iov32, sizeof(struct l_iovec32));
|
||||
if (error) {
|
||||
free(iov, M_IOV);
|
||||
return (error);
|
||||
}
|
||||
iov[i].iov_base = PTRIN(iov32.iov_base);
|
||||
iov[i].iov_len = iov32.iov_len;
|
||||
}
|
||||
*iovp = iov;
|
||||
return(0);
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
linux_readv(struct thread *td, struct linux_readv_args *uap)
|
||||
{
|
||||
|
@ -252,10 +252,10 @@
|
||||
143 AUE_FLOCK NOPROTO { int flock(int fd, int how); }
|
||||
144 AUE_MSYNC STD { int linux_msync(l_ulong addr, \
|
||||
l_size_t len, l_int fl); }
|
||||
145 AUE_READV STD { int linux_readv(int fd, struct iovec32 *iovp, \
|
||||
u_int iovcnt); }
|
||||
146 AUE_WRITEV STD { int linux_writev(int fd, struct iovec32 *iovp, \
|
||||
u_int iovcnt); }
|
||||
145 AUE_READV STD { int linux_readv(l_ulong fd, struct l_iovec32 *iovp, \
|
||||
l_ulong iovcnt); }
|
||||
146 AUE_WRITEV STD { int linux_writev(l_ulong fd, struct l_iovec32 *iovp, \
|
||||
l_ulong iovcnt); }
|
||||
147 AUE_GETSID STD { int linux_getsid(l_pid_t pid); }
|
||||
148 AUE_NULL STD { int linux_fdatasync(l_uint fd); }
|
||||
149 AUE_SYSCTL STD { int linux_sysctl( \
|
||||
|
Loading…
Reference in New Issue
Block a user