Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
44c02a2c
cloud-kernel
项目概览
openanolis
/
cloud-kernel
1 年多 前同步成功
通知
161
Star
36
Fork
7
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
44c02a2c
编写于
10月 05, 2017
作者:
A
Al Viro
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
dev_ioctl(): move copyin/copyout to callers
Signed-off-by:
N
Al Viro
<
viro@zeniv.linux.org.uk
>
上级
6a88fbe7
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
71 addition
and
108 deletion
+71
-108
include/linux/netdevice.h
include/linux/netdevice.h
+2
-1
net/core/dev_ioctl.c
net/core/dev_ioctl.c
+24
-61
net/socket.c
net/socket.c
+45
-46
未找到文件。
include/linux/netdevice.h
浏览文件 @
44c02a2c
...
...
@@ -3315,7 +3315,8 @@ int netdev_rx_handler_register(struct net_device *dev,
void
netdev_rx_handler_unregister
(
struct
net_device
*
dev
);
bool
dev_valid_name
(
const
char
*
name
);
int
dev_ioctl
(
struct
net
*
net
,
unsigned
int
cmd
,
void
__user
*
);
int
dev_ioctl
(
struct
net
*
net
,
unsigned
int
cmd
,
struct
ifreq
*
ifr
,
bool
*
need_copyout
);
int
dev_ifconf
(
struct
net
*
net
,
struct
ifconf
*
,
int
);
int
dev_ethtool
(
struct
net
*
net
,
struct
ifreq
*
);
unsigned
int
dev_get_flags
(
const
struct
net_device
*
);
...
...
net/core/dev_ioctl.c
浏览文件 @
44c02a2c
...
...
@@ -18,26 +18,10 @@
* match. --pb
*/
static
int
dev_ifname
(
struct
net
*
net
,
struct
ifreq
__user
*
arg
)
static
int
dev_ifname
(
struct
net
*
net
,
struct
ifreq
*
ifr
)
{
struct
ifreq
ifr
;
int
error
;
/*
* Fetch the caller's info block.
*/
if
(
copy_from_user
(
&
ifr
,
arg
,
sizeof
(
struct
ifreq
)))
return
-
EFAULT
;
ifr
.
ifr_name
[
IFNAMSIZ
-
1
]
=
0
;
error
=
netdev_get_name
(
net
,
ifr
.
ifr_name
,
ifr
.
ifr_ifindex
);
if
(
error
)
return
error
;
if
(
copy_to_user
(
arg
,
&
ifr
,
sizeof
(
struct
ifreq
)))
return
-
EFAULT
;
return
0
;
ifr
->
ifr_name
[
IFNAMSIZ
-
1
]
=
0
;
return
netdev_get_name
(
net
,
ifr
->
ifr_name
,
ifr
->
ifr_ifindex
);
}
static
gifconf_func_t
*
gifconf_list
[
NPROTO
];
...
...
@@ -402,24 +386,24 @@ EXPORT_SYMBOL(dev_load);
* positive or a negative errno code on error.
*/
int
dev_ioctl
(
struct
net
*
net
,
unsigned
int
cmd
,
void
__user
*
arg
)
int
dev_ioctl
(
struct
net
*
net
,
unsigned
int
cmd
,
struct
ifreq
*
ifr
,
bool
*
need_copyout
)
{
struct
ifreq
ifr
;
int
ret
;
char
*
colon
;
if
(
need_copyout
)
*
need_copyout
=
true
;
if
(
cmd
==
SIOCGIFNAME
)
return
dev_ifname
(
net
,
(
struct
ifreq
__user
*
)
arg
);
if
(
copy_from_user
(
&
ifr
,
arg
,
sizeof
(
struct
ifreq
)))
return
-
EFAULT
;
return
dev_ifname
(
net
,
ifr
);
ifr
.
ifr_name
[
IFNAMSIZ
-
1
]
=
0
;
ifr
->
ifr_name
[
IFNAMSIZ
-
1
]
=
0
;
colon
=
strchr
(
ifr
.
ifr_name
,
':'
);
colon
=
strchr
(
ifr
->
ifr_name
,
':'
);
if
(
colon
)
*
colon
=
0
;
dev_load
(
net
,
ifr
->
ifr_name
);
/*
* See which interface the caller is talking about.
*/
...
...
@@ -439,31 +423,19 @@ int dev_ioctl(struct net *net, unsigned int cmd, void __user *arg)
case
SIOCGIFMAP
:
case
SIOCGIFINDEX
:
case
SIOCGIFTXQLEN
:
dev_load
(
net
,
ifr
.
ifr_name
);
rcu_read_lock
();
ret
=
dev_ifsioc_locked
(
net
,
&
ifr
,
cmd
);
ret
=
dev_ifsioc_locked
(
net
,
ifr
,
cmd
);
rcu_read_unlock
();
if
(
!
ret
)
{
if
(
colon
)
*
colon
=
':'
;
if
(
copy_to_user
(
arg
,
&
ifr
,
sizeof
(
struct
ifreq
)))
ret
=
-
EFAULT
;
}
if
(
colon
)
*
colon
=
':'
;
return
ret
;
case
SIOCETHTOOL
:
dev_load
(
net
,
ifr
.
ifr_name
);
rtnl_lock
();
ret
=
dev_ethtool
(
net
,
&
ifr
);
ret
=
dev_ethtool
(
net
,
ifr
);
rtnl_unlock
();
if
(
!
ret
)
{
if
(
colon
)
*
colon
=
':'
;
if
(
copy_to_user
(
arg
,
&
ifr
,
sizeof
(
struct
ifreq
)))
ret
=
-
EFAULT
;
}
if
(
colon
)
*
colon
=
':'
;
return
ret
;
/*
...
...
@@ -477,17 +449,11 @@ int dev_ioctl(struct net *net, unsigned int cmd, void __user *arg)
case
SIOCSIFNAME
:
if
(
!
ns_capable
(
net
->
user_ns
,
CAP_NET_ADMIN
))
return
-
EPERM
;
dev_load
(
net
,
ifr
.
ifr_name
);
rtnl_lock
();
ret
=
dev_ifsioc
(
net
,
&
ifr
,
cmd
);
ret
=
dev_ifsioc
(
net
,
ifr
,
cmd
);
rtnl_unlock
();
if
(
!
ret
)
{
if
(
colon
)
*
colon
=
':'
;
if
(
copy_to_user
(
arg
,
&
ifr
,
sizeof
(
struct
ifreq
)))
ret
=
-
EFAULT
;
}
if
(
colon
)
*
colon
=
':'
;
return
ret
;
/*
...
...
@@ -528,10 +494,11 @@ int dev_ioctl(struct net *net, unsigned int cmd, void __user *arg)
/* fall through */
case
SIOCBONDSLAVEINFOQUERY
:
case
SIOCBONDINFOQUERY
:
dev_load
(
net
,
ifr
.
ifr_name
);
rtnl_lock
();
ret
=
dev_ifsioc
(
net
,
&
ifr
,
cmd
);
ret
=
dev_ifsioc
(
net
,
ifr
,
cmd
);
rtnl_unlock
();
if
(
need_copyout
)
*
need_copyout
=
false
;
return
ret
;
case
SIOCGIFMEM
:
...
...
@@ -551,13 +518,9 @@ int dev_ioctl(struct net *net, unsigned int cmd, void __user *arg)
cmd
==
SIOCGHWTSTAMP
||
(
cmd
>=
SIOCDEVPRIVATE
&&
cmd
<=
SIOCDEVPRIVATE
+
15
))
{
dev_load
(
net
,
ifr
.
ifr_name
);
rtnl_lock
();
ret
=
dev_ifsioc
(
net
,
&
ifr
,
cmd
);
ret
=
dev_ifsioc
(
net
,
ifr
,
cmd
);
rtnl_unlock
();
if
(
!
ret
&&
copy_to_user
(
arg
,
&
ifr
,
sizeof
(
struct
ifreq
)))
ret
=
-
EFAULT
;
return
ret
;
}
return
-
ENOTTY
;
...
...
net/socket.c
浏览文件 @
44c02a2c
...
...
@@ -973,10 +973,17 @@ static long sock_do_ioctl(struct net *net, struct socket *sock,
rtnl_unlock
();
if
(
!
err
&&
copy_to_user
(
argp
,
&
ifc
,
sizeof
(
struct
ifconf
)))
err
=
-
EFAULT
;
return
err
;
}
else
{
struct
ifreq
ifr
;
bool
need_copyout
;
if
(
copy_from_user
(
&
ifr
,
argp
,
sizeof
(
struct
ifreq
)))
return
-
EFAULT
;
err
=
dev_ioctl
(
net
,
cmd
,
&
ifr
,
&
need_copyout
);
if
(
!
err
&&
need_copyout
)
if
(
copy_to_user
(
argp
,
&
ifr
,
sizeof
(
struct
ifreq
)))
return
-
EFAULT
;
}
return
dev_ioctl
(
net
,
cmd
,
argp
);
return
err
;
}
/*
...
...
@@ -1000,8 +1007,15 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
sock
=
file
->
private_data
;
sk
=
sock
->
sk
;
net
=
sock_net
(
sk
);
if
(
cmd
>=
SIOCDEVPRIVATE
&&
cmd
<=
(
SIOCDEVPRIVATE
+
15
))
{
err
=
dev_ioctl
(
net
,
cmd
,
argp
);
if
(
unlikely
(
cmd
>=
SIOCDEVPRIVATE
&&
cmd
<=
(
SIOCDEVPRIVATE
+
15
)))
{
struct
ifreq
ifr
;
bool
need_copyout
;
if
(
copy_from_user
(
&
ifr
,
argp
,
sizeof
(
struct
ifreq
)))
return
-
EFAULT
;
err
=
dev_ioctl
(
net
,
cmd
,
&
ifr
,
&
need_copyout
);
if
(
!
err
&&
need_copyout
)
if
(
copy_to_user
(
argp
,
&
ifr
,
sizeof
(
struct
ifreq
)))
return
-
EFAULT
;
}
else
#ifdef CONFIG_WEXT_CORE
if
(
cmd
>=
SIOCIWFIRST
&&
cmd
<=
SIOCIWLAST
)
{
...
...
@@ -2695,9 +2709,9 @@ static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32)
{
struct
compat_ethtool_rxnfc
__user
*
compat_rxnfc
;
bool
convert_in
=
false
,
convert_out
=
false
;
size_t
buf_size
=
ALIGN
(
sizeof
(
struct
ifreq
),
8
)
;
struct
ethtool_rxnfc
__user
*
rxnfc
;
struct
ifreq
__user
*
ifr
;
size_t
buf_size
=
0
;
struct
ethtool_rxnfc
__user
*
rxnfc
=
NULL
;
struct
ifreq
ifr
;
u32
rule_cnt
=
0
,
actual_rule_cnt
;
u32
ethcmd
;
u32
data
;
...
...
@@ -2734,18 +2748,14 @@ static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32)
case
ETHTOOL_SRXCLSRLDEL
:
buf_size
+=
sizeof
(
struct
ethtool_rxnfc
);
convert_in
=
true
;
rxnfc
=
compat_alloc_user_space
(
buf_size
);
break
;
}
ifr
=
compat_alloc_user_space
(
buf_size
);
rxnfc
=
(
void
__user
*
)
ifr
+
ALIGN
(
sizeof
(
struct
ifreq
),
8
);
if
(
copy_in_user
(
&
ifr
->
ifr_name
,
&
ifr32
->
ifr_name
,
IFNAMSIZ
))
if
(
copy_from_user
(
&
ifr
.
ifr_name
,
&
ifr32
->
ifr_name
,
IFNAMSIZ
))
return
-
EFAULT
;
if
(
put_user
(
convert_in
?
rxnfc
:
compat_ptr
(
data
),
&
ifr
->
ifr_ifru
.
ifru_data
))
return
-
EFAULT
;
ifr
.
ifr_data
=
convert_in
?
rxnfc
:
(
void
__user
*
)
compat_rxnfc
;
if
(
convert_in
)
{
/* We expect there to be holes between fs.m_ext and
...
...
@@ -2773,7 +2783,7 @@ static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32)
return
-
EFAULT
;
}
ret
=
dev_ioctl
(
net
,
SIOCETHTOOL
,
ifr
);
ret
=
dev_ioctl
(
net
,
SIOCETHTOOL
,
&
ifr
,
NULL
);
if
(
ret
)
return
ret
;
...
...
@@ -2814,50 +2824,43 @@ static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32)
static
int
compat_siocwandev
(
struct
net
*
net
,
struct
compat_ifreq
__user
*
uifr32
)
{
void
__user
*
uptr
;
compat_uptr_t
uptr32
;
struct
ifreq
__user
*
uifr
;
struct
ifreq
ifr
;
void
__user
*
saved
;
int
err
;
uifr
=
compat_alloc_user_space
(
sizeof
(
*
uifr
));
if
(
copy_in_user
(
uifr
,
uifr32
,
sizeof
(
struct
compat_ifreq
)))
if
(
copy_from_user
(
&
ifr
,
uifr32
,
sizeof
(
struct
compat_ifreq
)))
return
-
EFAULT
;
if
(
get_user
(
uptr32
,
&
uifr32
->
ifr_settings
.
ifs_ifsu
))
return
-
EFAULT
;
uptr
=
compat_ptr
(
uptr32
);
if
(
put_user
(
uptr
,
&
uifr
->
ifr_settings
.
ifs_ifsu
.
raw_hdlc
))
return
-
EFAULT
;
saved
=
ifr
.
ifr_settings
.
ifs_ifsu
.
raw_hdlc
;
ifr
.
ifr_settings
.
ifs_ifsu
.
raw_hdlc
=
compat_ptr
(
uptr32
);
return
dev_ioctl
(
net
,
SIOCWANDEV
,
uifr
);
err
=
dev_ioctl
(
net
,
SIOCWANDEV
,
&
ifr
,
NULL
);
if
(
!
err
)
{
ifr
.
ifr_settings
.
ifs_ifsu
.
raw_hdlc
=
saved
;
if
(
copy_to_user
(
uifr32
,
&
ifr
,
sizeof
(
struct
compat_ifreq
)))
err
=
-
EFAULT
;
}
return
err
;
}
/* Handle ioctls that use ifreq::ifr_data and just need struct ifreq converted */
static
int
compat_ifr_data_ioctl
(
struct
net
*
net
,
unsigned
int
cmd
,
struct
compat_ifreq
__user
*
u_ifreq32
)
{
struct
ifreq
__user
*
u_ifreq64
;
char
tmp_buf
[
IFNAMSIZ
];
void
__user
*
data64
;
struct
ifreq
ifreq
;
u32
data32
;
if
(
copy_from_user
(
&
tmp_buf
[
0
],
&
(
u_ifreq32
->
ifr_ifrn
.
ifrn_name
[
0
]),
IFNAMSIZ
))
if
(
copy_from_user
(
ifreq
.
ifr_name
,
u_ifreq32
->
ifr_name
,
IFNAMSIZ
))
return
-
EFAULT
;
if
(
get_user
(
data32
,
&
u_ifreq32
->
ifr_
ifru
.
ifru_
data
))
if
(
get_user
(
data32
,
&
u_ifreq32
->
ifr_data
))
return
-
EFAULT
;
data64
=
compat_ptr
(
data32
);
ifreq
.
ifr_data
=
compat_ptr
(
data32
);
u_ifreq64
=
compat_alloc_user_space
(
sizeof
(
*
u_ifreq64
));
if
(
copy_to_user
(
&
u_ifreq64
->
ifr_ifrn
.
ifrn_name
[
0
],
&
tmp_buf
[
0
],
IFNAMSIZ
))
return
-
EFAULT
;
if
(
put_user
(
data64
,
&
u_ifreq64
->
ifr_ifru
.
ifru_data
))
return
-
EFAULT
;
return
dev_ioctl
(
net
,
cmd
,
u_ifreq64
);
return
dev_ioctl
(
net
,
cmd
,
&
ifreq
,
NULL
);
}
static
int
compat_sioc_ifmap
(
struct
net
*
net
,
unsigned
int
cmd
,
...
...
@@ -2865,7 +2868,6 @@ static int compat_sioc_ifmap(struct net *net, unsigned int cmd,
{
struct
ifreq
ifr
;
struct
compat_ifmap
__user
*
uifmap32
;
mm_segment_t
old_fs
;
int
err
;
uifmap32
=
&
uifr32
->
ifr_ifru
.
ifru_map
;
...
...
@@ -2879,10 +2881,7 @@ static int compat_sioc_ifmap(struct net *net, unsigned int cmd,
if
(
err
)
return
-
EFAULT
;
old_fs
=
get_fs
();
set_fs
(
KERNEL_DS
);
err
=
dev_ioctl
(
net
,
cmd
,
(
void
__user
__force
*
)
&
ifr
);
set_fs
(
old_fs
);
err
=
dev_ioctl
(
net
,
cmd
,
&
ifr
,
NULL
);
if
(
cmd
==
SIOCGIFMAP
&&
!
err
)
{
err
=
copy_to_user
(
uifr32
,
&
ifr
,
sizeof
(
ifr
.
ifr_name
));
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录