Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
80f0cce6
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看板
提交
80f0cce6
编写于
4月 08, 2017
作者:
A
Al Viro
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fcntl: move compat syscalls from compat.c
Signed-off-by:
N
Al Viro
<
viro@zeniv.linux.org.uk
>
上级
0460b2a2
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
157 addition
and
154 deletion
+157
-154
fs/compat.c
fs/compat.c
+0
-154
fs/fcntl.c
fs/fcntl.c
+157
-0
未找到文件。
fs/compat.c
浏览文件 @
80f0cce6
...
...
@@ -137,160 +137,6 @@ COMPAT_SYSCALL_DEFINE2(newfstat, unsigned int, fd,
return
error
;
}
static
int
get_compat_flock
(
struct
flock
*
kfl
,
struct
compat_flock
__user
*
ufl
)
{
if
(
!
access_ok
(
VERIFY_READ
,
ufl
,
sizeof
(
*
ufl
))
||
__get_user
(
kfl
->
l_type
,
&
ufl
->
l_type
)
||
__get_user
(
kfl
->
l_whence
,
&
ufl
->
l_whence
)
||
__get_user
(
kfl
->
l_start
,
&
ufl
->
l_start
)
||
__get_user
(
kfl
->
l_len
,
&
ufl
->
l_len
)
||
__get_user
(
kfl
->
l_pid
,
&
ufl
->
l_pid
))
return
-
EFAULT
;
return
0
;
}
static
int
put_compat_flock
(
struct
flock
*
kfl
,
struct
compat_flock
__user
*
ufl
)
{
if
(
!
access_ok
(
VERIFY_WRITE
,
ufl
,
sizeof
(
*
ufl
))
||
__put_user
(
kfl
->
l_type
,
&
ufl
->
l_type
)
||
__put_user
(
kfl
->
l_whence
,
&
ufl
->
l_whence
)
||
__put_user
(
kfl
->
l_start
,
&
ufl
->
l_start
)
||
__put_user
(
kfl
->
l_len
,
&
ufl
->
l_len
)
||
__put_user
(
kfl
->
l_pid
,
&
ufl
->
l_pid
))
return
-
EFAULT
;
return
0
;
}
#ifndef HAVE_ARCH_GET_COMPAT_FLOCK64
static
int
get_compat_flock64
(
struct
flock
*
kfl
,
struct
compat_flock64
__user
*
ufl
)
{
if
(
!
access_ok
(
VERIFY_READ
,
ufl
,
sizeof
(
*
ufl
))
||
__get_user
(
kfl
->
l_type
,
&
ufl
->
l_type
)
||
__get_user
(
kfl
->
l_whence
,
&
ufl
->
l_whence
)
||
__get_user
(
kfl
->
l_start
,
&
ufl
->
l_start
)
||
__get_user
(
kfl
->
l_len
,
&
ufl
->
l_len
)
||
__get_user
(
kfl
->
l_pid
,
&
ufl
->
l_pid
))
return
-
EFAULT
;
return
0
;
}
#endif
#ifndef HAVE_ARCH_PUT_COMPAT_FLOCK64
static
int
put_compat_flock64
(
struct
flock
*
kfl
,
struct
compat_flock64
__user
*
ufl
)
{
if
(
!
access_ok
(
VERIFY_WRITE
,
ufl
,
sizeof
(
*
ufl
))
||
__put_user
(
kfl
->
l_type
,
&
ufl
->
l_type
)
||
__put_user
(
kfl
->
l_whence
,
&
ufl
->
l_whence
)
||
__put_user
(
kfl
->
l_start
,
&
ufl
->
l_start
)
||
__put_user
(
kfl
->
l_len
,
&
ufl
->
l_len
)
||
__put_user
(
kfl
->
l_pid
,
&
ufl
->
l_pid
))
return
-
EFAULT
;
return
0
;
}
#endif
static
unsigned
int
convert_fcntl_cmd
(
unsigned
int
cmd
)
{
switch
(
cmd
)
{
case
F_GETLK64
:
return
F_GETLK
;
case
F_SETLK64
:
return
F_SETLK
;
case
F_SETLKW64
:
return
F_SETLKW
;
}
return
cmd
;
}
COMPAT_SYSCALL_DEFINE3
(
fcntl64
,
unsigned
int
,
fd
,
unsigned
int
,
cmd
,
compat_ulong_t
,
arg
)
{
mm_segment_t
old_fs
;
struct
flock
f
;
long
ret
;
unsigned
int
conv_cmd
;
switch
(
cmd
)
{
case
F_GETLK
:
case
F_SETLK
:
case
F_SETLKW
:
ret
=
get_compat_flock
(
&
f
,
compat_ptr
(
arg
));
if
(
ret
!=
0
)
break
;
old_fs
=
get_fs
();
set_fs
(
KERNEL_DS
);
ret
=
sys_fcntl
(
fd
,
cmd
,
(
unsigned
long
)
&
f
);
set_fs
(
old_fs
);
if
(
cmd
==
F_GETLK
&&
ret
==
0
)
{
/* GETLK was successful and we need to return the data...
* but it needs to fit in the compat structure.
* l_start shouldn't be too big, unless the original
* start + end is greater than COMPAT_OFF_T_MAX, in which
* case the app was asking for trouble, so we return
* -EOVERFLOW in that case.
* l_len could be too big, in which case we just truncate it,
* and only allow the app to see that part of the conflicting
* lock that might make sense to it anyway
*/
if
(
f
.
l_start
>
COMPAT_OFF_T_MAX
)
ret
=
-
EOVERFLOW
;
if
(
f
.
l_len
>
COMPAT_OFF_T_MAX
)
f
.
l_len
=
COMPAT_OFF_T_MAX
;
if
(
ret
==
0
)
ret
=
put_compat_flock
(
&
f
,
compat_ptr
(
arg
));
}
break
;
case
F_GETLK64
:
case
F_SETLK64
:
case
F_SETLKW64
:
case
F_OFD_GETLK
:
case
F_OFD_SETLK
:
case
F_OFD_SETLKW
:
ret
=
get_compat_flock64
(
&
f
,
compat_ptr
(
arg
));
if
(
ret
!=
0
)
break
;
old_fs
=
get_fs
();
set_fs
(
KERNEL_DS
);
conv_cmd
=
convert_fcntl_cmd
(
cmd
);
ret
=
sys_fcntl
(
fd
,
conv_cmd
,
(
unsigned
long
)
&
f
);
set_fs
(
old_fs
);
if
((
conv_cmd
==
F_GETLK
||
conv_cmd
==
F_OFD_GETLK
)
&&
ret
==
0
)
{
/* need to return lock information - see above for commentary */
if
(
f
.
l_start
>
COMPAT_LOFF_T_MAX
)
ret
=
-
EOVERFLOW
;
if
(
f
.
l_len
>
COMPAT_LOFF_T_MAX
)
f
.
l_len
=
COMPAT_LOFF_T_MAX
;
if
(
ret
==
0
)
ret
=
put_compat_flock64
(
&
f
,
compat_ptr
(
arg
));
}
break
;
default:
ret
=
sys_fcntl
(
fd
,
cmd
,
arg
);
break
;
}
return
ret
;
}
COMPAT_SYSCALL_DEFINE3
(
fcntl
,
unsigned
int
,
fd
,
unsigned
int
,
cmd
,
compat_ulong_t
,
arg
)
{
switch
(
cmd
)
{
case
F_GETLK64
:
case
F_SETLK64
:
case
F_SETLKW64
:
case
F_OFD_GETLK
:
case
F_OFD_SETLK
:
case
F_OFD_SETLKW
:
return
-
EINVAL
;
}
return
compat_sys_fcntl64
(
fd
,
cmd
,
arg
);
}
/* A write operation does a read from user space and vice versa */
#define vrfy_dir(type) ((type) == READ ? VERIFY_WRITE : VERIFY_READ)
...
...
fs/fcntl.c
浏览文件 @
80f0cce6
...
...
@@ -23,6 +23,7 @@
#include <linux/pid_namespace.h>
#include <linux/user_namespace.h>
#include <linux/shmem_fs.h>
#include <linux/compat.h>
#include <asm/poll.h>
#include <asm/siginfo.h>
...
...
@@ -420,6 +421,162 @@ SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd,
}
#endif
#ifdef CONFIG_COMPAT
static
int
get_compat_flock
(
struct
flock
*
kfl
,
struct
compat_flock
__user
*
ufl
)
{
if
(
!
access_ok
(
VERIFY_READ
,
ufl
,
sizeof
(
*
ufl
))
||
__get_user
(
kfl
->
l_type
,
&
ufl
->
l_type
)
||
__get_user
(
kfl
->
l_whence
,
&
ufl
->
l_whence
)
||
__get_user
(
kfl
->
l_start
,
&
ufl
->
l_start
)
||
__get_user
(
kfl
->
l_len
,
&
ufl
->
l_len
)
||
__get_user
(
kfl
->
l_pid
,
&
ufl
->
l_pid
))
return
-
EFAULT
;
return
0
;
}
static
int
put_compat_flock
(
struct
flock
*
kfl
,
struct
compat_flock
__user
*
ufl
)
{
if
(
!
access_ok
(
VERIFY_WRITE
,
ufl
,
sizeof
(
*
ufl
))
||
__put_user
(
kfl
->
l_type
,
&
ufl
->
l_type
)
||
__put_user
(
kfl
->
l_whence
,
&
ufl
->
l_whence
)
||
__put_user
(
kfl
->
l_start
,
&
ufl
->
l_start
)
||
__put_user
(
kfl
->
l_len
,
&
ufl
->
l_len
)
||
__put_user
(
kfl
->
l_pid
,
&
ufl
->
l_pid
))
return
-
EFAULT
;
return
0
;
}
#ifndef HAVE_ARCH_GET_COMPAT_FLOCK64
static
int
get_compat_flock64
(
struct
flock
*
kfl
,
struct
compat_flock64
__user
*
ufl
)
{
if
(
!
access_ok
(
VERIFY_READ
,
ufl
,
sizeof
(
*
ufl
))
||
__get_user
(
kfl
->
l_type
,
&
ufl
->
l_type
)
||
__get_user
(
kfl
->
l_whence
,
&
ufl
->
l_whence
)
||
__get_user
(
kfl
->
l_start
,
&
ufl
->
l_start
)
||
__get_user
(
kfl
->
l_len
,
&
ufl
->
l_len
)
||
__get_user
(
kfl
->
l_pid
,
&
ufl
->
l_pid
))
return
-
EFAULT
;
return
0
;
}
#endif
#ifndef HAVE_ARCH_PUT_COMPAT_FLOCK64
static
int
put_compat_flock64
(
struct
flock
*
kfl
,
struct
compat_flock64
__user
*
ufl
)
{
if
(
!
access_ok
(
VERIFY_WRITE
,
ufl
,
sizeof
(
*
ufl
))
||
__put_user
(
kfl
->
l_type
,
&
ufl
->
l_type
)
||
__put_user
(
kfl
->
l_whence
,
&
ufl
->
l_whence
)
||
__put_user
(
kfl
->
l_start
,
&
ufl
->
l_start
)
||
__put_user
(
kfl
->
l_len
,
&
ufl
->
l_len
)
||
__put_user
(
kfl
->
l_pid
,
&
ufl
->
l_pid
))
return
-
EFAULT
;
return
0
;
}
#endif
static
unsigned
int
convert_fcntl_cmd
(
unsigned
int
cmd
)
{
switch
(
cmd
)
{
case
F_GETLK64
:
return
F_GETLK
;
case
F_SETLK64
:
return
F_SETLK
;
case
F_SETLKW64
:
return
F_SETLKW
;
}
return
cmd
;
}
COMPAT_SYSCALL_DEFINE3
(
fcntl64
,
unsigned
int
,
fd
,
unsigned
int
,
cmd
,
compat_ulong_t
,
arg
)
{
mm_segment_t
old_fs
;
struct
flock
f
;
long
ret
;
unsigned
int
conv_cmd
;
switch
(
cmd
)
{
case
F_GETLK
:
case
F_SETLK
:
case
F_SETLKW
:
ret
=
get_compat_flock
(
&
f
,
compat_ptr
(
arg
));
if
(
ret
!=
0
)
break
;
old_fs
=
get_fs
();
set_fs
(
KERNEL_DS
);
ret
=
sys_fcntl
(
fd
,
cmd
,
(
unsigned
long
)
&
f
);
set_fs
(
old_fs
);
if
(
cmd
==
F_GETLK
&&
ret
==
0
)
{
/* GETLK was successful and we need to return the data...
* but it needs to fit in the compat structure.
* l_start shouldn't be too big, unless the original
* start + end is greater than COMPAT_OFF_T_MAX, in which
* case the app was asking for trouble, so we return
* -EOVERFLOW in that case.
* l_len could be too big, in which case we just truncate it,
* and only allow the app to see that part of the conflicting
* lock that might make sense to it anyway
*/
if
(
f
.
l_start
>
COMPAT_OFF_T_MAX
)
ret
=
-
EOVERFLOW
;
if
(
f
.
l_len
>
COMPAT_OFF_T_MAX
)
f
.
l_len
=
COMPAT_OFF_T_MAX
;
if
(
ret
==
0
)
ret
=
put_compat_flock
(
&
f
,
compat_ptr
(
arg
));
}
break
;
case
F_GETLK64
:
case
F_SETLK64
:
case
F_SETLKW64
:
case
F_OFD_GETLK
:
case
F_OFD_SETLK
:
case
F_OFD_SETLKW
:
ret
=
get_compat_flock64
(
&
f
,
compat_ptr
(
arg
));
if
(
ret
!=
0
)
break
;
old_fs
=
get_fs
();
set_fs
(
KERNEL_DS
);
conv_cmd
=
convert_fcntl_cmd
(
cmd
);
ret
=
sys_fcntl
(
fd
,
conv_cmd
,
(
unsigned
long
)
&
f
);
set_fs
(
old_fs
);
if
((
conv_cmd
==
F_GETLK
||
conv_cmd
==
F_OFD_GETLK
)
&&
ret
==
0
)
{
/* need to return lock information - see above for commentary */
if
(
f
.
l_start
>
COMPAT_LOFF_T_MAX
)
ret
=
-
EOVERFLOW
;
if
(
f
.
l_len
>
COMPAT_LOFF_T_MAX
)
f
.
l_len
=
COMPAT_LOFF_T_MAX
;
if
(
ret
==
0
)
ret
=
put_compat_flock64
(
&
f
,
compat_ptr
(
arg
));
}
break
;
default:
ret
=
sys_fcntl
(
fd
,
cmd
,
arg
);
break
;
}
return
ret
;
}
COMPAT_SYSCALL_DEFINE3
(
fcntl
,
unsigned
int
,
fd
,
unsigned
int
,
cmd
,
compat_ulong_t
,
arg
)
{
switch
(
cmd
)
{
case
F_GETLK64
:
case
F_SETLK64
:
case
F_SETLKW64
:
case
F_OFD_GETLK
:
case
F_OFD_SETLK
:
case
F_OFD_SETLKW
:
return
-
EINVAL
;
}
return
compat_sys_fcntl64
(
fd
,
cmd
,
arg
);
}
#endif
/* Table to convert sigio signal codes into poll band bitmaps */
static
const
long
band_table
[
NSIGPOLL
]
=
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录