Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
kernel_linux
提交
156d9ed1
K
kernel_linux
项目概览
OpenHarmony
/
kernel_linux
上一次同步 4 年多
通知
15
Star
8
Fork
2
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
kernel_linux
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
156d9ed1
编写于
7月 09, 2017
作者:
A
Al Viro
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
msgctl(): split the actual work from copyin/copyout
Signed-off-by:
N
Al Viro
<
viro@zeniv.linux.org.uk
>
上级
553f770e
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
96 addition
and
106 deletion
+96
-106
ipc/msg.c
ipc/msg.c
+96
-106
未找到文件。
ipc/msg.c
浏览文件 @
156d9ed1
...
@@ -361,23 +361,17 @@ copy_msqid_from_user(struct msqid64_ds *out, void __user *buf, int version)
...
@@ -361,23 +361,17 @@ copy_msqid_from_user(struct msqid64_ds *out, void __user *buf, int version)
* NOTE: no locks must be held, the rwsem is taken inside this function.
* NOTE: no locks must be held, the rwsem is taken inside this function.
*/
*/
static
int
msgctl_down
(
struct
ipc_namespace
*
ns
,
int
msqid
,
int
cmd
,
static
int
msgctl_down
(
struct
ipc_namespace
*
ns
,
int
msqid
,
int
cmd
,
struct
msqid_ds
__user
*
buf
,
int
version
)
struct
msqid64_ds
*
msqid64
)
{
{
struct
kern_ipc_perm
*
ipcp
;
struct
kern_ipc_perm
*
ipcp
;
struct
msqid64_ds
uninitialized_var
(
msqid64
);
struct
msg_queue
*
msq
;
struct
msg_queue
*
msq
;
int
err
;
int
err
;
if
(
cmd
==
IPC_SET
)
{
if
(
copy_msqid_from_user
(
&
msqid64
,
buf
,
version
))
return
-
EFAULT
;
}
down_write
(
&
msg_ids
(
ns
).
rwsem
);
down_write
(
&
msg_ids
(
ns
).
rwsem
);
rcu_read_lock
();
rcu_read_lock
();
ipcp
=
ipcctl_pre_down_nolock
(
ns
,
&
msg_ids
(
ns
),
msqid
,
cmd
,
ipcp
=
ipcctl_pre_down_nolock
(
ns
,
&
msg_ids
(
ns
),
msqid
,
cmd
,
&
msqid64
.
msg_perm
,
msqid64
.
msg_qbytes
);
&
msqid64
->
msg_perm
,
msqid64
->
msg_qbytes
);
if
(
IS_ERR
(
ipcp
))
{
if
(
IS_ERR
(
ipcp
))
{
err
=
PTR_ERR
(
ipcp
);
err
=
PTR_ERR
(
ipcp
);
goto
out_unlock1
;
goto
out_unlock1
;
...
@@ -399,18 +393,18 @@ static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd,
...
@@ -399,18 +393,18 @@ static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd,
{
{
DEFINE_WAKE_Q
(
wake_q
);
DEFINE_WAKE_Q
(
wake_q
);
if
(
msqid64
.
msg_qbytes
>
ns
->
msg_ctlmnb
&&
if
(
msqid64
->
msg_qbytes
>
ns
->
msg_ctlmnb
&&
!
capable
(
CAP_SYS_RESOURCE
))
{
!
capable
(
CAP_SYS_RESOURCE
))
{
err
=
-
EPERM
;
err
=
-
EPERM
;
goto
out_unlock1
;
goto
out_unlock1
;
}
}
ipc_lock_object
(
&
msq
->
q_perm
);
ipc_lock_object
(
&
msq
->
q_perm
);
err
=
ipc_update_perm
(
&
msqid64
.
msg_perm
,
ipcp
);
err
=
ipc_update_perm
(
&
msqid64
->
msg_perm
,
ipcp
);
if
(
err
)
if
(
err
)
goto
out_unlock0
;
goto
out_unlock0
;
msq
->
q_qbytes
=
msqid64
.
msg_qbytes
;
msq
->
q_qbytes
=
msqid64
->
msg_qbytes
;
msq
->
q_ctime
=
get_seconds
();
msq
->
q_ctime
=
get_seconds
();
/*
/*
...
@@ -442,111 +436,89 @@ static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd,
...
@@ -442,111 +436,89 @@ static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd,
return
err
;
return
err
;
}
}
static
int
msgctl_
nolock
(
struct
ipc_namespace
*
ns
,
int
msqid
,
static
int
msgctl_
info
(
struct
ipc_namespace
*
ns
,
int
msqid
,
int
cmd
,
int
version
,
void
__user
*
buf
)
int
cmd
,
struct
msginfo
*
msginfo
)
{
{
int
err
;
int
err
;
struct
msg_queue
*
msq
;
int
max_id
;
switch
(
cmd
)
{
case
IPC_INFO
:
case
MSG_INFO
:
{
struct
msginfo
msginfo
;
int
max_id
;
if
(
!
buf
)
return
-
EFAULT
;
/*
/*
* We must not return kernel stack data.
* We must not return kernel stack data.
* due to padding, it's not enough
* due to padding, it's not enough
* to set all member fields.
* to set all member fields.
*/
*/
err
=
security_msg_queue_msgctl
(
NULL
,
cmd
);
err
=
security_msg_queue_msgctl
(
NULL
,
cmd
);
if
(
err
)
if
(
err
)
return
err
;
return
err
;
memset
(
&
msginfo
,
0
,
sizeof
(
msginfo
));
memset
(
msginfo
,
0
,
sizeof
(
*
msginfo
));
msginfo
.
msgmni
=
ns
->
msg_ctlmni
;
msginfo
->
msgmni
=
ns
->
msg_ctlmni
;
msginfo
.
msgmax
=
ns
->
msg_ctlmax
;
msginfo
->
msgmax
=
ns
->
msg_ctlmax
;
msginfo
.
msgmnb
=
ns
->
msg_ctlmnb
;
msginfo
->
msgmnb
=
ns
->
msg_ctlmnb
;
msginfo
.
msgssz
=
MSGSSZ
;
msginfo
->
msgssz
=
MSGSSZ
;
msginfo
.
msgseg
=
MSGSEG
;
msginfo
->
msgseg
=
MSGSEG
;
down_read
(
&
msg_ids
(
ns
).
rwsem
);
down_read
(
&
msg_ids
(
ns
).
rwsem
);
if
(
cmd
==
MSG_INFO
)
{
if
(
cmd
==
MSG_INFO
)
{
msginfo
.
msgpool
=
msg_ids
(
ns
).
in_use
;
msginfo
->
msgpool
=
msg_ids
(
ns
).
in_use
;
msginfo
.
msgmap
=
atomic_read
(
&
ns
->
msg_hdrs
);
msginfo
->
msgmap
=
atomic_read
(
&
ns
->
msg_hdrs
);
msginfo
.
msgtql
=
atomic_read
(
&
ns
->
msg_bytes
);
msginfo
->
msgtql
=
atomic_read
(
&
ns
->
msg_bytes
);
}
else
{
}
else
{
msginfo
.
msgmap
=
MSGMAP
;
msginfo
->
msgmap
=
MSGMAP
;
msginfo
.
msgpool
=
MSGPOOL
;
msginfo
->
msgpool
=
MSGPOOL
;
msginfo
.
msgtql
=
MSGTQL
;
msginfo
->
msgtql
=
MSGTQL
;
}
max_id
=
ipc_get_maxid
(
&
msg_ids
(
ns
));
up_read
(
&
msg_ids
(
ns
).
rwsem
);
if
(
copy_to_user
(
buf
,
&
msginfo
,
sizeof
(
struct
msginfo
)))
return
-
EFAULT
;
return
(
max_id
<
0
)
?
0
:
max_id
;
}
}
max_id
=
ipc_get_maxid
(
&
msg_ids
(
ns
));
up_read
(
&
msg_ids
(
ns
).
rwsem
);
return
(
max_id
<
0
)
?
0
:
max_id
;
}
case
MSG_STAT
:
static
int
msgctl_stat
(
struct
ipc_namespace
*
ns
,
int
msqid
,
case
IPC_STAT
:
int
cmd
,
struct
msqid64_ds
*
p
)
{
{
struct
msqid64_ds
tbuf
;
int
err
;
int
success_return
;
struct
msg_queue
*
msq
;
int
success_return
;
if
(
!
buf
)
return
-
EFAULT
;
memset
(
&
tbuf
,
0
,
sizeof
(
tbuf
));
rcu_read_lock
();
memset
(
p
,
0
,
sizeof
(
*
p
));
if
(
cmd
==
MSG_STAT
)
{
msq
=
msq_obtain_object
(
ns
,
msqid
);
if
(
IS_ERR
(
msq
))
{
err
=
PTR_ERR
(
msq
);
goto
out_unlock
;
}
success_return
=
msq
->
q_perm
.
id
;
}
else
{
msq
=
msq_obtain_object_check
(
ns
,
msqid
);
if
(
IS_ERR
(
msq
))
{
err
=
PTR_ERR
(
msq
);
goto
out_unlock
;
}
success_return
=
0
;
}
err
=
-
EACCES
;
rcu_read_lock
();
if
(
ipcperms
(
ns
,
&
msq
->
q_perm
,
S_IRUGO
))
if
(
cmd
==
MSG_STAT
)
{
msq
=
msq_obtain_object
(
ns
,
msqid
);
if
(
IS_ERR
(
msq
))
{
err
=
PTR_ERR
(
msq
);
goto
out_unlock
;
goto
out_unlock
;
}
err
=
security_msg_queue_msgctl
(
msq
,
cmd
);
success_return
=
msq
->
q_perm
.
id
;
if
(
err
)
}
else
{
msq
=
msq_obtain_object_check
(
ns
,
msqid
);
if
(
IS_ERR
(
msq
))
{
err
=
PTR_ERR
(
msq
);
goto
out_unlock
;
goto
out_unlock
;
}
success_return
=
0
;
}
kernel_to_ipc64_perm
(
&
msq
->
q_perm
,
&
tbuf
.
msg_perm
);
err
=
-
EACCES
;
tbuf
.
msg_stime
=
msq
->
q_stime
;
if
(
ipcperms
(
ns
,
&
msq
->
q_perm
,
S_IRUGO
))
tbuf
.
msg_rtime
=
msq
->
q_rtime
;
goto
out_unlock
;
tbuf
.
msg_ctime
=
msq
->
q_ctime
;
tbuf
.
msg_cbytes
=
msq
->
q_cbytes
;
tbuf
.
msg_qnum
=
msq
->
q_qnum
;
tbuf
.
msg_qbytes
=
msq
->
q_qbytes
;
tbuf
.
msg_lspid
=
msq
->
q_lspid
;
tbuf
.
msg_lrpid
=
msq
->
q_lrpid
;
rcu_read_unlock
();
if
(
copy_msqid_to_user
(
buf
,
&
tbuf
,
version
))
err
=
security_msg_queue_msgctl
(
msq
,
cmd
);
return
-
EFAULT
;
if
(
err
)
return
success_return
;
goto
out_unlock
;
}
kernel_to_ipc64_perm
(
&
msq
->
q_perm
,
&
p
->
msg_perm
);
p
->
msg_stime
=
msq
->
q_stime
;
p
->
msg_rtime
=
msq
->
q_rtime
;
p
->
msg_ctime
=
msq
->
q_ctime
;
p
->
msg_cbytes
=
msq
->
q_cbytes
;
p
->
msg_qnum
=
msq
->
q_qnum
;
p
->
msg_qbytes
=
msq
->
q_qbytes
;
p
->
msg_lspid
=
msq
->
q_lspid
;
p
->
msg_lrpid
=
msq
->
q_lrpid
;
rcu_read_unlock
();
default:
return
success_return
;
return
-
EINVAL
;
}
return
err
;
out_unlock:
out_unlock:
rcu_read_unlock
();
rcu_read_unlock
();
return
err
;
return
err
;
...
@@ -556,6 +528,8 @@ SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, struct msqid_ds __user *, buf)
...
@@ -556,6 +528,8 @@ SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, struct msqid_ds __user *, buf)
{
{
int
version
;
int
version
;
struct
ipc_namespace
*
ns
;
struct
ipc_namespace
*
ns
;
struct
msqid64_ds
msqid64
;
int
err
;
if
(
msqid
<
0
||
cmd
<
0
)
if
(
msqid
<
0
||
cmd
<
0
)
return
-
EINVAL
;
return
-
EINVAL
;
...
@@ -565,13 +539,29 @@ SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, struct msqid_ds __user *, buf)
...
@@ -565,13 +539,29 @@ SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, struct msqid_ds __user *, buf)
switch
(
cmd
)
{
switch
(
cmd
)
{
case
IPC_INFO
:
case
IPC_INFO
:
case
MSG_INFO
:
case
MSG_INFO
:
{
struct
msginfo
msginfo
;
err
=
msgctl_info
(
ns
,
msqid
,
cmd
,
&
msginfo
);
if
(
err
<
0
)
return
err
;
if
(
copy_to_user
(
buf
,
&
msginfo
,
sizeof
(
struct
msginfo
)))
err
=
-
EFAULT
;
return
err
;
}
case
MSG_STAT
:
/* msqid is an index rather than a msg queue id */
case
MSG_STAT
:
/* msqid is an index rather than a msg queue id */
case
IPC_STAT
:
case
IPC_STAT
:
return
msgctl_nolock
(
ns
,
msqid
,
cmd
,
version
,
buf
);
err
=
msgctl_stat
(
ns
,
msqid
,
cmd
,
&
msqid64
);
if
(
err
<
0
)
return
err
;
if
(
copy_msqid_to_user
(
buf
,
&
msqid64
,
version
))
err
=
-
EFAULT
;
return
err
;
case
IPC_SET
:
case
IPC_SET
:
if
(
copy_msqid_from_user
(
&
msqid64
,
buf
,
version
))
return
-
EFAULT
;
/* fallthru */
case
IPC_RMID
:
case
IPC_RMID
:
return
msgctl_down
(
ns
,
msqid
,
cmd
,
buf
,
version
);
return
msgctl_down
(
ns
,
msqid
,
cmd
,
&
msqid64
);
default:
default:
return
-
EINVAL
;
return
-
EINVAL
;
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录