Commit 3225fc8a authored by Benjamin LaHaise's avatar Benjamin LaHaise Committed by David S. Miller

[NET]: Simplify scm handling and sendmsg/recvmsg invocation, consolidate net compat syscalls.

1) Pull scm argument from sendmsg/recvmsg, it is available
from I/O control block
2) Consolidate networking syscall compat call into net/compat.c
3) Change ops->{sendmsg,recvmsg}() code sequences into sock_{sendmsg,recvmsg}()
parent 8589b566
...@@ -300,7 +300,7 @@ ia32_syscall_table: ...@@ -300,7 +300,7 @@ ia32_syscall_table:
data8 compat_sys_statfs data8 compat_sys_statfs
data8 compat_sys_fstatfs /* 100 */ data8 compat_sys_fstatfs /* 100 */
data8 sys32_ioperm data8 sys32_ioperm
data8 sys32_socketcall data8 compat_sys_socketcall
data8 sys_syslog data8 sys_syslog
data8 compat_sys_setitimer data8 compat_sys_setitimer
data8 compat_sys_getitimer /* 105 */ data8 compat_sys_getitimer /* 105 */
......
...@@ -97,11 +97,9 @@ typedef struct sg_io_hdr32 { ...@@ -97,11 +97,9 @@ typedef struct sg_io_hdr32 {
int info; /* [o] auxiliary information */ int info; /* [o] auxiliary information */
} sg_io_hdr32_t; /* 64 bytes long (on IA32) */ } sg_io_hdr32_t; /* 64 bytes long (on IA32) */
struct iovec32 { unsigned int iov_base; int iov_len; };
static int alloc_sg_iovec(sg_io_hdr_t *sgp, int uptr32) static int alloc_sg_iovec(sg_io_hdr_t *sgp, int uptr32)
{ {
struct iovec32 *uiov = (struct iovec32 *) P(uptr32); struct compat_iovec *uiov = (struct compat_iovec *) P(uptr32);
sg_iovec_t *kiov; sg_iovec_t *kiov;
int i; int i;
...@@ -136,7 +134,7 @@ static int alloc_sg_iovec(sg_io_hdr_t *sgp, int uptr32) ...@@ -136,7 +134,7 @@ static int alloc_sg_iovec(sg_io_hdr_t *sgp, int uptr32)
static int copy_back_sg_iovec(sg_io_hdr_t *sgp, int uptr32) static int copy_back_sg_iovec(sg_io_hdr_t *sgp, int uptr32)
{ {
struct iovec32 *uiov = (struct iovec32 *) P(uptr32); struct compat_iovec *uiov = (struct compat_iovec *) P(uptr32);
sg_iovec_t *kiov = (sg_iovec_t *) sgp->dxferp; sg_iovec_t *kiov = (sg_iovec_t *) sgp->dxferp;
int i; int i;
......
This diff is collapsed.
...@@ -729,12 +729,10 @@ extern asmlinkage int sys32_llseek(unsigned int fd, unsigned int offset_high, ...@@ -729,12 +729,10 @@ extern asmlinkage int sys32_llseek(unsigned int fd, unsigned int offset_high,
return sys_llseek(fd, offset_high, offset_low, result, origin); return sys_llseek(fd, offset_high, offset_low, result, origin);
} }
struct iovec32 { unsigned int iov_base; int iov_len; };
typedef ssize_t (*IO_fn_t)(struct file *, char *, size_t, loff_t *); typedef ssize_t (*IO_fn_t)(struct file *, char *, size_t, loff_t *);
static long static long
do_readv_writev32(int type, struct file *file, const struct iovec32 *vector, do_readv_writev32(int type, struct file *file, const struct compat_iovec *vector,
u32 count) u32 count)
{ {
unsigned long tot_len; unsigned long tot_len;
...@@ -749,7 +747,7 @@ do_readv_writev32(int type, struct file *file, const struct iovec32 *vector, ...@@ -749,7 +747,7 @@ do_readv_writev32(int type, struct file *file, const struct iovec32 *vector,
*/ */
if (!count) if (!count)
return 0; return 0;
if(verify_area(VERIFY_READ, vector, sizeof(struct iovec32)*count)) if(verify_area(VERIFY_READ, vector, sizeof(struct compat_iovec)*count))
return -EFAULT; return -EFAULT;
if (count > UIO_MAXIOV) if (count > UIO_MAXIOV)
return -EINVAL; return -EINVAL;
...@@ -835,7 +833,7 @@ do_readv_writev32(int type, struct file *file, const struct iovec32 *vector, ...@@ -835,7 +833,7 @@ do_readv_writev32(int type, struct file *file, const struct iovec32 *vector,
} }
asmlinkage long asmlinkage long
sys32_readv(int fd, struct iovec32 *vector, u32 count) sys32_readv(int fd, struct compat_iovec *vector, u32 count)
{ {
struct file *file; struct file *file;
ssize_t ret; ssize_t ret;
...@@ -855,7 +853,7 @@ sys32_readv(int fd, struct iovec32 *vector, u32 count) ...@@ -855,7 +853,7 @@ sys32_readv(int fd, struct iovec32 *vector, u32 count)
} }
asmlinkage long asmlinkage long
sys32_writev(int fd, struct iovec32 *vector, u32 count) sys32_writev(int fd, struct compat_iovec *vector, u32 count)
{ {
struct file *file; struct file *file;
ssize_t ret; ssize_t ret;
...@@ -1155,48 +1153,6 @@ asmlinkage long sys32_times(struct tms32 *tbuf) ...@@ -1155,48 +1153,6 @@ asmlinkage long sys32_times(struct tms32 *tbuf)
return ret; return ret;
} }
extern asmlinkage int sys_setsockopt(int fd, int level, int optname,
char *optval, int optlen);
asmlinkage int sys32_setsockopt(int fd, int level, int optname,
char *optval, int optlen)
{
if (optname == SO_ATTACH_FILTER) {
struct sock_fprog32 {
__u16 len;
__u32 filter;
} *fprog32 = (struct sock_fprog32 *)optval;
struct sock_fprog kfprog;
struct sock_filter *kfilter;
unsigned int fsize;
mm_segment_t old_fs;
__u32 uptr;
int ret;
if (get_user(kfprog.len, &fprog32->len) ||
__get_user(uptr, &fprog32->filter))
return -EFAULT;
kfprog.filter = (struct sock_filter *)A(uptr);
fsize = kfprog.len * sizeof(struct sock_filter);
kfilter = (struct sock_filter *)kmalloc(fsize, GFP_KERNEL);
if (kfilter == NULL)
return -ENOMEM;
if (copy_from_user(kfilter, kfprog.filter, fsize)) {
kfree(kfilter);
return -EFAULT;
}
kfprog.filter = kfilter;
old_fs = get_fs();
set_fs(KERNEL_DS);
ret = sys_setsockopt(fd, level, optname,
(char *)&kfprog, sizeof(kfprog));
set_fs(old_fs);
kfree(kfilter);
return ret;
}
return sys_setsockopt(fd, level, optname, optval, optlen);
}
struct flock32 { struct flock32 {
short l_type; short l_type;
short l_whence; short l_whence;
...@@ -1873,256 +1829,3 @@ asmlinkage int sys32_adjtimex(struct timex32 *utp) ...@@ -1873,256 +1829,3 @@ asmlinkage int sys32_adjtimex(struct timex32 *utp)
return ret; return ret;
} }
/*
* Declare the 32-bit version of the msghdr
*/
struct msghdr32 {
unsigned int msg_name; /* Socket name */
int msg_namelen; /* Length of name */
unsigned int msg_iov; /* Data blocks */
unsigned int msg_iovlen; /* Number of blocks */
unsigned int msg_control; /* Per protocol magic (eg BSD file descriptor passing) */
unsigned int msg_controllen; /* Length of cmsg list */
unsigned msg_flags;
};
static inline int
shape_msg(struct msghdr *mp, struct msghdr32 *mp32)
{
int ret;
unsigned int i;
if (!access_ok(VERIFY_READ, mp32, sizeof(*mp32)))
return(-EFAULT);
ret = __get_user(i, &mp32->msg_name);
mp->msg_name = (void *)A(i);
ret |= __get_user(mp->msg_namelen, &mp32->msg_namelen);
ret |= __get_user(i, &mp32->msg_iov);
mp->msg_iov = (struct iovec *)A(i);
ret |= __get_user(mp->msg_iovlen, &mp32->msg_iovlen);
ret |= __get_user(i, &mp32->msg_control);
mp->msg_control = (void *)A(i);
ret |= __get_user(mp->msg_controllen, &mp32->msg_controllen);
ret |= __get_user(mp->msg_flags, &mp32->msg_flags);
return(ret ? -EFAULT : 0);
}
/*
* Verify & re-shape IA32 iovec. The caller must ensure that the
* iovec is big enough to hold the re-shaped message iovec.
*
* Save time not doing verify_area. copy_*_user will make this work
* in any case.
*
* Don't need to check the total size for overflow (cf net/core/iovec.c),
* 32-bit sizes can't overflow a 64-bit count.
*/
static inline int
verify_iovec32(struct msghdr *m, struct iovec *iov, char *address, int mode)
{
int size, err, ct;
struct iovec32 *iov32;
if(m->msg_namelen)
{
if(mode==VERIFY_READ)
{
err=move_addr_to_kernel(m->msg_name, m->msg_namelen, address);
if(err<0)
goto out;
}
m->msg_name = address;
} else
m->msg_name = NULL;
err = -EFAULT;
size = m->msg_iovlen * sizeof(struct iovec32);
if (copy_from_user(iov, m->msg_iov, size))
goto out;
m->msg_iov=iov;
err = 0;
iov32 = (struct iovec32 *)iov;
for (ct = m->msg_iovlen; ct-- > 0; ) {
iov[ct].iov_len = (__kernel_size_t)iov32[ct].iov_len;
iov[ct].iov_base = (void *) A(iov32[ct].iov_base);
err += iov[ct].iov_len;
}
out:
return err;
}
/* XXX This really belongs in some header file... -DaveM */
#define MAX_SOCK_ADDR 128 /* 108 for Unix domain -
16 for IP, 16 for IPX,
24 for IPv6,
about 80 for AX.25 */
/*
* BSD sendmsg interface
*/
int sys32_sendmsg(int fd, struct msghdr32 *msg, unsigned flags)
{
struct socket *sock;
char address[MAX_SOCK_ADDR];
struct iovec iovstack[UIO_FASTIOV], *iov = iovstack;
unsigned char ctl[sizeof(struct cmsghdr) + 20]; /* 20 is size of ipv6_pktinfo */
unsigned char *ctl_buf = ctl;
struct msghdr msg_sys;
int err, ctl_len, iov_size, total_len;
err = -EFAULT;
if (shape_msg(&msg_sys, msg))
goto out;
sock = sockfd_lookup(fd, &err);
if (!sock)
goto out;
/* do not move before msg_sys is valid */
err = -EINVAL;
if (msg_sys.msg_iovlen > UIO_MAXIOV)
goto out_put;
/* Check whether to allocate the iovec area*/
err = -ENOMEM;
iov_size = msg_sys.msg_iovlen * sizeof(struct iovec32);
if (msg_sys.msg_iovlen > UIO_FASTIOV) {
iov = sock_kmalloc(sock->sk, iov_size, GFP_KERNEL);
if (!iov)
goto out_put;
}
/* This will also move the address data into kernel space */
err = verify_iovec32(&msg_sys, iov, address, VERIFY_READ);
if (err < 0)
goto out_freeiov;
total_len = err;
err = -ENOBUFS;
if (msg_sys.msg_controllen > INT_MAX)
goto out_freeiov;
ctl_len = msg_sys.msg_controllen;
if (ctl_len)
{
if (ctl_len > sizeof(ctl))
{
err = -ENOBUFS;
ctl_buf = sock_kmalloc(sock->sk, ctl_len, GFP_KERNEL);
if (ctl_buf == NULL)
goto out_freeiov;
}
err = -EFAULT;
if (copy_from_user(ctl_buf, msg_sys.msg_control, ctl_len))
goto out_freectl;
msg_sys.msg_control = ctl_buf;
}
msg_sys.msg_flags = flags;
if (sock->file->f_flags & O_NONBLOCK)
msg_sys.msg_flags |= MSG_DONTWAIT;
err = sock_sendmsg(sock, &msg_sys, total_len);
out_freectl:
if (ctl_buf != ctl)
sock_kfree_s(sock->sk, ctl_buf, ctl_len);
out_freeiov:
if (iov != iovstack)
sock_kfree_s(sock->sk, iov, iov_size);
out_put:
sockfd_put(sock);
out:
return err;
}
/*
* BSD recvmsg interface
*/
int
sys32_recvmsg (int fd, struct msghdr32 *msg, unsigned int flags)
{
struct socket *sock;
struct iovec iovstack[UIO_FASTIOV];
struct iovec *iov=iovstack;
struct msghdr msg_sys;
unsigned long cmsg_ptr;
int err, iov_size, total_len, len;
/* kernel mode address */
char addr[MAX_SOCK_ADDR];
/* user mode address pointers */
struct sockaddr *uaddr;
int *uaddr_len;
err=-EFAULT;
if (shape_msg(&msg_sys, msg))
goto out;
sock = sockfd_lookup(fd, &err);
if (!sock)
goto out;
err = -EINVAL;
if (msg_sys.msg_iovlen > UIO_MAXIOV)
goto out_put;
/* Check whether to allocate the iovec area*/
err = -ENOMEM;
iov_size = msg_sys.msg_iovlen * sizeof(struct iovec);
if (msg_sys.msg_iovlen > UIO_FASTIOV) {
iov = sock_kmalloc(sock->sk, iov_size, GFP_KERNEL);
if (!iov)
goto out_put;
}
/*
* Save the user-mode address (verify_iovec will change the
* kernel msghdr to use the kernel address space)
*/
uaddr = msg_sys.msg_name;
uaddr_len = &msg->msg_namelen;
err = verify_iovec32(&msg_sys, iov, addr, VERIFY_WRITE);
if (err < 0)
goto out_freeiov;
total_len=err;
cmsg_ptr = (unsigned long)msg_sys.msg_control;
msg_sys.msg_flags = 0;
if (sock->file->f_flags & O_NONBLOCK)
flags |= MSG_DONTWAIT;
err = sock_recvmsg(sock, &msg_sys, total_len, flags);
if (err < 0)
goto out_freeiov;
len = err;
if (uaddr != NULL) {
err = move_addr_to_user(addr, msg_sys.msg_namelen, uaddr, uaddr_len);
if (err < 0)
goto out_freeiov;
}
err = __put_user(msg_sys.msg_flags, &msg->msg_flags);
if (err)
goto out_freeiov;
err = __put_user((unsigned long)msg_sys.msg_control-cmsg_ptr,
&msg->msg_controllen);
if (err)
goto out_freeiov;
err = len;
out_freeiov:
if (iov != iovstack)
sock_kfree_s(sock->sk, iov, iov_size);
out_put:
sockfd_put(sock);
out:
return err;
}
...@@ -378,8 +378,8 @@ illegal_syscall: ...@@ -378,8 +378,8 @@ illegal_syscall:
sys sys32_select 5 sys sys32_select 5
sys sys_flock 2 sys sys_flock 2
sys sys_msync 3 sys sys_msync 3
sys sys32_readv 3 /* 4145 */ sys compat_sys_readv 3 /* 4145 */
sys sys32_writev 3 sys compat_sys_writev 3
sys sys_cacheflush 3 sys sys_cacheflush 3
sys sys_cachectl 3 sys sys_cachectl 3
sys sys_sysmips 4 sys sys_sysmips 4
...@@ -410,11 +410,11 @@ illegal_syscall: ...@@ -410,11 +410,11 @@ illegal_syscall:
sys sys_listen 2 sys sys_listen 2
sys sys_recv 4 /* 4175 */ sys sys_recv 4 /* 4175 */
sys sys_recvfrom 6 sys sys_recvfrom 6
sys sys32_recvmsg 3 sys compat_sys_recvmsg 3
sys sys_send 4 sys sys_send 4
sys sys32_sendmsg 3 sys compat_sys_sendmsg 3
sys sys_sendto 6 /* 4180 */ sys sys_sendto 6 /* 4180 */
sys sys32_setsockopt 5 sys compat_sys_setsockopt 5
sys sys_shutdown 2 sys sys_shutdown 2
sys sys_socket 3 sys sys_socket 3
sys sys_socketpair 4 sys sys_socketpair 4
......
This diff is collapsed.
...@@ -604,7 +604,7 @@ _GLOBAL(sys_call_table32) ...@@ -604,7 +604,7 @@ _GLOBAL(sys_call_table32)
.llong .compat_sys_statfs .llong .compat_sys_statfs
.llong .compat_sys_fstatfs /* 100 */ .llong .compat_sys_fstatfs /* 100 */
.llong .sys_ioperm .llong .sys_ioperm
.llong .sys32_socketcall .llong .compat_sys_socketcall
.llong .sys32_syslog .llong .sys32_syslog
.llong .compat_sys_setitimer .llong .compat_sys_setitimer
.llong .compat_sys_getitimer /* 105 */ .llong .compat_sys_getitimer /* 105 */
......
...@@ -25,7 +25,7 @@ _GLOBAL(ppc32_lseek) ...@@ -25,7 +25,7 @@ _GLOBAL(ppc32_lseek)
extsw r4,r4 /* sign extend off_t offset parm */ extsw r4,r4 /* sign extend off_t offset parm */
b .sys_lseek b .sys_lseek
_GLOBAL(sys32_socketcall) /* r3=call, r4=args */ _GLOBAL(compat_sys_socketcall) /* r3=call, r4=args */
cmpwi r3, 1 cmpwi r3, 1
blt- .do_einval blt- .do_einval
cmpwi r3, 17 cmpwi r3, 17
...@@ -221,14 +221,14 @@ _STATIC(do_sys_shutdown) /* sys_shutdown(int, int) */ ...@@ -221,14 +221,14 @@ _STATIC(do_sys_shutdown) /* sys_shutdown(int, int) */
.llong 2b,.do_efault .llong 2b,.do_efault
.previous .previous
_STATIC(do_sys_setsockopt) /* sys32_setsockopt(int, int, int, char *, int) */ _STATIC(do_sys_setsockopt) /* compat_sys_setsockopt(int, int, int, char *, int) */
mr r10,r4 mr r10,r4
1: lwa r3,0(r10) 1: lwa r3,0(r10)
2: lwa r4,4(r10) 2: lwa r4,4(r10)
3: lwa r5,8(r10) 3: lwa r5,8(r10)
4: lwz r6,12(r10) 4: lwz r6,12(r10)
5: lwa r7,16(r10) 5: lwa r7,16(r10)
b .sys32_setsockopt b .compat_sys_setsockopt
.section __ex_table,"a" .section __ex_table,"a"
.align 3 .align 3
.llong 1b,.do_efault .llong 1b,.do_efault
...@@ -238,14 +238,14 @@ _STATIC(do_sys_setsockopt) /* sys32_setsockopt(int, int, int, char *, int) */ ...@@ -238,14 +238,14 @@ _STATIC(do_sys_setsockopt) /* sys32_setsockopt(int, int, int, char *, int) */
.llong 5b,.do_efault .llong 5b,.do_efault
.previous .previous
_STATIC(do_sys_getsockopt) /* sys32_getsockopt(int, int, int, u32, u32) */ _STATIC(do_sys_getsockopt) /* compat_sys_getsockopt(int, int, int, u32, u32) */
mr r10,r4 mr r10,r4
1: lwa r3,0(r10) 1: lwa r3,0(r10)
2: lwa r4,4(r10) 2: lwa r4,4(r10)
3: lwa r5,8(r10) 3: lwa r5,8(r10)
4: lwz r6,12(r10) 4: lwz r6,12(r10)
5: lwz r7,16(r10) 5: lwz r7,16(r10)
b .sys32_getsockopt b .compat_sys_getsockopt
.section __ex_table,"a" .section __ex_table,"a"
.align 3 .align 3
.llong 1b,.do_efault .llong 1b,.do_efault
...@@ -255,12 +255,12 @@ _STATIC(do_sys_getsockopt) /* sys32_getsockopt(int, int, int, u32, u32) */ ...@@ -255,12 +255,12 @@ _STATIC(do_sys_getsockopt) /* sys32_getsockopt(int, int, int, u32, u32) */
.llong 5b,.do_efault .llong 5b,.do_efault
.previous .previous
_STATIC(do_sys_sendmsg) /* sys32_sendmsg(int, struct msghdr32 *, unsigned int) */ _STATIC(do_sys_sendmsg) /* compat_sys_sendmsg(int, struct compat_msghdr *, unsigned int) */
mr r10,r4 mr r10,r4
1: lwa r3,0(r10) 1: lwa r3,0(r10)
2: lwz r4,4(r10) 2: lwz r4,4(r10)
3: lwa r5,8(r10) 3: lwa r5,8(r10)
b .sys32_sendmsg b .compat_sys_sendmsg
.section __ex_table,"a" .section __ex_table,"a"
.align 3 .align 3
.llong 1b,.do_efault .llong 1b,.do_efault
...@@ -268,12 +268,12 @@ _STATIC(do_sys_sendmsg) /* sys32_sendmsg(int, struct msghdr32 *, unsigned int) * ...@@ -268,12 +268,12 @@ _STATIC(do_sys_sendmsg) /* sys32_sendmsg(int, struct msghdr32 *, unsigned int) *
.llong 3b,.do_efault .llong 3b,.do_efault
.previous .previous
_STATIC(do_sys_recvmsg) /* sys32_recvmsg(int, struct msghdr32 *, unsigned int) */ _STATIC(do_sys_recvmsg) /* compat_sys_recvmsg(int, struct compat_msghdr *, unsigned int) */
mr r10,r4 mr r10,r4
1: lwa r3,0(r10) 1: lwa r3,0(r10)
2: lwz r4,4(r10) 2: lwz r4,4(r10)
3: lwa r5,8(r10) 3: lwa r5,8(r10)
b .sys32_recvmsg b .compat_sys_recvmsg
.section __ex_table,"a" .section __ex_table,"a"
.align 3 .align 3
.llong 1b,.do_efault .llong 1b,.do_efault
......
This diff is collapsed.
...@@ -499,7 +499,7 @@ sys_call_table: ...@@ -499,7 +499,7 @@ sys_call_table:
.long SYSCALL(sys_statfs,compat_sys_statfs_wrapper) .long SYSCALL(sys_statfs,compat_sys_statfs_wrapper)
.long SYSCALL(sys_fstatfs,compat_sys_fstatfs_wrapper) /* 100 */ .long SYSCALL(sys_fstatfs,compat_sys_fstatfs_wrapper) /* 100 */
.long SYSCALL(sys_ni_syscall,sys_ni_syscall) .long SYSCALL(sys_ni_syscall,sys_ni_syscall)
.long SYSCALL(sys_socketcall,sys32_socketcall_wrapper) .long SYSCALL(sys_socketcall,compat_sys_socketcall_wrapper)
.long SYSCALL(sys_syslog,sys32_syslog_wrapper) .long SYSCALL(sys_syslog,sys32_syslog_wrapper)
.long SYSCALL(sys_setitimer,compat_sys_setitimer_wrapper) .long SYSCALL(sys_setitimer,compat_sys_setitimer_wrapper)
.long SYSCALL(sys_getitimer,compat_sys_getitimer_wrapper) /* 105 */ .long SYSCALL(sys_getitimer,compat_sys_getitimer_wrapper) /* 105 */
......
This diff is collapsed.
...@@ -452,11 +452,11 @@ compat_sys_fstatfs_wrapper: ...@@ -452,11 +452,11 @@ compat_sys_fstatfs_wrapper:
llgtr %r3,%r3 # struct compat_statfs * llgtr %r3,%r3 # struct compat_statfs *
jg compat_sys_fstatfs # branch to system call jg compat_sys_fstatfs # branch to system call
.globl sys32_socketcall_wrapper .globl compat_sys_socketcall_wrapper
sys32_socketcall_wrapper: compat_sys_socketcall_wrapper:
lgfr %r2,%r2 # int lgfr %r2,%r2 # int
llgtr %r3,%r3 # u32 * llgtr %r3,%r3 # u32 *
jg sys32_socketcall # branch to system call jg compat_sys_socketcall # branch to system call
.globl sys32_syslog_wrapper .globl sys32_syslog_wrapper
sys32_syslog_wrapper: sys32_syslog_wrapper:
......
...@@ -202,38 +202,38 @@ do_sys_shutdown: /* sys_shutdown(int, int) */ ...@@ -202,38 +202,38 @@ do_sys_shutdown: /* sys_shutdown(int, int) */
nop nop
nop nop
nop nop
do_sys_setsockopt: /* sys32_setsockopt(int, int, int, char *, int) */ do_sys_setsockopt: /* compat_sys_setsockopt(int, int, int, char *, int) */
ldswa [%o1 + 0x0] %asi, %o0 ldswa [%o1 + 0x0] %asi, %o0
sethi %hi(sys32_setsockopt), %g1 sethi %hi(compat_sys_setsockopt), %g1
ldswa [%o1 + 0x8] %asi, %o2 ldswa [%o1 + 0x8] %asi, %o2
lduwa [%o1 + 0xc] %asi, %o3 lduwa [%o1 + 0xc] %asi, %o3
ldswa [%o1 + 0x10] %asi, %o4 ldswa [%o1 + 0x10] %asi, %o4
jmpl %g1 + %lo(sys32_setsockopt), %g0 jmpl %g1 + %lo(compat_sys_setsockopt), %g0
ldswa [%o1 + 0x4] %asi, %o1 ldswa [%o1 + 0x4] %asi, %o1
nop nop
do_sys_getsockopt: /* sys32_getsockopt(int, int, int, u32, u32) */ do_sys_getsockopt: /* compat_sys_getsockopt(int, int, int, u32, u32) */
ldswa [%o1 + 0x0] %asi, %o0 ldswa [%o1 + 0x0] %asi, %o0
sethi %hi(sys32_getsockopt), %g1 sethi %hi(compat_sys_getsockopt), %g1
ldswa [%o1 + 0x8] %asi, %o2 ldswa [%o1 + 0x8] %asi, %o2
lduwa [%o1 + 0xc] %asi, %o3 lduwa [%o1 + 0xc] %asi, %o3
lduwa [%o1 + 0x10] %asi, %o4 lduwa [%o1 + 0x10] %asi, %o4
jmpl %g1 + %lo(sys32_getsockopt), %g0 jmpl %g1 + %lo(compat_sys_getsockopt), %g0
ldswa [%o1 + 0x4] %asi, %o1 ldswa [%o1 + 0x4] %asi, %o1
nop nop
do_sys_sendmsg: /* sys32_sendmsg(int, struct msghdr32 *, unsigned int) */ do_sys_sendmsg: /* compat_sys_sendmsg(int, struct compat_msghdr *, unsigned int) */
ldswa [%o1 + 0x0] %asi, %o0 ldswa [%o1 + 0x0] %asi, %o0
sethi %hi(sys32_sendmsg), %g1 sethi %hi(compat_sys_sendmsg), %g1
lduwa [%o1 + 0x8] %asi, %o2 lduwa [%o1 + 0x8] %asi, %o2
jmpl %g1 + %lo(sys32_sendmsg), %g0 jmpl %g1 + %lo(compat_sys_sendmsg), %g0
lduwa [%o1 + 0x4] %asi, %o1 lduwa [%o1 + 0x4] %asi, %o1
nop nop
nop nop
nop nop
do_sys_recvmsg: /* sys32_recvmsg(int, struct msghdr32 *, unsigned int) */ do_sys_recvmsg: /* compat_sys_recvmsg(int, struct compat_msghdr *, unsigned int) */
ldswa [%o1 + 0x0] %asi, %o0 ldswa [%o1 + 0x0] %asi, %o0
sethi %hi(sys32_recvmsg), %g1 sethi %hi(compat_sys_recvmsg), %g1
lduwa [%o1 + 0x8] %asi, %o2 lduwa [%o1 + 0x8] %asi, %o2
jmpl %g1 + %lo(sys32_recvmsg), %g0 jmpl %g1 + %lo(compat_sys_recvmsg), %g0
lduwa [%o1 + 0x4] %asi, %o1 lduwa [%o1 + 0x4] %asi, %o1
nop nop
nop nop
......
This diff is collapsed.
...@@ -54,6 +54,7 @@ ...@@ -54,6 +54,7 @@
#include <linux/personality.h> #include <linux/personality.h>
/* For SOCKET_I */ /* For SOCKET_I */
#include <linux/socket.h>
#include <net/sock.h> #include <net/sock.h>
/* Use this to get at 32-bit user passed pointers. */ /* Use this to get at 32-bit user passed pointers. */
...@@ -1324,8 +1325,6 @@ asmlinkage int sunos_sigaction (int sig, u32 act, u32 oact) ...@@ -1324,8 +1325,6 @@ asmlinkage int sunos_sigaction (int sig, u32 act, u32 oact)
extern asmlinkage int sys_setsockopt(int fd, int level, int optname, extern asmlinkage int sys_setsockopt(int fd, int level, int optname,
char *optval, int optlen); char *optval, int optlen);
extern asmlinkage int sys32_getsockopt(int fd, int level, int optname,
u32 optval, u32 optlen);
asmlinkage int sunos_setsockopt(int fd, int level, int optname, u32 optval, asmlinkage int sunos_setsockopt(int fd, int level, int optname, u32 optval,
int optlen) int optlen)
...@@ -1353,6 +1352,6 @@ asmlinkage int sunos_getsockopt(int fd, int level, int optname, ...@@ -1353,6 +1352,6 @@ asmlinkage int sunos_getsockopt(int fd, int level, int optname,
if (tr_opt >=2 && tr_opt <= 6) if (tr_opt >=2 && tr_opt <= 6)
tr_opt += 30; tr_opt += 30;
} }
ret = sys32_getsockopt(fd, level, tr_opt, optval, optlen); ret = compat_sys_getsockopt(fd, level, tr_opt, (void*)(unsigned long)optval, (void*)(unsigned long)optlen);
return ret; return ret;
} }
...@@ -179,7 +179,7 @@ sunos_sys_table: ...@@ -179,7 +179,7 @@ sunos_sys_table:
.word sunos_nosys, sys_bind, sunos_setsockopt .word sunos_nosys, sys_bind, sunos_setsockopt
.word sys_listen, sunos_nosys, sunos_sigaction .word sys_listen, sunos_nosys, sunos_sigaction
.word sunos_sigblock, sunos_sigsetmask, sys_sigpause .word sunos_sigblock, sunos_sigsetmask, sys_sigpause
.word sys32_sigstack, sys32_recvmsg, sys32_sendmsg .word sys32_sigstack, compat_sys_recvmsg, compat_sys_sendmsg
.word sunos_nosys, sys32_gettimeofday, sys32_getrusage .word sunos_nosys, sys32_gettimeofday, sys32_getrusage
.word sunos_getsockopt, sunos_nosys, sunos_readv .word sunos_getsockopt, sunos_nosys, sunos_readv
.word sunos_writev, sys32_settimeofday, sys32_fchown16 .word sunos_writev, sys32_settimeofday, sys32_fchown16
......
...@@ -267,13 +267,8 @@ struct sol_cmsghdr { ...@@ -267,13 +267,8 @@ struct sol_cmsghdr {
unsigned char cmsg_data[0]; unsigned char cmsg_data[0];
}; };
struct iovec32 {
u32 iov_base;
u32 iov_len;
};
static inline int iov_from_user32_to_kern(struct iovec *kiov, static inline int iov_from_user32_to_kern(struct iovec *kiov,
struct iovec32 *uiov32, struct compat_iovec *uiov32,
int niov) int niov)
{ {
int tot_len = 0; int tot_len = 0;
...@@ -322,7 +317,7 @@ static inline int msghdr_from_user32_to_kern(struct msghdr *kmsg, ...@@ -322,7 +317,7 @@ static inline int msghdr_from_user32_to_kern(struct msghdr *kmsg,
} }
/* I've named the args so it is easy to tell whose space the pointers are in. */ /* I've named the args so it is easy to tell whose space the pointers are in. */
static int verify_iovec32(struct msghdr *kern_msg, struct iovec *kern_iov, static int verify_compat_iovec(struct msghdr *kern_msg, struct iovec *kern_iov,
char *kern_address, int mode) char *kern_address, int mode)
{ {
int tot_len; int tot_len;
...@@ -347,7 +342,7 @@ static int verify_iovec32(struct msghdr *kern_msg, struct iovec *kern_iov, ...@@ -347,7 +342,7 @@ static int verify_iovec32(struct msghdr *kern_msg, struct iovec *kern_iov,
} }
tot_len = iov_from_user32_to_kern(kern_iov, tot_len = iov_from_user32_to_kern(kern_iov,
(struct iovec32 *)kern_msg->msg_iov, (struct compat_iovec *)kern_msg->msg_iov,
kern_msg->msg_iovlen); kern_msg->msg_iovlen);
if(tot_len >= 0) if(tot_len >= 0)
kern_msg->msg_iov = kern_iov; kern_msg->msg_iov = kern_iov;
...@@ -371,7 +366,7 @@ asmlinkage int solaris_sendmsg(int fd, struct sol_nmsghdr *user_msg, unsigned us ...@@ -371,7 +366,7 @@ asmlinkage int solaris_sendmsg(int fd, struct sol_nmsghdr *user_msg, unsigned us
return -EFAULT; return -EFAULT;
if(kern_msg.msg_iovlen > UIO_MAXIOV) if(kern_msg.msg_iovlen > UIO_MAXIOV)
return -EINVAL; return -EINVAL;
err = verify_iovec32(&kern_msg, iov, address, VERIFY_READ); err = verify_compat_iovec(&kern_msg, iov, address, VERIFY_READ);
if (err < 0) if (err < 0)
goto out; goto out;
total_len = err; total_len = err;
...@@ -439,7 +434,7 @@ asmlinkage int solaris_recvmsg(int fd, struct sol_nmsghdr *user_msg, unsigned in ...@@ -439,7 +434,7 @@ asmlinkage int solaris_recvmsg(int fd, struct sol_nmsghdr *user_msg, unsigned in
uaddr = kern_msg.msg_name; uaddr = kern_msg.msg_name;
uaddr_len = &user_msg->msg_namelen; uaddr_len = &user_msg->msg_namelen;
err = verify_iovec32(&kern_msg, iov, addr, VERIFY_WRITE); err = verify_compat_iovec(&kern_msg, iov, addr, VERIFY_WRITE);
if (err < 0) if (err < 0)
goto out; goto out;
total_len = err; total_len = err;
......
...@@ -4,4 +4,4 @@ ...@@ -4,4 +4,4 @@
obj-$(CONFIG_IA32_EMULATION) := ia32entry.o sys_ia32.o ia32_ioctl.o \ obj-$(CONFIG_IA32_EMULATION) := ia32entry.o sys_ia32.o ia32_ioctl.o \
ia32_signal.o \ ia32_signal.o \
ia32_binfmt.o fpu32.o socket32.o ptrace32.o ipc32.o syscall32.o ia32_binfmt.o fpu32.o ptrace32.o ipc32.o syscall32.o
...@@ -302,7 +302,7 @@ ia32_sys_call_table: ...@@ -302,7 +302,7 @@ ia32_sys_call_table:
.quad compat_sys_statfs .quad compat_sys_statfs
.quad compat_sys_fstatfs /* 100 */ .quad compat_sys_fstatfs /* 100 */
.quad sys_ioperm .quad sys_ioperm
.quad sys32_socketcall .quad compat_sys_socketcall
.quad sys_syslog .quad sys_syslog
.quad compat_sys_setitimer .quad compat_sys_setitimer
.quad compat_sys_getitimer /* 105 */ .quad compat_sys_getitimer /* 105 */
......
...@@ -738,7 +738,7 @@ asmlinkage ssize_t sys_readv(unsigned long,const struct iovec *,unsigned long); ...@@ -738,7 +738,7 @@ asmlinkage ssize_t sys_readv(unsigned long,const struct iovec *,unsigned long);
asmlinkage ssize_t sys_writev(unsigned long,const struct iovec *,unsigned long); asmlinkage ssize_t sys_writev(unsigned long,const struct iovec *,unsigned long);
static struct iovec * static struct iovec *
get_iovec32(struct iovec32 *iov32, struct iovec *iov_buf, u32 count, int type, int *errp) get_compat_iovec(struct compat_iovec *iov32, struct iovec *iov_buf, u32 count, int type, int *errp)
{ {
int i; int i;
u32 buf, len; u32 buf, len;
...@@ -751,7 +751,7 @@ get_iovec32(struct iovec32 *iov32, struct iovec *iov_buf, u32 count, int type, i ...@@ -751,7 +751,7 @@ get_iovec32(struct iovec32 *iov32, struct iovec *iov_buf, u32 count, int type, i
return 0; return 0;
if (count > UIO_MAXIOV) if (count > UIO_MAXIOV)
return(struct iovec *)0; return(struct iovec *)0;
if(verify_area(VERIFY_READ, iov32, sizeof(struct iovec32)*count)) if(verify_area(VERIFY_READ, iov32, sizeof(struct compat_iovec)*count))
return(struct iovec *)0; return(struct iovec *)0;
if (count > UIO_FASTIOV) { if (count > UIO_FASTIOV) {
*errp = -ENOMEM; *errp = -ENOMEM;
...@@ -792,14 +792,14 @@ get_iovec32(struct iovec32 *iov32, struct iovec *iov_buf, u32 count, int type, i ...@@ -792,14 +792,14 @@ get_iovec32(struct iovec32 *iov32, struct iovec *iov_buf, u32 count, int type, i
} }
asmlinkage long asmlinkage long
sys32_readv(int fd, struct iovec32 *vector, u32 count) sys32_readv(int fd, struct compat_iovec *vector, u32 count)
{ {
struct iovec iovstack[UIO_FASTIOV]; struct iovec iovstack[UIO_FASTIOV];
struct iovec *iov; struct iovec *iov;
int ret; int ret;
mm_segment_t old_fs = get_fs(); mm_segment_t old_fs = get_fs();
if ((iov = get_iovec32(vector, iovstack, count, VERIFY_WRITE, &ret)) == NULL) if ((iov = get_compat_iovec(vector, iovstack, count, VERIFY_WRITE, &ret)) == NULL)
return ret; return ret;
set_fs(KERNEL_DS); set_fs(KERNEL_DS);
ret = sys_readv(fd, iov, count); ret = sys_readv(fd, iov, count);
...@@ -810,14 +810,14 @@ sys32_readv(int fd, struct iovec32 *vector, u32 count) ...@@ -810,14 +810,14 @@ sys32_readv(int fd, struct iovec32 *vector, u32 count)
} }
asmlinkage long asmlinkage long
sys32_writev(int fd, struct iovec32 *vector, u32 count) sys32_writev(int fd, struct compat_iovec *vector, u32 count)
{ {
struct iovec iovstack[UIO_FASTIOV]; struct iovec iovstack[UIO_FASTIOV];
struct iovec *iov; struct iovec *iov;
int ret; int ret;
mm_segment_t old_fs = get_fs(); mm_segment_t old_fs = get_fs();
if ((iov = get_iovec32(vector, iovstack, count, VERIFY_READ, &ret)) == NULL) if ((iov = get_compat_iovec(vector, iovstack, count, VERIFY_READ, &ret)) == NULL)
return ret; return ret;
set_fs(KERNEL_DS); set_fs(KERNEL_DS);
ret = sys_writev(fd, iov, count); ret = sys_writev(fd, iov, count);
......
...@@ -777,7 +777,7 @@ int pppoe_ioctl(struct socket *sock, unsigned int cmd, ...@@ -777,7 +777,7 @@ int pppoe_ioctl(struct socket *sock, unsigned int cmd,
int pppoe_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m, int pppoe_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
int total_len, struct scm_cookie *scm) int total_len)
{ {
struct sk_buff *skb = NULL; struct sk_buff *skb = NULL;
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
...@@ -937,7 +937,8 @@ int pppoe_xmit(struct ppp_channel *chan, struct sk_buff *skb) ...@@ -937,7 +937,8 @@ int pppoe_xmit(struct ppp_channel *chan, struct sk_buff *skb)
struct ppp_channel_ops pppoe_chan_ops = { pppoe_xmit , NULL }; struct ppp_channel_ops pppoe_chan_ops = { pppoe_xmit , NULL };
int pppoe_rcvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m, int total_len, int flags, struct scm_cookie *scm) int pppoe_recvmsg(struct kiocb *iocb, struct socket *sock,
struct msghdr *m, int total_len, int flags)
{ {
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
struct sk_buff *skb = NULL; struct sk_buff *skb = NULL;
...@@ -1089,7 +1090,7 @@ struct proto_ops pppoe_ops = { ...@@ -1089,7 +1090,7 @@ struct proto_ops pppoe_ops = {
.setsockopt = sock_no_setsockopt, .setsockopt = sock_no_setsockopt,
.getsockopt = sock_no_getsockopt, .getsockopt = sock_no_getsockopt,
.sendmsg = pppoe_sendmsg, .sendmsg = pppoe_sendmsg,
.recvmsg = pppoe_rcvmsg, .recvmsg = pppoe_recvmsg,
.mmap = sock_no_mmap .mmap = sock_no_mmap
}; };
......
...@@ -41,8 +41,6 @@ _recvfrom(struct socket *socket, unsigned char *ubuf, int size, unsigned flags) ...@@ -41,8 +41,6 @@ _recvfrom(struct socket *socket, unsigned char *ubuf, int size, unsigned flags)
{ {
struct iovec iov; struct iovec iov;
struct msghdr msg; struct msghdr msg;
struct kiocb iocb;
struct sock_iocb *si;
mm_segment_t fs; mm_segment_t fs;
fs = get_fs(); fs = get_fs();
...@@ -58,21 +56,7 @@ _recvfrom(struct socket *socket, unsigned char *ubuf, int size, unsigned flags) ...@@ -58,21 +56,7 @@ _recvfrom(struct socket *socket, unsigned char *ubuf, int size, unsigned flags)
iov.iov_base = ubuf; iov.iov_base = ubuf;
iov.iov_len = size; iov.iov_len = size;
init_sync_kiocb(&iocb, NULL); size = sock_recvmsg(socket, &msg, size, flags);
si = kiocb_to_siocb(&iocb);
si->sock = socket;
si->scm = &si->async_scm;
si->msg = &msg;
si->size = size;
si->flags = flags;
memset(si->scm, 0, sizeof(*si->scm));
size = socket->ops->recvmsg(&iocb, socket, &msg, size, flags, si->scm);
if (size >= 0)
scm_recv(socket, &msg, si->scm, flags);
if (-EIOCBQUEUED == size)
size = wait_on_sync_kiocb(&iocb);
set_fs(fs); set_fs(fs);
return size; return size;
...@@ -299,8 +283,6 @@ smb_receive_drop(struct smb_sb_info *server) ...@@ -299,8 +283,6 @@ smb_receive_drop(struct smb_sb_info *server)
unsigned int flags; unsigned int flags;
struct iovec iov; struct iovec iov;
struct msghdr msg; struct msghdr msg;
struct kiocb iocb;
struct sock_iocb *si;
mm_segment_t fs; mm_segment_t fs;
int rlen = smb_len(server->header) - server->smb_read + 4; int rlen = smb_len(server->header) - server->smb_read + 4;
int result = -EIO; int result = -EIO;
...@@ -327,21 +309,7 @@ smb_receive_drop(struct smb_sb_info *server) ...@@ -327,21 +309,7 @@ smb_receive_drop(struct smb_sb_info *server)
if (rlen > PAGE_SIZE) if (rlen > PAGE_SIZE)
rlen = PAGE_SIZE; rlen = PAGE_SIZE;
init_sync_kiocb(&iocb, NULL); result = sock_recvmsg(sock, &msg, rlen, flags);
si = kiocb_to_siocb(&iocb);
si->sock = sock;
si->scm = &si->async_scm;
si->msg = &msg;
si->size = rlen;
si->flags = flags;
memset(si->scm, 0, sizeof(*si->scm));
result = sock->ops->recvmsg(&iocb, sock, &msg, rlen, flags, si->scm);
if (result >= 0)
scm_recv(sock, &msg, si->scm, flags);
if (-EIOCBQUEUED == result)
result = wait_on_sync_kiocb(&iocb);
set_fs(fs); set_fs(fs);
...@@ -370,8 +338,6 @@ smb_receive(struct smb_sb_info *server, struct smb_request *req) ...@@ -370,8 +338,6 @@ smb_receive(struct smb_sb_info *server, struct smb_request *req)
unsigned int flags; unsigned int flags;
struct iovec iov[4]; struct iovec iov[4];
struct msghdr msg; struct msghdr msg;
struct kiocb iocb;
struct sock_iocb *si;
mm_segment_t fs; mm_segment_t fs;
int rlen; int rlen;
int result = -EIO; int result = -EIO;
...@@ -398,21 +364,7 @@ smb_receive(struct smb_sb_info *server, struct smb_request *req) ...@@ -398,21 +364,7 @@ smb_receive(struct smb_sb_info *server, struct smb_request *req)
if (req->rq_rlen < rlen) if (req->rq_rlen < rlen)
rlen = req->rq_rlen; rlen = req->rq_rlen;
init_sync_kiocb(&iocb, NULL); result = sock_recvmsg(sock, &msg, rlen, flags);
si = kiocb_to_siocb(&iocb);
si->sock = sock;
si->scm = &si->async_scm;
si->msg = &msg;
si->size = rlen;
si->flags = flags;
memset(si->scm, 0, sizeof(*si->scm));
result = sock->ops->recvmsg(&iocb, sock, &msg, rlen, flags, si->scm);
if (result >= 0)
scm_recv(sock, &msg, si->scm, flags);
if (-EIOCBQUEUED == result)
result = wait_on_sync_kiocb(&iocb);
set_fs(fs); set_fs(fs);
...@@ -440,8 +392,6 @@ smb_send_request(struct smb_request *req) ...@@ -440,8 +392,6 @@ smb_send_request(struct smb_request *req)
mm_segment_t fs; mm_segment_t fs;
struct smb_sb_info *server = req->rq_server; struct smb_sb_info *server = req->rq_server;
struct socket *sock; struct socket *sock;
struct kiocb iocb;
struct sock_iocb *si;
struct msghdr msg; struct msghdr msg;
int slen = req->rq_slen - req->rq_bytes_sent; int slen = req->rq_slen - req->rq_bytes_sent;
int result = -EIO; int result = -EIO;
...@@ -465,23 +415,9 @@ smb_send_request(struct smb_request *req) ...@@ -465,23 +415,9 @@ smb_send_request(struct smb_request *req)
if (req->rq_bytes_sent) if (req->rq_bytes_sent)
smb_move_iov(&msg, iov, req->rq_bytes_sent); smb_move_iov(&msg, iov, req->rq_bytes_sent);
init_sync_kiocb(&iocb, NULL);
si = kiocb_to_siocb(&iocb);
si->scm = &si->async_scm;
si->sock = sock;
si->msg = &msg;
si->size = slen;
fs = get_fs(); fs = get_fs();
set_fs(get_ds()); set_fs(get_ds());
result = scm_send(sock, &msg, si->scm); result = sock_sendmsg(sock, &msg, slen);
if (result >= 0) {
result = sock->ops->sendmsg(&iocb, sock, &msg, slen, si->scm);
if (-EIOCBQUEUED != result)
scm_destroy(si->scm);
}
if (-EIOCBQUEUED == result)
result = wait_on_sync_kiocb(&iocb);
set_fs(fs); set_fs(fs);
if (result >= 0) { if (result >= 0) {
......
...@@ -153,11 +153,6 @@ struct ustat32 { ...@@ -153,11 +153,6 @@ struct ustat32 {
char f_fpack[6]; char f_fpack[6];
}; };
struct iovec32 {
unsigned int iov_base;
int iov_len;
};
#define IA32_PAGE_OFFSET 0xffffe000 #define IA32_PAGE_OFFSET 0xffffe000
#define IA32_STACK_TOP IA32_PAGE_OFFSET #define IA32_STACK_TOP IA32_PAGE_OFFSET
......
#ifndef SOCKET32_H
#define SOCKET32_H 1
#include <linux/compat.h>
/* XXX This really belongs in some header file... -DaveM */
#define MAX_SOCK_ADDR 128 /* 108 for Unix domain -
16 for IP, 16 for IPX,
24 for IPv6,
about 80 for AX.25 */
struct msghdr32 {
u32 msg_name;
int msg_namelen;
u32 msg_iov;
compat_size_t msg_iovlen;
u32 msg_control;
compat_size_t msg_controllen;
unsigned msg_flags;
};
struct cmsghdr32 {
compat_size_t cmsg_len;
int cmsg_level;
int cmsg_type;
};
/* Bleech... */
#define __CMSG32_NXTHDR(ctl, len, cmsg, cmsglen) __cmsg32_nxthdr((ctl),(len),(cmsg),(cmsglen))
#define CMSG32_NXTHDR(mhdr, cmsg, cmsglen) cmsg32_nxthdr((mhdr), (cmsg), (cmsglen))
#define CMSG32_ALIGN(len) ( ((len)+sizeof(int)-1) & ~(sizeof(int)-1) )
#define CMSG32_DATA(cmsg) ((void *)((char *)(cmsg) + CMSG32_ALIGN(sizeof(struct cmsghdr32))))
#define CMSG32_SPACE(len) (CMSG32_ALIGN(sizeof(struct cmsghdr32)) + CMSG32_ALIGN(len))
#define CMSG32_LEN(len) (CMSG32_ALIGN(sizeof(struct cmsghdr32)) + (len))
#define __CMSG32_FIRSTHDR(ctl,len) ((len) >= sizeof(struct cmsghdr32) ? \
(struct cmsghdr32 *)(ctl) : \
(struct cmsghdr32 *)NULL)
#define CMSG32_FIRSTHDR(msg) __CMSG32_FIRSTHDR((msg)->msg_control, (msg)->msg_controllen)
__inline__ struct cmsghdr32 *__cmsg32_nxthdr(void *__ctl, __kernel_size_t __size,
struct cmsghdr32 *__cmsg, int __cmsg_len)
{
struct cmsghdr32 * __ptr;
__ptr = (struct cmsghdr32 *)(((unsigned char *) __cmsg) +
CMSG32_ALIGN(__cmsg_len));
if ((unsigned long)((char*)(__ptr+1) - (char *) __ctl) > __size)
return NULL;
return __ptr;
}
__inline__ struct cmsghdr32 *cmsg32_nxthdr (struct msghdr *__msg,
struct cmsghdr32 *__cmsg,
int __cmsg_len)
{
return __cmsg32_nxthdr(__msg->msg_control, __msg->msg_controllen,
__cmsg, __cmsg_len);
}
#endif
...@@ -45,5 +45,12 @@ extern int put_compat_flock(struct flock *, struct compat_flock *); ...@@ -45,5 +45,12 @@ extern int put_compat_flock(struct flock *, struct compat_flock *);
extern int get_compat_timespec(struct timespec *, struct compat_timespec *); extern int get_compat_timespec(struct timespec *, struct compat_timespec *);
extern int put_compat_timespec(struct timespec *, struct compat_timespec *); extern int put_compat_timespec(struct timespec *, struct compat_timespec *);
struct compat_iovec {
u32 iov_base;
compat_size_t iov_len;
};
#else /* no CONFIG_COMPAT */
#define compat_size_t size_t
#endif /* CONFIG_COMPAT */ #endif /* CONFIG_COMPAT */
#endif /* _LINUX_COMPAT_H */ #endif /* _LINUX_COMPAT_H */
...@@ -78,7 +78,6 @@ struct socket ...@@ -78,7 +78,6 @@ struct socket
unsigned char passcred; unsigned char passcred;
}; };
struct scm_cookie;
struct vm_area_struct; struct vm_area_struct;
struct page; struct page;
struct kiocb; struct kiocb;
...@@ -106,11 +105,9 @@ struct proto_ops { ...@@ -106,11 +105,9 @@ struct proto_ops {
int (*getsockopt) (struct socket *sock, int level, int optname, int (*getsockopt) (struct socket *sock, int level, int optname,
char *optval, int *optlen); char *optval, int *optlen);
int (*sendmsg) (struct kiocb *iocb, struct socket *sock, int (*sendmsg) (struct kiocb *iocb, struct socket *sock,
struct msghdr *m, int total_len, struct msghdr *m, int total_len);
struct scm_cookie *scm);
int (*recvmsg) (struct kiocb *iocb, struct socket *sock, int (*recvmsg) (struct kiocb *iocb, struct socket *sock,
struct msghdr *m, int total_len, int flags, struct msghdr *m, int total_len, int flags);
struct scm_cookie *scm);
int (*mmap) (struct file *file, struct socket *sock, struct vm_area_struct * vma); int (*mmap) (struct file *file, struct socket *sock, struct vm_area_struct * vma);
ssize_t (*sendpage) (struct socket *sock, struct page *page, int offset, size_t size, int flags); ssize_t (*sendpage) (struct socket *sock, struct page *page, int offset, size_t size, int flags);
}; };
...@@ -202,10 +199,10 @@ SOCKCALL_WRAP(name, setsockopt, (struct socket *sock, int level, int optname, \ ...@@ -202,10 +199,10 @@ SOCKCALL_WRAP(name, setsockopt, (struct socket *sock, int level, int optname, \
char *optval, int optlen), (sock, level, optname, optval, optlen)) \ char *optval, int optlen), (sock, level, optname, optval, optlen)) \
SOCKCALL_WRAP(name, getsockopt, (struct socket *sock, int level, int optname, \ SOCKCALL_WRAP(name, getsockopt, (struct socket *sock, int level, int optname, \
char *optval, int *optlen), (sock, level, optname, optval, optlen)) \ char *optval, int *optlen), (sock, level, optname, optval, optlen)) \
SOCKCALL_WRAP(name, sendmsg, (struct kiocb *iocb, struct socket *sock, struct msghdr *m, int len, struct scm_cookie *scm), \ SOCKCALL_WRAP(name, sendmsg, (struct kiocb *iocb, struct socket *sock, struct msghdr *m, int len), \
(iocb, sock, m, len, scm)) \ (iocb, sock, m, len)) \
SOCKCALL_WRAP(name, recvmsg, (struct kiocb *iocb, struct socket *sock, struct msghdr *m, int len, int flags, struct scm_cookie *scm), \ SOCKCALL_WRAP(name, recvmsg, (struct kiocb *iocb, struct socket *sock, struct msghdr *m, int len, int flags), \
(iocb, sock, m, len, flags, scm)) \ (iocb, sock, m, len, flags)) \
SOCKCALL_WRAP(name, mmap, (struct file *file, struct socket *sock, struct vm_area_struct *vma), \ SOCKCALL_WRAP(name, mmap, (struct file *file, struct socket *sock, struct vm_area_struct *vma), \
(file, sock, vma)) \ (file, sock, vma)) \
\ \
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) #if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
#include <linux/linkage.h>
#include <asm/socket.h> /* arch-dependent defines */ #include <asm/socket.h> /* arch-dependent defines */
#include <linux/sockios.h> /* the SIOCxxx I/O controls */ #include <linux/sockios.h> /* the SIOCxxx I/O controls */
#include <linux/uio.h> /* iovec support */ #include <linux/uio.h> /* iovec support */
...@@ -234,6 +235,24 @@ struct ucred { ...@@ -234,6 +235,24 @@ struct ucred {
#define MSG_EOF MSG_FIN #define MSG_EOF MSG_FIN
#if defined(CONFIG_COMPAT)
#define MSG_CMSG_COMPAT 0x80000000 /* This message needs 32 bit fixups */
#else
#define MSG_CMSG_COMPAT 0 /* We never have 32 bit fixups */
#define compat_msghdr msghdr /* Needed to avoid compiler hoops */
#endif
struct compat_msghdr;
extern int msghdr_from_user_compat_to_kern(struct msghdr *, struct compat_msghdr *);
extern int verify_compat_iovec(struct msghdr *, struct iovec *, char *, int);
extern asmlinkage long compat_sys_sendmsg(int,struct compat_msghdr *,unsigned);
extern asmlinkage long compat_sys_recvmsg(int,struct compat_msghdr *,unsigned);
extern asmlinkage long sys_sendmsg(int fd, struct msghdr *msg, unsigned flags);
extern asmlinkage long sys_recvmsg(int fd, struct msghdr *msg, unsigned flags);
extern asmlinkage long compat_sys_getsockopt(int fd, int level, int optname,
char *optval, int *optlen);
/* Setsockoptions(2) level. Thanks to BSD these must match IPPROTO_xxx */ /* Setsockoptions(2) level. Thanks to BSD these must match IPPROTO_xxx */
#define SOL_IP 0 #define SOL_IP 0
...@@ -276,6 +295,11 @@ extern void memcpy_tokerneliovec(struct iovec *iov, unsigned char *kdata, int le ...@@ -276,6 +295,11 @@ extern void memcpy_tokerneliovec(struct iovec *iov, unsigned char *kdata, int le
extern int move_addr_to_user(void *kaddr, int klen, void *uaddr, int *ulen); extern int move_addr_to_user(void *kaddr, int klen, void *uaddr, int *ulen);
extern int move_addr_to_kernel(void *uaddr, int ulen, void *kaddr); extern int move_addr_to_kernel(void *uaddr, int ulen, void *kaddr);
extern int put_cmsg(struct msghdr*, int level, int type, int len, void *data); extern int put_cmsg(struct msghdr*, int level, int type, int len, void *data);
extern int put_cmsg_compat(struct msghdr*, int level, int type, int len, void *data);
extern void cmsg_compat_recvmsg_fixup(struct msghdr *kmsg, unsigned long orig_cmsg_uptr);
extern int cmsghdr_from_user_compat_to_kern(struct msghdr *kmsg,
unsigned char *stackbuf, int stackbuf_size);
#endif #endif
#endif /* not kernel and not glibc */ #endif /* not kernel and not glibc */
#endif /* _LINUX_SOCKET_H */ #endif /* _LINUX_SOCKET_H */
...@@ -128,7 +128,7 @@ int bt_sock_unregister(int proto); ...@@ -128,7 +128,7 @@ int bt_sock_unregister(int proto);
struct sock *bt_sock_alloc(struct socket *sock, int proto, int pi_size, int prio); struct sock *bt_sock_alloc(struct socket *sock, int proto, int pi_size, int prio);
void bt_sock_link(struct bt_sock_list *l, struct sock *s); void bt_sock_link(struct bt_sock_list *l, struct sock *s);
void bt_sock_unlink(struct bt_sock_list *l, struct sock *s); void bt_sock_unlink(struct bt_sock_list *l, struct sock *s);
int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, int len, int flags, struct scm_cookie *scm); int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, int len, int flags);
uint bt_sock_poll(struct file * file, struct socket *sock, poll_table *wait); uint bt_sock_poll(struct file * file, struct socket *sock, poll_table *wait);
int bt_sock_w4_connect(struct sock *sk, int flags); int bt_sock_w4_connect(struct sock *sk, int flags);
......
This diff is collapsed.
...@@ -23,11 +23,11 @@ extern int inet_accept(struct socket *sock, ...@@ -23,11 +23,11 @@ extern int inet_accept(struct socket *sock,
extern int inet_recvmsg(struct kiocb *iocb, extern int inet_recvmsg(struct kiocb *iocb,
struct socket *sock, struct socket *sock,
struct msghdr *ubuf, struct msghdr *ubuf,
int size, int flags, struct scm_cookie *scm); int size, int flags);
extern int inet_sendmsg(struct kiocb *iocb, extern int inet_sendmsg(struct kiocb *iocb,
struct socket *sock, struct socket *sock,
struct msghdr *msg, struct msghdr *msg,
int size, struct scm_cookie *scm); int size);
extern int inet_shutdown(struct socket *sock, int how); extern int inet_shutdown(struct socket *sock, int how);
extern unsigned int inet_poll(struct file * file, struct socket *sock, struct poll_table_struct *wait); extern unsigned int inet_poll(struct file * file, struct socket *sock, struct poll_table_struct *wait);
extern int inet_setsockopt(struct socket *sock, int level, extern int inet_setsockopt(struct socket *sock, int level,
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment