On Donnerstag, 27. Mai 2021 19:04:11 CEST Christian Schoenebeck wrote: > We already capture the QID of the exported 9p root path, i.e. to > prevent client access outside the defined, exported filesystem's tree. > This is currently checked by comparing the root QID with another FID's > QID. > > The problem with the latter is that resolving a QID of any given 9p path > can only be done on 9p server's main thread, that's because it might > mutate the server's state if inode remapping is enabled. > > For that reason also capture the POSIX stat info of the root path for > being able to identify on any (e.g. worker) thread whether an > arbitrary given path is identical to the export root. > > Signed-off-by: Christian Schoenebeck <qemu_...@crudebyte.com> > --- > hw/9pfs/9p.c | 10 +++++++++- > hw/9pfs/9p.h | 1 + > 2 files changed, 10 insertions(+), 1 deletion(-) > > diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c > index 89aa07db78..825de1561d 100644 > --- a/hw/9pfs/9p.c > +++ b/hw/9pfs/9p.c > @@ -1400,6 +1400,7 @@ static void coroutine_fn v9fs_attach(void *opaque) > size_t offset = 7; > V9fsQID qid; > ssize_t err; > + struct stat stbuf; > > v9fs_string_init(&uname); > v9fs_string_init(&aname); > @@ -1422,7 +1423,13 @@ static void coroutine_fn v9fs_attach(void *opaque) > clunk_fid(s, fid); > goto out; > } > - err = fid_to_qid(pdu, fidp, &qid); > + err = v9fs_co_lstat(pdu, &fidp->path, &stbuf); > + if (err < 0) { > + err = -EINVAL; > + clunk_fid(s, fid); > + goto out; > + } > + err = stat_to_qid(pdu, &stbuf, &qid); > if (err < 0) { > err = -EINVAL; > clunk_fid(s, fid); > @@ -1455,6 +1462,7 @@ static void coroutine_fn v9fs_attach(void *opaque) > err += offset; > > memcpy(&s->root_qid, &qid, sizeof(qid)); > + memcpy(&s->root_st, &stbuf, sizeof(struct stat));
I'll make that sizeof(stbuf) instead to match with common code style here. > trace_v9fs_attach_return(pdu->tag, pdu->id, > qid.type, qid.version, qid.path); > out: > diff --git a/hw/9pfs/9p.h b/hw/9pfs/9p.h > index 00381591ff..6f0b4c78c0 100644 > --- a/hw/9pfs/9p.h > +++ b/hw/9pfs/9p.h > @@ -356,6 +356,7 @@ struct V9fsState { > Error *migration_blocker; > V9fsConf fsconf; > V9fsQID root_qid; > + struct stat root_st; > dev_t dev_id; > struct qht qpd_table; > struct qht qpp_table;