From: Christian Schoenebeck <qemu_oss@crudebyte.com>
To: qemu-devel@nongnu.org, Peter Maydell <peter.maydell@linaro.org>,
Richard Henderson <richard.henderson@linaro.org>
Cc: Greg Kurz <groug@kaod.org>,
Akihiko Odaki <akihiko.odaki@gmail.com>,
Will Cohen <wwcohen@gmail.com>
Subject: [PULL v2 4/7] 9pfs: fix wrong encoding of rdev field in Rgetattr on macOS
Date: Sun, 01 May 2022 15:10:16 +0200 [thread overview]
Message-ID: <e5c88e2264ebd0bfe35b347b8cdca1e3af784d84.1651410615.git.qemu_oss@crudebyte.com> (raw)
In-Reply-To: <cover.1651410615.git.qemu_oss@crudebyte.com>
The 'rdev' field in 9p reponse 'Rgetattr' is of type dev_t,
which is actually a system dependant type and therefore both the
size and encoding of dev_t differ between macOS and Linux.
So far we have sent 'rdev' to guest in host's dev_t format as-is,
which caused devices to appear with wrong device numbers on
guests running on macOS hosts, eventually leading to various
misbehaviours on guest in conjunction with device files.
This patch fixes this issue by converting the device number from
host's dev_t format to Linux dev_t format. As 9p request
'Tgettattr' is exclusive to protocol version 9p2000.L, it should
be fair to assume that 'rdev' field is assumed to be in Linux dev_t
format by client as well.
Signed-off-by: Christian Schoenebeck <qemu_oss@crudebyte.com>
Link: https://lore.kernel.org/qemu-devel/20220421093056.5ab1e7ed@bahia/
Reviewed-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Akihiko Odaki <akihiko.odaki@gmail.com>
Message-Id: <b3a430c2c382ba69a7405e04c0b090ab0d86f17e.1651228001.git.qemu_oss@crudebyte.com>
---
hw/9pfs/9p-util.h | 39 +++++++++++++++++++++++++++++++++++++++
hw/9pfs/9p.c | 2 +-
2 files changed, 40 insertions(+), 1 deletion(-)
diff --git a/hw/9pfs/9p-util.h b/hw/9pfs/9p-util.h
index 97e681e167..2cc9a5dbfb 100644
--- a/hw/9pfs/9p-util.h
+++ b/hw/9pfs/9p-util.h
@@ -19,6 +19,45 @@
#define O_PATH_9P_UTIL 0
#endif
+#if !defined(CONFIG_LINUX)
+
+/*
+ * Generates a Linux device number (a.k.a. dev_t) for given device major
+ * and minor numbers.
+ *
+ * To be more precise: it generates a device number in glibc's format
+ * (MMMM_Mmmm_mmmM_MMmm, 64 bits) actually, which is compatible with
+ * Linux's format (mmmM_MMmm, 32 bits), as described in <bits/sysmacros.h>.
+ */
+static inline uint64_t makedev_dotl(uint32_t dev_major, uint32_t dev_minor)
+{
+ uint64_t dev;
+
+ // from glibc sysmacros.h:
+ dev = (((uint64_t) (dev_major & 0x00000fffu)) << 8);
+ dev |= (((uint64_t) (dev_major & 0xfffff000u)) << 32);
+ dev |= (((uint64_t) (dev_minor & 0x000000ffu)) << 0);
+ dev |= (((uint64_t) (dev_minor & 0xffffff00u)) << 12);
+ return dev;
+}
+
+#endif
+
+/*
+ * Converts given device number from host's device number format to Linux
+ * device number format. As both the size of type dev_t and encoding of
+ * dev_t is system dependant, we have to convert them for Linux guests if
+ * host is not running Linux.
+ */
+static inline uint64_t host_dev_to_dotl_dev(dev_t dev)
+{
+#ifdef CONFIG_LINUX
+ return dev;
+#else
+ return makedev_dotl(major(dev), minor(dev));
+#endif
+}
+
#ifdef CONFIG_DARWIN
#define qemu_fgetxattr(...) fgetxattr(__VA_ARGS__, 0, 0)
#define qemu_lgetxattr(...) getxattr(__VA_ARGS__, 0, XATTR_NOFOLLOW)
diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c
index 225f31fc31..4a296a0b94 100644
--- a/hw/9pfs/9p.c
+++ b/hw/9pfs/9p.c
@@ -1327,7 +1327,7 @@ static int stat_to_v9stat_dotl(V9fsPDU *pdu, const struct stat *stbuf,
v9lstat->st_nlink = stbuf->st_nlink;
v9lstat->st_uid = stbuf->st_uid;
v9lstat->st_gid = stbuf->st_gid;
- v9lstat->st_rdev = stbuf->st_rdev;
+ v9lstat->st_rdev = host_dev_to_dotl_dev(stbuf->st_rdev);
v9lstat->st_size = stbuf->st_size;
v9lstat->st_blksize = stat_to_iounit(pdu, stbuf);
v9lstat->st_blocks = stbuf->st_blocks;
--
2.30.2
next prev parent reply other threads:[~2022-05-01 13:23 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-05-01 13:10 [PULL v2 0/7] 9p queue 2022-05-01 (previous 2022-04-30) Christian Schoenebeck
2022-05-01 13:10 ` [PULL v2 6/7] 9pfs: fix removing non-existent POSIX ACL xattr on macOS host Christian Schoenebeck
2022-05-01 13:10 ` [PULL v2 1/7] 9pfs: fix inode sequencing in 'synth' driver Christian Schoenebeck
2022-05-01 13:10 ` Christian Schoenebeck [this message]
2022-05-01 13:10 ` [PULL v2 7/7] 9pfs: fix qemu_mknodat() to always return -1 on error on macOS host Christian Schoenebeck
2022-05-01 13:10 ` [PULL v2 5/7] 9pfs: fix wrong errno being sent to Linux client " Christian Schoenebeck
2022-05-01 13:10 ` [PULL v2 3/7] 9pfs: fix qemu_mknodat(S_IFSOCK) on macOS Christian Schoenebeck
2022-05-01 13:10 ` [PULL v2 2/7] 9pfs: fix qemu_mknodat(S_IFREG) " Christian Schoenebeck
2022-05-01 16:52 ` [PULL v2 0/7] 9p queue 2022-05-01 (previous 2022-04-30) Richard Henderson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=e5c88e2264ebd0bfe35b347b8cdca1e3af784d84.1651410615.git.qemu_oss@crudebyte.com \
--to=qemu_oss@crudebyte.com \
--cc=akihiko.odaki@gmail.com \
--cc=groug@kaod.org \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=richard.henderson@linaro.org \
--cc=wwcohen@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).