提交 afcd6c3b 编写于 作者: W wanghao-free

fix: release1.0.1分支解决多进程情况下,pipe的内核操作节点存在使用脏私有字段dev,导致系统概率异常问题

问题场景描述:
(1)进程A使用pipe获取操作fd,然后循环使用poll操作;
(2)kill正在进行poll操作的进程A, pipe的fd会被回收,当pipe的设备节点未注销;
(3)进程B使用pipe获取操作fd,此时获取的内核操作节点为进程A创建的,存在使用进程A的操作节点的私有字段。
解决方案:pipe每次调用如果操作节点存在,就更新私有字段。

master分支已解决该问题。
Signed-off-by: Nwanghao-free <wanghao453@huawei.com>
上级 23d8ea4b
...@@ -48,6 +48,7 @@ ...@@ -48,6 +48,7 @@
#include <fs/fs.h> #include <fs/fs.h>
#include "pipe_common.h" #include "pipe_common.h"
#include "inode/inode.h"
#include "stdio.h" #include "stdio.h"
#if CONFIG_DEV_PIPE_SIZE > 0 #if CONFIG_DEV_PIPE_SIZE > 0
...@@ -226,6 +227,42 @@ static int pipe_unlink(FAR struct inode *priv) ...@@ -226,6 +227,42 @@ static int pipe_unlink(FAR struct inode *priv)
* *
****************************************************************************/ ****************************************************************************/
static void UpdateDev(struct pipe_dev_s *dev)
{
FAR struct inode *node;
struct pipe_dev_s *olddev = NULL;
struct inode_search_s desc;
SETUP_SEARCH(&desc, dev->name, fasle);
FAR const char *path = desc.path;
FAR const char **relpath = &(desc.relpath);
FAR struct inode **peer = &(desc.peer);
FAR struct inode **parent = &(desc.parent);
inode_semtake();
desc.node = inode_search(&path, peer, parent, relpath);
if (desc.node == NULL)
{
inode_semgive();
PRINT_ERR("[%s,%d] failed.\n", __FUNCTION__, __LINE__);
return;
}
node = desc.node;
olddev = (struct pipe_dev_s *)node->i_private;
if (olddev != NULL)
{
if (olddev->d_buffer != NULL)
{
free(olddev->d_buffer);
olddev->d_buffer = NULL;
}
pipecommon_freedev(olddev);
}
node->i_private = dev;
inode_semgive();
return;
}
int pipe(int fd[2]) int pipe(int fd[2])
{ {
FAR struct pipe_dev_s *dev = NULL; FAR struct pipe_dev_s *dev = NULL;
...@@ -258,10 +295,6 @@ int pipe(int fd[2]) ...@@ -258,10 +295,6 @@ int pipe(int fd[2])
snprintf_s(devname, sizeof(devname), sizeof(devname) - 1, "/dev/pipe%d", pipeno); snprintf_s(devname, sizeof(devname), sizeof(devname) - 1, "/dev/pipe%d", pipeno);
/* Check if the pipe device has already been created */
if ((g_pipecreated & (1 << pipeno)) == 0)
{
/* No.. Allocate and initialize a new device structure instance */ /* No.. Allocate and initialize a new device structure instance */
dev = pipecommon_allocdev(bufsize, devname); dev = pipecommon_allocdev(bufsize, devname);
...@@ -274,6 +307,10 @@ int pipe(int fd[2]) ...@@ -274,6 +307,10 @@ int pipe(int fd[2])
dev->d_pipeno = pipeno; dev->d_pipeno = pipeno;
/* Check if the pipe device has already been created */
if ((g_pipecreated & (1 << pipeno)) == 0)
{
/* Register the pipe device */ /* Register the pipe device */
ret = register_driver(devname, &pipe_fops, 0660, (FAR void *)dev); ret = register_driver(devname, &pipe_fops, 0660, (FAR void *)dev);
...@@ -288,6 +325,10 @@ int pipe(int fd[2]) ...@@ -288,6 +325,10 @@ int pipe(int fd[2])
g_pipecreated |= (1 << pipeno); g_pipecreated |= (1 << pipeno);
} }
else
{
UpdateDev(dev);
}
(void)sem_post(&g_pipesem); (void)sem_post(&g_pipesem);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册