Skip to content

Commit aa7aeee

Browse files
tyhicksmartinetd
authored andcommitted
net/9p: Initialize the iounit field during fid creation
Ensure that the fid's iounit field is set to zero when a new fid is created. Certain 9P operations, such as OPEN and CREATE, allow the server to reply with an iounit size which the client code assigns to the p9_fid struct shortly after the fid is created by p9_fid_create(). On the other hand, an XATTRWALK operation doesn't allow for the server to specify an iounit value. The iounit field of the newly allocated p9_fid struct remained uninitialized in that case. Depending on allocation patterns, the iounit value could have been something reasonable that was carried over from previously freed fids or, in the worst case, could have been arbitrary values from non-fid related usages of the memory location. The bug was detected in the Windows Subsystem for Linux 2 (WSL2) kernel after the uninitialized iounit field resulted in the typical sequence of two getxattr(2) syscalls, one to get the size of an xattr and another after allocating a sufficiently sized buffer to fit the xattr value, to hit an unexpected ERANGE error in the second call to getxattr(2). An uninitialized iounit field would sometimes force rsize to be smaller than the xattr value size in p9_client_read_once() and the 9P server in WSL refused to chunk up the READ on the attr_fid and, instead, returned ERANGE to the client. The virtfs server in QEMU seems happy to chunk up the READ and this problem goes undetected there. Link: https://lkml.kernel.org/r/20220710141402.803295-1-tyhicks@linux.microsoft.com Fixes: ebf4626 ("fs/9p: Add support user. xattr") Cc: stable@vger.kernel.org Signed-off-by: Tyler Hicks <tyhicks@linux.microsoft.com> Reviewed-by: Christian Schoenebeck <linux_oss@crudebyte.com> Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
1 parent 4ac7573 commit aa7aeee

File tree

1 file changed

+1
-4
lines changed

1 file changed

+1
-4
lines changed

net/9p/client.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -887,16 +887,13 @@ static struct p9_fid *p9_fid_create(struct p9_client *clnt)
887887
struct p9_fid *fid;
888888

889889
p9_debug(P9_DEBUG_FID, "clnt %p\n", clnt);
890-
fid = kmalloc(sizeof(*fid), GFP_KERNEL);
890+
fid = kzalloc(sizeof(*fid), GFP_KERNEL);
891891
if (!fid)
892892
return NULL;
893893

894-
memset(&fid->qid, 0, sizeof(fid->qid));
895894
fid->mode = -1;
896895
fid->uid = current_fsuid();
897896
fid->clnt = clnt;
898-
fid->rdir = NULL;
899-
fid->fid = 0;
900897
refcount_set(&fid->count, 1);
901898

902899
idr_preload(GFP_KERNEL);

0 commit comments

Comments
 (0)