提交 6280c975 编写于 作者: F Far

fix: 修复NFS使用不可靠父节点信息的错误

NFS的read/write/readpage/writepage接口在读写数据前会尝试更新当前节点的fhandle,更新时会取用父节点vnode的私有数据。
此时如果父节点已经被释放,则可能导致访问空指针或错误数据。因此需要将父节点fhandle保存在当前节点私有数据中。

Close #I4EZ0V
Signed-off-by: NFar <yesiyuan2@huawei.com>
上级 924604f7
......@@ -824,6 +824,7 @@ int vfs_nfs_mount(struct Mount *mnt, struct Vnode *device, const void *data)
vp->data = root;
root->n_fhsize = nmp->nm_fhsize;
(void)memcpy_s(&(root->n_fhandle), root->n_fhsize, &(nmp->nm_fh), nmp->nm_fhsize);
root->n_pfhsize = 0;
mnt->vnodeCovered = vp;
mnt->data = nmp;
root->n_next = nmp->nm_head;
......@@ -874,6 +875,8 @@ int vfs_nfs_lookup(struct Vnode *parent, const char *path, int len, struct Vnode
nfs_node = zalloc(sizeof(struct nfsnode));
nfs_node->n_fhsize = (uint8_t)fhandle.length;
memcpy_s(&(nfs_node->n_fhandle), nfs_node->n_fhsize, &(fhandle.handle), fhandle.length);
nfs_node->n_pfhsize = parent_nfs_node->n_fhsize;
(void)memcpy_s(&(nfs_node->n_pfhandle), NFSX_V3FHMAX, &(parent_nfs_node->n_fhandle), parent_nfs_node->n_fhsize);
nfs_node->n_name = zalloc(sizeof(filename));
memcpy_s(nfs_node->n_name, (len + 1), filename, sizeof(filename));
nfs_node->n_next = nmp->nm_head;
......@@ -1523,6 +1526,8 @@ int vfs_nfs_mkdir(struct Vnode *parent, const char *dirname, mode_t mode, struct
target_node = zalloc(sizeof(struct nfsnode));
target_node->n_fhsize = (uint8_t)fhandle.length;
memcpy_s(&(target_node->n_fhandle), target_node->n_fhsize, &(fhandle.handle), fhandle.length);
target_node->n_pfhsize = parent_nfs_node->n_fhsize;
(void)memcpy_s(&(target_node->n_pfhandle), NFSX_V3FHMAX, &(parent_nfs_node->n_fhandle), parent_nfs_node->n_fhsize);
target_node->n_name = zalloc(sizeof (dirname));
memcpy_s(target_node->n_name, sizeof(dirname), dirname, sizeof (dirname));
target_node->n_next = nmp->nm_head;
......@@ -1576,10 +1581,10 @@ int vfs_nfs_write(struct file *filep, const char *buffer, size_t buflen)
goto errout_with_mutex;
}
parent_fhandle.length = ((struct nfsnode *)node->parent->data)->n_fhsize;
memcpy_s(&(parent_fhandle.handle), parent_fhandle.length,
&(((struct nfsnode *)node->parent->data)->n_fhandle),
((struct nfsnode *)node->parent->data)->n_fhsize);
parent_fhandle.length = ((struct nfsnode *)node->data)->n_pfhsize;
(void)memcpy_s(&(parent_fhandle.handle), NFSX_V3FHMAX,
&(((struct nfsnode *)node->data)->n_pfhandle),
((struct nfsnode *)node->data)->n_pfhsize);
if (filep->f_oflags & O_APPEND)
{
......@@ -1794,10 +1799,10 @@ ssize_t vfs_nfs_writepage(struct Vnode *node, char *buffer, off_t pos, size_t bu
goto errout_with_mutex;
}
parent_fhandle.length = ((struct nfsnode *)node->parent->data)->n_fhsize;
memcpy_s(&(parent_fhandle.handle), parent_fhandle.length,
&(((struct nfsnode *)node->parent->data)->n_fhandle),
((struct nfsnode *)node->parent->data)->n_fhsize);
parent_fhandle.length = ((struct nfsnode *)node->data)->n_pfhsize;
(void)memcpy_s(&(parent_fhandle.handle), NFSX_V3FHMAX,
&(((struct nfsnode *)node->data)->n_pfhandle),
((struct nfsnode *)node->data)->n_pfhsize);
/* Check if the file size would exceed the range of off_t */
......@@ -2066,10 +2071,10 @@ ssize_t vfs_nfs_readpage(struct Vnode *node, char *buffer, off_t pos)
}
parent_fhandle.length = ((struct nfsnode *)node->parent->data)->n_fhsize;
memcpy_s(&(parent_fhandle.handle), parent_fhandle.length,
&(((struct nfsnode *)node->parent->data)->n_fhandle),
((struct nfsnode *)node->parent->data)->n_fhsize);
parent_fhandle.length = ((struct nfsnode *)node->data)->n_pfhsize;
(void)memcpy_s(&(parent_fhandle.handle), NFSX_V3FHMAX,
&(((struct nfsnode *)node->data)->n_pfhandle),
((struct nfsnode *)node->data)->n_pfhsize);
error = nfs_fileupdate(nmp, np->n_name, &parent_fhandle, np);
if (error != OK)
{
......@@ -2217,10 +2222,10 @@ ssize_t vfs_nfs_read(struct file *filep, char *buffer, size_t buflen)
}
parent_fhandle.length = ((struct nfsnode *)node->parent->data)->n_fhsize;
memcpy_s(&(parent_fhandle.handle), parent_fhandle.length,
&(((struct nfsnode *)node->parent->data)->n_fhandle),
((struct nfsnode *)node->parent->data)->n_fhsize);
parent_fhandle.length = ((struct nfsnode *)node->data)->n_pfhsize;
(void)memcpy_s(&(parent_fhandle.handle), NFSX_V3FHMAX,
&(((struct nfsnode *)node->data)->n_pfhandle),
((struct nfsnode *)node->data)->n_pfhsize);
error = nfs_fileupdate(nmp, np->n_name, &parent_fhandle, np);
if (error != OK)
{
......@@ -2497,6 +2502,9 @@ int vfs_nfs_create(struct Vnode *parent, const char *filename, int mode, struct
np->n_next = nmp->nm_head;
nmp->nm_head = np;
np->n_pfhsize = parent_nfs_node->n_fhsize;
(void)memcpy_s(&(np->n_pfhandle), NFSX_V3FHMAX, &(parent_nfs_node->n_fhandle), parent_nfs_node->n_fhsize);
np->n_flags |= (NFSNODE_OPEN | NFSNODE_MODIFIED);
np->n_name = zalloc(namelen + 1);
memcpy_s(np->n_name, (namelen + 1), filename, (namelen + 1));
......
......@@ -79,12 +79,14 @@ struct nfsnode
uint8_t n_crefs; /* Reference count (for nfs_dup) */
uint8_t n_type; /* File type */
uint8_t n_fhsize; /* Size in bytes of the file handle */
uint8_t n_pfhsize; /* Size in bytes of the file handle of parent */
uint8_t n_flags; /* Node flags */
uint16_t n_mode; /* File mode for fstat() */
time_t n_atime; /* File access time */
time_t n_mtime; /* File modification time */
time_t n_ctime; /* File creation time */
nfsfh_t n_fhandle; /* NFS File Handle */
nfsfh_t n_pfhandle; /* NFS File Handle of parent */
uint64_t n_size; /* Current size of file */
int n_oflags; /* Flags provided when file was opened */
loff_t n_fpos; /* NFS File position */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册