Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
675a53bd
K
Kernel
项目概览
openeuler
/
Kernel
1 年多 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
675a53bd
编写于
11月 21, 2014
作者:
D
David S. Miller
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'for-davem' of
git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
上级
abd40774
232365f6
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
114 addition
and
211 deletion
+114
-211
arch/arm/kernel/sys_oabi-compat.c
arch/arm/kernel/sys_oabi-compat.c
+2
-2
include/linux/socket.h
include/linux/socket.h
+13
-4
include/linux/syscalls.h
include/linux/syscalls.h
+3
-3
include/net/compat.h
include/net/compat.h
+2
-3
include/net/sock.h
include/net/sock.h
+0
-23
net/compat.c
net/compat.c
+27
-56
net/core/iovec.c
net/core/iovec.c
+0
-47
net/socket.c
net/socket.c
+67
-73
未找到文件。
arch/arm/kernel/sys_oabi-compat.c
浏览文件 @
675a53bd
...
...
@@ -400,7 +400,7 @@ asmlinkage long sys_oabi_sendto(int fd, void __user *buff,
return
sys_sendto
(
fd
,
buff
,
len
,
flags
,
addr
,
addrlen
);
}
asmlinkage
long
sys_oabi_sendmsg
(
int
fd
,
struct
msghdr
__user
*
msg
,
unsigned
flags
)
asmlinkage
long
sys_oabi_sendmsg
(
int
fd
,
struct
user_
msghdr
__user
*
msg
,
unsigned
flags
)
{
struct
sockaddr
__user
*
addr
;
int
msg_namelen
;
...
...
@@ -446,7 +446,7 @@ asmlinkage long sys_oabi_socketcall(int call, unsigned long __user *args)
break
;
case
SYS_SENDMSG
:
if
(
copy_from_user
(
a
,
args
,
3
*
sizeof
(
long
))
==
0
)
r
=
sys_oabi_sendmsg
(
a
[
0
],
(
struct
msghdr
__user
*
)
a
[
1
],
a
[
2
]);
r
=
sys_oabi_sendmsg
(
a
[
0
],
(
struct
user_
msghdr
__user
*
)
a
[
1
],
a
[
2
]);
break
;
default:
r
=
sys_socketcall
(
call
,
args
);
...
...
include/linux/socket.h
浏览文件 @
675a53bd
...
...
@@ -53,10 +53,20 @@ struct msghdr {
__kernel_size_t
msg_controllen
;
/* ancillary data buffer length */
unsigned
int
msg_flags
;
/* flags on received message */
};
struct
user_msghdr
{
void
__user
*
msg_name
;
/* ptr to socket address structure */
int
msg_namelen
;
/* size of socket address structure */
struct
iovec
__user
*
msg_iov
;
/* scatter/gather array */
__kernel_size_t
msg_iovlen
;
/* # elements in msg_iov */
void
__user
*
msg_control
;
/* ancillary data */
__kernel_size_t
msg_controllen
;
/* ancillary data buffer length */
unsigned
int
msg_flags
;
/* flags on received message */
};
/* For recvmmsg/sendmmsg */
struct
mmsghdr
{
struct
msghdr
msg_hdr
;
struct
user_msghdr
msg_hdr
;
unsigned
int
msg_len
;
};
...
...
@@ -312,15 +322,14 @@ extern int csum_partial_copy_fromiovecend(unsigned char *kdata,
extern
unsigned
long
iov_pages
(
const
struct
iovec
*
iov
,
int
offset
,
unsigned
long
nr_segs
);
extern
int
verify_iovec
(
struct
msghdr
*
m
,
struct
iovec
*
iov
,
struct
sockaddr_storage
*
address
,
int
mode
);
extern
int
move_addr_to_kernel
(
void
__user
*
uaddr
,
int
ulen
,
struct
sockaddr_storage
*
kaddr
);
extern
int
put_cmsg
(
struct
msghdr
*
,
int
level
,
int
type
,
int
len
,
void
*
data
);
struct
timespec
;
/* The __sys_...msg variants allow MSG_CMSG_COMPAT */
extern
long
__sys_recvmsg
(
int
fd
,
struct
msghdr
__user
*
msg
,
unsigned
flags
);
extern
long
__sys_sendmsg
(
int
fd
,
struct
msghdr
__user
*
msg
,
unsigned
flags
);
extern
long
__sys_recvmsg
(
int
fd
,
struct
user_
msghdr
__user
*
msg
,
unsigned
flags
);
extern
long
__sys_sendmsg
(
int
fd
,
struct
user_
msghdr
__user
*
msg
,
unsigned
flags
);
extern
int
__sys_recvmmsg
(
int
fd
,
struct
mmsghdr
__user
*
mmsg
,
unsigned
int
vlen
,
unsigned
int
flags
,
struct
timespec
*
timeout
);
extern
int
__sys_sendmmsg
(
int
fd
,
struct
mmsghdr
__user
*
mmsg
,
...
...
include/linux/syscalls.h
浏览文件 @
675a53bd
...
...
@@ -25,7 +25,7 @@ struct linux_dirent64;
struct
list_head
;
struct
mmap_arg_struct
;
struct
msgbuf
;
struct
msghdr
;
struct
user_
msghdr
;
struct
mmsghdr
;
struct
msqid_ds
;
struct
new_utsname
;
...
...
@@ -601,13 +601,13 @@ asmlinkage long sys_getpeername(int, struct sockaddr __user *, int __user *);
asmlinkage
long
sys_send
(
int
,
void
__user
*
,
size_t
,
unsigned
);
asmlinkage
long
sys_sendto
(
int
,
void
__user
*
,
size_t
,
unsigned
,
struct
sockaddr
__user
*
,
int
);
asmlinkage
long
sys_sendmsg
(
int
fd
,
struct
msghdr
__user
*
msg
,
unsigned
flags
);
asmlinkage
long
sys_sendmsg
(
int
fd
,
struct
user_
msghdr
__user
*
msg
,
unsigned
flags
);
asmlinkage
long
sys_sendmmsg
(
int
fd
,
struct
mmsghdr
__user
*
msg
,
unsigned
int
vlen
,
unsigned
flags
);
asmlinkage
long
sys_recv
(
int
,
void
__user
*
,
size_t
,
unsigned
);
asmlinkage
long
sys_recvfrom
(
int
,
void
__user
*
,
size_t
,
unsigned
,
struct
sockaddr
__user
*
,
int
__user
*
);
asmlinkage
long
sys_recvmsg
(
int
fd
,
struct
msghdr
__user
*
msg
,
unsigned
flags
);
asmlinkage
long
sys_recvmsg
(
int
fd
,
struct
user_
msghdr
__user
*
msg
,
unsigned
flags
);
asmlinkage
long
sys_recvmmsg
(
int
fd
,
struct
mmsghdr
__user
*
msg
,
unsigned
int
vlen
,
unsigned
flags
,
struct
timespec
__user
*
timeout
);
...
...
include/net/compat.h
浏览文件 @
675a53bd
...
...
@@ -40,9 +40,8 @@ int compat_sock_get_timestampns(struct sock *, struct timespec __user *);
#define compat_mmsghdr mmsghdr
#endif
/* defined(CONFIG_COMPAT) */
int
get_compat_msghdr
(
struct
msghdr
*
,
struct
compat_msghdr
__user
*
);
int
verify_compat_iovec
(
struct
msghdr
*
,
struct
iovec
*
,
struct
sockaddr_storage
*
,
int
);
ssize_t
get_compat_msghdr
(
struct
msghdr
*
,
struct
compat_msghdr
__user
*
,
struct
sockaddr
__user
**
,
struct
iovec
**
);
asmlinkage
long
compat_sys_sendmsg
(
int
,
struct
compat_msghdr
__user
*
,
unsigned
int
);
asmlinkage
long
compat_sys_sendmmsg
(
int
,
struct
compat_mmsghdr
__user
*
,
...
...
include/net/sock.h
浏览文件 @
675a53bd
...
...
@@ -1884,29 +1884,6 @@ static inline int skb_copy_to_page_nocache(struct sock *sk, char __user *from,
return
0
;
}
static
inline
int
skb_copy_to_page
(
struct
sock
*
sk
,
char
__user
*
from
,
struct
sk_buff
*
skb
,
struct
page
*
page
,
int
off
,
int
copy
)
{
if
(
skb
->
ip_summed
==
CHECKSUM_NONE
)
{
int
err
=
0
;
__wsum
csum
=
csum_and_copy_from_user
(
from
,
page_address
(
page
)
+
off
,
copy
,
0
,
&
err
);
if
(
err
)
return
err
;
skb
->
csum
=
csum_block_add
(
skb
->
csum
,
csum
,
skb
->
len
);
}
else
if
(
copy_from_user
(
page_address
(
page
)
+
off
,
from
,
copy
))
return
-
EFAULT
;
skb
->
len
+=
copy
;
skb
->
data_len
+=
copy
;
skb
->
truesize
+=
copy
;
sk
->
sk_wmem_queued
+=
copy
;
sk_mem_charge
(
sk
,
copy
);
return
0
;
}
/**
* sk_wmem_alloc_get - returns write allocations
* @sk: socket
...
...
net/compat.c
浏览文件 @
675a53bd
...
...
@@ -31,41 +31,18 @@
#include <asm/uaccess.h>
#include <net/compat.h>
static
inline
int
iov_from_user_compat_to_kern
(
struct
iovec
*
kiov
,
struct
compat_iovec
__user
*
uiov32
,
int
niov
)
ssize_t
get_compat_msghdr
(
struct
msghdr
*
kmsg
,
struct
compat_msghdr
__user
*
umsg
,
struct
sockaddr
__user
**
save_addr
,
struct
iovec
**
iov
)
{
int
tot_len
=
0
;
while
(
niov
>
0
)
{
compat_uptr_t
buf
;
compat_size_t
len
;
if
(
get_user
(
len
,
&
uiov32
->
iov_len
)
||
get_user
(
buf
,
&
uiov32
->
iov_base
))
return
-
EFAULT
;
if
(
len
>
INT_MAX
-
tot_len
)
len
=
INT_MAX
-
tot_len
;
tot_len
+=
len
;
kiov
->
iov_base
=
compat_ptr
(
buf
);
kiov
->
iov_len
=
(
__kernel_size_t
)
len
;
uiov32
++
;
kiov
++
;
niov
--
;
}
return
tot_len
;
}
int
get_compat_msghdr
(
struct
msghdr
*
kmsg
,
struct
compat_msghdr
__user
*
umsg
)
{
compat_uptr_t
tmp1
,
tmp2
,
tmp3
;
compat_uptr_t
uaddr
,
uiov
,
tmp3
;
ssize_t
err
;
if
(
!
access_ok
(
VERIFY_READ
,
umsg
,
sizeof
(
*
umsg
))
||
__get_user
(
tmp1
,
&
umsg
->
msg_name
)
||
__get_user
(
uaddr
,
&
umsg
->
msg_name
)
||
__get_user
(
kmsg
->
msg_namelen
,
&
umsg
->
msg_namelen
)
||
__get_user
(
tmp2
,
&
umsg
->
msg_iov
)
||
__get_user
(
uiov
,
&
umsg
->
msg_iov
)
||
__get_user
(
kmsg
->
msg_iovlen
,
&
umsg
->
msg_iovlen
)
||
__get_user
(
tmp3
,
&
umsg
->
msg_control
)
||
__get_user
(
kmsg
->
msg_controllen
,
&
umsg
->
msg_controllen
)
||
...
...
@@ -73,39 +50,33 @@ int get_compat_msghdr(struct msghdr *kmsg, struct compat_msghdr __user *umsg)
return
-
EFAULT
;
if
(
kmsg
->
msg_namelen
>
sizeof
(
struct
sockaddr_storage
))
kmsg
->
msg_namelen
=
sizeof
(
struct
sockaddr_storage
);
kmsg
->
msg_name
=
compat_ptr
(
tmp1
);
kmsg
->
msg_iov
=
compat_ptr
(
tmp2
);
kmsg
->
msg_control
=
compat_ptr
(
tmp3
);
return
0
;
}
/* I've named the args so it is easy to tell whose space the pointers are in. */
int
verify_compat_iovec
(
struct
msghdr
*
kern_msg
,
struct
iovec
*
kern_iov
,
struct
sockaddr_storage
*
kern_address
,
int
mode
)
{
int
tot_len
;
if
(
save_addr
)
*
save_addr
=
compat_ptr
(
uaddr
);
if
(
kern_msg
->
msg_name
&&
kern_
msg
->
msg_namelen
)
{
if
(
mode
==
VERIFY_READ
)
{
int
err
=
move_addr_to_kernel
(
kern_msg
->
msg_name
,
kern_
msg
->
msg_namelen
,
kern_address
);
if
(
uaddr
&&
k
msg
->
msg_namelen
)
{
if
(
!
save_addr
)
{
err
=
move_addr_to_kernel
(
compat_ptr
(
uaddr
)
,
k
msg
->
msg_namelen
,
kmsg
->
msg_name
);
if
(
err
<
0
)
return
err
;
}
kern_msg
->
msg_name
=
kern_address
;
}
else
{
k
ern_
msg
->
msg_name
=
NULL
;
k
ern_
msg
->
msg_namelen
=
0
;
kmsg
->
msg_name
=
NULL
;
kmsg
->
msg_namelen
=
0
;
}
tot_len
=
iov_from_user_compat_to_kern
(
kern_iov
,
(
struct
compat_iovec
__user
*
)
kern_msg
->
msg_iov
,
kern_msg
->
msg_iovlen
);
if
(
tot_len
>=
0
)
kern_msg
->
msg_iov
=
kern_iov
;
if
(
kmsg
->
msg_iovlen
>
UIO_MAXIOV
)
return
-
EMSGSIZE
;
return
tot_len
;
err
=
compat_rw_copy_check_uvector
(
save_addr
?
READ
:
WRITE
,
compat_ptr
(
uiov
),
kmsg
->
msg_iovlen
,
UIO_FASTIOV
,
*
iov
,
iov
);
if
(
err
>=
0
)
kmsg
->
msg_iov
=
*
iov
;
return
err
;
}
/* Bleech... */
...
...
@@ -740,7 +711,7 @@ COMPAT_SYSCALL_DEFINE3(sendmsg, int, fd, struct compat_msghdr __user *, msg, uns
{
if
(
flags
&
MSG_CMSG_COMPAT
)
return
-
EINVAL
;
return
__sys_sendmsg
(
fd
,
(
struct
msghdr
__user
*
)
msg
,
flags
|
MSG_CMSG_COMPAT
);
return
__sys_sendmsg
(
fd
,
(
struct
user_
msghdr
__user
*
)
msg
,
flags
|
MSG_CMSG_COMPAT
);
}
COMPAT_SYSCALL_DEFINE4
(
sendmmsg
,
int
,
fd
,
struct
compat_mmsghdr
__user
*
,
mmsg
,
...
...
@@ -756,7 +727,7 @@ COMPAT_SYSCALL_DEFINE3(recvmsg, int, fd, struct compat_msghdr __user *, msg, uns
{
if
(
flags
&
MSG_CMSG_COMPAT
)
return
-
EINVAL
;
return
__sys_recvmsg
(
fd
,
(
struct
msghdr
__user
*
)
msg
,
flags
|
MSG_CMSG_COMPAT
);
return
__sys_recvmsg
(
fd
,
(
struct
user_
msghdr
__user
*
)
msg
,
flags
|
MSG_CMSG_COMPAT
);
}
COMPAT_SYSCALL_DEFINE4
(
recv
,
int
,
fd
,
void
__user
*
,
buf
,
compat_size_t
,
len
,
unsigned
int
,
flags
)
...
...
net/core/iovec.c
浏览文件 @
675a53bd
...
...
@@ -27,53 +27,6 @@
#include <net/checksum.h>
#include <net/sock.h>
/*
* Verify iovec. The caller must ensure that the iovec is big enough
* to hold the message iovec.
*
* Save time not doing access_ok. copy_*_user will make this work
* in any case.
*/
int
verify_iovec
(
struct
msghdr
*
m
,
struct
iovec
*
iov
,
struct
sockaddr_storage
*
address
,
int
mode
)
{
int
size
,
ct
,
err
;
if
(
m
->
msg_name
&&
m
->
msg_namelen
)
{
if
(
mode
==
VERIFY_READ
)
{
void
__user
*
namep
;
namep
=
(
void
__user
__force
*
)
m
->
msg_name
;
err
=
move_addr_to_kernel
(
namep
,
m
->
msg_namelen
,
address
);
if
(
err
<
0
)
return
err
;
}
m
->
msg_name
=
address
;
}
else
{
m
->
msg_name
=
NULL
;
m
->
msg_namelen
=
0
;
}
size
=
m
->
msg_iovlen
*
sizeof
(
struct
iovec
);
if
(
copy_from_user
(
iov
,
(
void
__user
__force
*
)
m
->
msg_iov
,
size
))
return
-
EFAULT
;
m
->
msg_iov
=
iov
;
err
=
0
;
for
(
ct
=
0
;
ct
<
m
->
msg_iovlen
;
ct
++
)
{
size_t
len
=
iov
[
ct
].
iov_len
;
if
(
len
>
INT_MAX
-
err
)
{
len
=
INT_MAX
-
err
;
iov
[
ct
].
iov_len
=
len
;
}
err
+=
len
;
}
return
err
;
}
/*
* And now for the all-in-one: copy and checksum from a user iovec
* directly to a datagram
...
...
net/socket.c
浏览文件 @
675a53bd
...
...
@@ -1988,13 +1988,26 @@ struct used_address {
unsigned
int
name_len
;
};
static
int
copy_msghdr_from_user
(
struct
msghdr
*
kmsg
,
struct
msghdr
__user
*
umsg
)
static
ssize_t
copy_msghdr_from_user
(
struct
msghdr
*
kmsg
,
struct
user_msghdr
__user
*
umsg
,
struct
sockaddr
__user
**
save_addr
,
struct
iovec
**
iov
)
{
if
(
copy_from_user
(
kmsg
,
umsg
,
sizeof
(
struct
msghdr
)))
struct
sockaddr
__user
*
uaddr
;
struct
iovec
__user
*
uiov
;
ssize_t
err
;
if
(
!
access_ok
(
VERIFY_READ
,
umsg
,
sizeof
(
*
umsg
))
||
__get_user
(
uaddr
,
&
umsg
->
msg_name
)
||
__get_user
(
kmsg
->
msg_namelen
,
&
umsg
->
msg_namelen
)
||
__get_user
(
uiov
,
&
umsg
->
msg_iov
)
||
__get_user
(
kmsg
->
msg_iovlen
,
&
umsg
->
msg_iovlen
)
||
__get_user
(
kmsg
->
msg_control
,
&
umsg
->
msg_control
)
||
__get_user
(
kmsg
->
msg_controllen
,
&
umsg
->
msg_controllen
)
||
__get_user
(
kmsg
->
msg_flags
,
&
umsg
->
msg_flags
))
return
-
EFAULT
;
if
(
kmsg
->
msg_name
==
NULL
)
if
(
!
uaddr
)
kmsg
->
msg_namelen
=
0
;
if
(
kmsg
->
msg_namelen
<
0
)
...
...
@@ -2002,10 +2015,34 @@ static int copy_msghdr_from_user(struct msghdr *kmsg,
if
(
kmsg
->
msg_namelen
>
sizeof
(
struct
sockaddr_storage
))
kmsg
->
msg_namelen
=
sizeof
(
struct
sockaddr_storage
);
return
0
;
if
(
save_addr
)
*
save_addr
=
uaddr
;
if
(
uaddr
&&
kmsg
->
msg_namelen
)
{
if
(
!
save_addr
)
{
err
=
move_addr_to_kernel
(
uaddr
,
kmsg
->
msg_namelen
,
kmsg
->
msg_name
);
if
(
err
<
0
)
return
err
;
}
}
else
{
kmsg
->
msg_name
=
NULL
;
kmsg
->
msg_namelen
=
0
;
}
if
(
kmsg
->
msg_iovlen
>
UIO_MAXIOV
)
return
-
EMSGSIZE
;
err
=
rw_copy_check_uvector
(
save_addr
?
READ
:
WRITE
,
uiov
,
kmsg
->
msg_iovlen
,
UIO_FASTIOV
,
*
iov
,
iov
);
if
(
err
>=
0
)
kmsg
->
msg_iov
=
*
iov
;
return
err
;
}
static
int
___sys_sendmsg
(
struct
socket
*
sock
,
struct
msghdr
__user
*
msg
,
static
int
___sys_sendmsg
(
struct
socket
*
sock
,
struct
user_
msghdr
__user
*
msg
,
struct
msghdr
*
msg_sys
,
unsigned
int
flags
,
struct
used_address
*
used_address
)
{
...
...
@@ -2017,34 +2054,15 @@ static int ___sys_sendmsg(struct socket *sock, struct msghdr __user *msg,
__attribute__
((
aligned
(
sizeof
(
__kernel_size_t
))));
/* 20 is size of ipv6_pktinfo */
unsigned
char
*
ctl_buf
=
ctl
;
int
err
,
ctl_len
,
total_len
;
err
=
-
EFAULT
;
if
(
MSG_CMSG_COMPAT
&
flags
)
{
if
(
get_compat_msghdr
(
msg_sys
,
msg_compat
))
return
-
EFAULT
;
}
else
{
err
=
copy_msghdr_from_user
(
msg_sys
,
msg
);
if
(
err
)
return
err
;
}
int
ctl_len
,
total_len
;
ssize_t
err
;
if
(
msg_sys
->
msg_iovlen
>
UIO_FASTIOV
)
{
err
=
-
EMSGSIZE
;
if
(
msg_sys
->
msg_iovlen
>
UIO_MAXIOV
)
goto
out
;
err
=
-
ENOMEM
;
iov
=
kmalloc
(
msg_sys
->
msg_iovlen
*
sizeof
(
struct
iovec
),
GFP_KERNEL
);
if
(
!
iov
)
goto
out
;
}
msg_sys
->
msg_name
=
&
address
;
/* This will also move the address data into kernel space */
if
(
MSG_CMSG_COMPAT
&
flags
)
{
err
=
verify_compat_iovec
(
msg_sys
,
iov
,
&
address
,
VERIFY_READ
);
}
else
err
=
verify_iovec
(
msg_sys
,
iov
,
&
address
,
VERIFY_READ
);
if
(
MSG_CMSG_COMPAT
&
flags
)
err
=
get_compat_msghdr
(
msg_sys
,
msg_compat
,
NULL
,
&
iov
);
else
err
=
copy_msghdr_from_user
(
msg_sys
,
msg
,
NULL
,
&
iov
);
if
(
err
<
0
)
goto
out_freeiov
;
total_len
=
err
;
...
...
@@ -2115,7 +2133,6 @@ static int ___sys_sendmsg(struct socket *sock, struct msghdr __user *msg,
out_freeiov:
if
(
iov
!=
iovstack
)
kfree
(
iov
);
out:
return
err
;
}
...
...
@@ -2123,7 +2140,7 @@ static int ___sys_sendmsg(struct socket *sock, struct msghdr __user *msg,
* BSD sendmsg interface
*/
long
__sys_sendmsg
(
int
fd
,
struct
msghdr
__user
*
msg
,
unsigned
flags
)
long
__sys_sendmsg
(
int
fd
,
struct
user_
msghdr
__user
*
msg
,
unsigned
flags
)
{
int
fput_needed
,
err
;
struct
msghdr
msg_sys
;
...
...
@@ -2140,7 +2157,7 @@ long __sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags)
return
err
;
}
SYSCALL_DEFINE3
(
sendmsg
,
int
,
fd
,
struct
msghdr
__user
*
,
msg
,
unsigned
int
,
flags
)
SYSCALL_DEFINE3
(
sendmsg
,
int
,
fd
,
struct
user_
msghdr
__user
*
,
msg
,
unsigned
int
,
flags
)
{
if
(
flags
&
MSG_CMSG_COMPAT
)
return
-
EINVAL
;
...
...
@@ -2177,7 +2194,7 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
while
(
datagrams
<
vlen
)
{
if
(
MSG_CMSG_COMPAT
&
flags
)
{
err
=
___sys_sendmsg
(
sock
,
(
struct
msghdr
__user
*
)
compat_entry
,
err
=
___sys_sendmsg
(
sock
,
(
struct
user_
msghdr
__user
*
)
compat_entry
,
&
msg_sys
,
flags
,
&
used_address
);
if
(
err
<
0
)
break
;
...
...
@@ -2185,7 +2202,7 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
++
compat_entry
;
}
else
{
err
=
___sys_sendmsg
(
sock
,
(
struct
msghdr
__user
*
)
entry
,
(
struct
user_
msghdr
__user
*
)
entry
,
&
msg_sys
,
flags
,
&
used_address
);
if
(
err
<
0
)
break
;
...
...
@@ -2215,7 +2232,7 @@ SYSCALL_DEFINE4(sendmmsg, int, fd, struct mmsghdr __user *, mmsg,
return
__sys_sendmmsg
(
fd
,
mmsg
,
vlen
,
flags
);
}
static
int
___sys_recvmsg
(
struct
socket
*
sock
,
struct
msghdr
__user
*
msg
,
static
int
___sys_recvmsg
(
struct
socket
*
sock
,
struct
user_
msghdr
__user
*
msg
,
struct
msghdr
*
msg_sys
,
unsigned
int
flags
,
int
nosec
)
{
struct
compat_msghdr
__user
*
msg_compat
=
...
...
@@ -2223,44 +2240,22 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
struct
iovec
iovstack
[
UIO_FASTIOV
];
struct
iovec
*
iov
=
iovstack
;
unsigned
long
cmsg_ptr
;
int
err
,
total_len
,
len
;
int
total_len
,
len
;
ssize_t
err
;
/* kernel mode address */
struct
sockaddr_storage
addr
;
/* user mode address pointers */
struct
sockaddr
__user
*
uaddr
;
int
__user
*
uaddr_len
;
int
__user
*
uaddr_len
=
COMPAT_NAMELEN
(
msg
)
;
if
(
MSG_CMSG_COMPAT
&
flags
)
{
if
(
get_compat_msghdr
(
msg_sys
,
msg_compat
))
return
-
EFAULT
;
}
else
{
err
=
copy_msghdr_from_user
(
msg_sys
,
msg
);
if
(
err
)
return
err
;
}
if
(
msg_sys
->
msg_iovlen
>
UIO_FASTIOV
)
{
err
=
-
EMSGSIZE
;
if
(
msg_sys
->
msg_iovlen
>
UIO_MAXIOV
)
goto
out
;
err
=
-
ENOMEM
;
iov
=
kmalloc
(
msg_sys
->
msg_iovlen
*
sizeof
(
struct
iovec
),
GFP_KERNEL
);
if
(
!
iov
)
goto
out
;
}
msg_sys
->
msg_name
=
&
addr
;
/* Save the user-mode address (verify_iovec will change the
* kernel msghdr to use the kernel address space)
*/
uaddr
=
(
__force
void
__user
*
)
msg_sys
->
msg_name
;
uaddr_len
=
COMPAT_NAMELEN
(
msg
);
if
(
MSG_CMSG_COMPAT
&
flags
)
err
=
verify_compat_iovec
(
msg_sys
,
iov
,
&
addr
,
VERIFY_WRITE
);
err
=
get_compat_msghdr
(
msg_sys
,
msg_compat
,
&
uaddr
,
&
iov
);
else
err
=
verify_iovec
(
msg_sys
,
iov
,
&
addr
,
VERIFY_WRITE
);
err
=
copy_msghdr_from_user
(
msg_sys
,
msg
,
&
uaddr
,
&
iov
);
if
(
err
<
0
)
goto
out_freeiov
;
total_len
=
err
;
...
...
@@ -2303,7 +2298,6 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
out_freeiov:
if
(
iov
!=
iovstack
)
kfree
(
iov
);
out:
return
err
;
}
...
...
@@ -2311,7 +2305,7 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
* BSD recvmsg interface
*/
long
__sys_recvmsg
(
int
fd
,
struct
msghdr
__user
*
msg
,
unsigned
flags
)
long
__sys_recvmsg
(
int
fd
,
struct
user_
msghdr
__user
*
msg
,
unsigned
flags
)
{
int
fput_needed
,
err
;
struct
msghdr
msg_sys
;
...
...
@@ -2328,7 +2322,7 @@ long __sys_recvmsg(int fd, struct msghdr __user *msg, unsigned flags)
return
err
;
}
SYSCALL_DEFINE3
(
recvmsg
,
int
,
fd
,
struct
msghdr
__user
*
,
msg
,
SYSCALL_DEFINE3
(
recvmsg
,
int
,
fd
,
struct
user_
msghdr
__user
*
,
msg
,
unsigned
int
,
flags
)
{
if
(
flags
&
MSG_CMSG_COMPAT
)
...
...
@@ -2373,7 +2367,7 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
* No need to ask LSM for more than the first datagram.
*/
if
(
MSG_CMSG_COMPAT
&
flags
)
{
err
=
___sys_recvmsg
(
sock
,
(
struct
msghdr
__user
*
)
compat_entry
,
err
=
___sys_recvmsg
(
sock
,
(
struct
user_
msghdr
__user
*
)
compat_entry
,
&
msg_sys
,
flags
&
~
MSG_WAITFORONE
,
datagrams
);
if
(
err
<
0
)
...
...
@@ -2382,7 +2376,7 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
++
compat_entry
;
}
else
{
err
=
___sys_recvmsg
(
sock
,
(
struct
msghdr
__user
*
)
entry
,
(
struct
user_
msghdr
__user
*
)
entry
,
&
msg_sys
,
flags
&
~
MSG_WAITFORONE
,
datagrams
);
if
(
err
<
0
)
...
...
@@ -2571,13 +2565,13 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args)
(
int
__user
*
)
a
[
4
]);
break
;
case
SYS_SENDMSG
:
err
=
sys_sendmsg
(
a0
,
(
struct
msghdr
__user
*
)
a1
,
a
[
2
]);
err
=
sys_sendmsg
(
a0
,
(
struct
user_
msghdr
__user
*
)
a1
,
a
[
2
]);
break
;
case
SYS_SENDMMSG
:
err
=
sys_sendmmsg
(
a0
,
(
struct
mmsghdr
__user
*
)
a1
,
a
[
2
],
a
[
3
]);
break
;
case
SYS_RECVMSG
:
err
=
sys_recvmsg
(
a0
,
(
struct
msghdr
__user
*
)
a1
,
a
[
2
]);
err
=
sys_recvmsg
(
a0
,
(
struct
user_
msghdr
__user
*
)
a1
,
a
[
2
]);
break
;
case
SYS_RECVMMSG
:
err
=
sys_recvmmsg
(
a0
,
(
struct
mmsghdr
__user
*
)
a1
,
a
[
2
],
a
[
3
],
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录