From nobody Mon May 6 23:39:58 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 149399763059675.97623479958236; Fri, 5 May 2017 08:20:30 -0700 (PDT) Received: from localhost ([::1]:47478 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1d6f1w-0001A2-Vm for importer@patchew.org; Fri, 05 May 2017 11:20:29 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:60996) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1d6ezL-0007uK-6i for qemu-devel@nongnu.org; Fri, 05 May 2017 11:17:48 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1d6ezH-0007PE-V7 for qemu-devel@nongnu.org; Fri, 05 May 2017 11:17:47 -0400 Received: from 13.mo5.mail-out.ovh.net ([87.98.182.191]:54644) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1d6ezH-0007OM-OB for qemu-devel@nongnu.org; Fri, 05 May 2017 11:17:43 -0400 Received: from player786.ha.ovh.net (b6.ovh.net [213.186.33.56]) by mo5.mail-out.ovh.net (Postfix) with ESMTP id 30FE3EC065 for ; Fri, 5 May 2017 17:17:42 +0200 (CEST) Received: from bahia.lan (gar31-1-82-66-74-139.fbx.proxad.net [82.66.74.139]) (Authenticated sender: groug@kaod.org) by player786.ha.ovh.net (Postfix) with ESMTPA id 90EBD80830; Fri, 5 May 2017 16:37:04 +0200 (CEST) From: Greg Kurz To: qemu-devel@nongnu.org Date: Fri, 05 May 2017 16:37:04 +0200 Message-ID: <149399502436.29022.4452572475773635974.stgit@bahia.lan> In-Reply-To: <149399500677.29022.12340124231191204194.stgit@bahia.lan> References: <149399500677.29022.12340124231191204194.stgit@bahia.lan> User-Agent: StGit/0.17.1-20-gc0b1b-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Ovh-Tracer-Id: 10237526381112760648 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrfeeliedrieeggdekjecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 87.98.182.191 Subject: [Qemu-devel] [PATCH 1/5] 9pfs: check return value of v9fs_co_name_to_path() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?L=C3=A9o?= Gaspard , Greg Kurz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 These v9fs_co_name_to_path() call sites have always been around. I guess no care was taken to check the return value because the name_to_path operation could never fail at the time. This is no longer true: the handle and synth backends can already fail this operation, and so will the local backend soon. Signed-off-by: Greg Kurz Reviewed-by: Eric Blake --- hw/9pfs/9p.c | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c index c80ba67389ce..dc5250b342fa 100644 --- a/hw/9pfs/9p.c +++ b/hw/9pfs/9p.c @@ -2576,7 +2576,10 @@ static int coroutine_fn v9fs_complete_rename(V9fsPDU= *pdu, V9fsFidState *fidp, err =3D -EINVAL; goto out; } - v9fs_co_name_to_path(pdu, &dirfidp->path, name->data, &new_path); + err =3D v9fs_co_name_to_path(pdu, &dirfidp->path, name->data, &new= _path); + if (err < 0) { + goto out; + } } else { old_name =3D fidp->path.data; end =3D strrchr(old_name, '/'); @@ -2588,8 +2591,11 @@ static int coroutine_fn v9fs_complete_rename(V9fsPDU= *pdu, V9fsFidState *fidp, new_name =3D g_malloc0(end - old_name + name->size + 1); strncat(new_name, old_name, end - old_name); strncat(new_name + (end - old_name), name->data, name->size); - v9fs_co_name_to_path(pdu, NULL, new_name, &new_path); + err =3D v9fs_co_name_to_path(pdu, NULL, new_name, &new_path); g_free(new_name); + if (err < 0) { + goto out; + } } err =3D v9fs_co_rename(pdu, &fidp->path, &new_path); if (err < 0) { @@ -2669,20 +2675,26 @@ out_nofid: v9fs_string_free(&name); } =20 -static void coroutine_fn v9fs_fix_fid_paths(V9fsPDU *pdu, V9fsPath *olddir, - V9fsString *old_name, - V9fsPath *newdir, - V9fsString *new_name) +static int coroutine_fn v9fs_fix_fid_paths(V9fsPDU *pdu, V9fsPath *olddir, + V9fsString *old_name, + V9fsPath *newdir, + V9fsString *new_name) { V9fsFidState *tfidp; V9fsPath oldpath, newpath; V9fsState *s =3D pdu->s; - + int err; =20 v9fs_path_init(&oldpath); v9fs_path_init(&newpath); - v9fs_co_name_to_path(pdu, olddir, old_name->data, &oldpath); - v9fs_co_name_to_path(pdu, newdir, new_name->data, &newpath); + err =3D v9fs_co_name_to_path(pdu, olddir, old_name->data, &oldpath); + if (err < 0) { + goto out; + } + err =3D v9fs_co_name_to_path(pdu, newdir, new_name->data, &newpath); + if (err < 0) { + goto out; + } =20 /* * Fixup fid's pointing to the old name to @@ -2694,8 +2706,10 @@ static void coroutine_fn v9fs_fix_fid_paths(V9fsPDU = *pdu, V9fsPath *olddir, v9fs_fix_path(&tfidp->path, &newpath, strlen(oldpath.data)); } } +out: v9fs_path_free(&oldpath); v9fs_path_free(&newpath); + return err; } =20 static int coroutine_fn v9fs_complete_renameat(V9fsPDU *pdu, int32_t olddi= rfid, @@ -2729,8 +2743,8 @@ static int coroutine_fn v9fs_complete_renameat(V9fsPD= U *pdu, int32_t olddirfid, } if (s->ctx.export_flags & V9FS_PATHNAME_FSCONTEXT) { /* Only for path based fid we need to do the below fixup */ - v9fs_fix_fid_paths(pdu, &olddirfidp->path, old_name, - &newdirfidp->path, new_name); + err =3D v9fs_fix_fid_paths(pdu, &olddirfidp->path, old_name, + &newdirfidp->path, new_name); } out: if (olddirfidp) { From nobody Mon May 6 23:39:58 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1493997753301515.903529570461; Fri, 5 May 2017 08:22:33 -0700 (PDT) Received: from localhost ([::1]:47487 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1d6f3t-0002q2-RB for importer@patchew.org; Fri, 05 May 2017 11:22:29 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33207) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1d6f0H-0000CX-As for qemu-devel@nongnu.org; Fri, 05 May 2017 11:18:46 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1d6f0E-0007tw-1O for qemu-devel@nongnu.org; Fri, 05 May 2017 11:18:45 -0400 Received: from 20.mo5.mail-out.ovh.net ([91.121.55.239]:40029) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1d6f0D-0007t4-Rl for qemu-devel@nongnu.org; Fri, 05 May 2017 11:18:41 -0400 Received: from player786.ha.ovh.net (b6.ovh.net [213.186.33.56]) by mo5.mail-out.ovh.net (Postfix) with ESMTP id 72958EC728 for ; Fri, 5 May 2017 17:18:40 +0200 (CEST) Received: from bahia.lan (gar31-1-82-66-74-139.fbx.proxad.net [82.66.74.139]) (Authenticated sender: groug@kaod.org) by player786.ha.ovh.net (Postfix) with ESMTPA id 1A0C680846; Fri, 5 May 2017 16:37:13 +0200 (CEST) From: Greg Kurz To: qemu-devel@nongnu.org Date: Fri, 05 May 2017 16:37:12 +0200 Message-ID: <149399503288.29022.13904385823492355197.stgit@bahia.lan> In-Reply-To: <149399500677.29022.12340124231191204194.stgit@bahia.lan> References: <149399500677.29022.12340124231191204194.stgit@bahia.lan> User-Agent: StGit/0.17.1-20-gc0b1b-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Ovh-Tracer-Id: 10240059654095214920 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrfeeliedrieeggdekjecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 91.121.55.239 Subject: [Qemu-devel] [PATCH 2/5] 9pfs: local: resolve special directories in paths X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?L=C3=A9o?= Gaspard , Greg Kurz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 When using the mapped-file security mode, the creds of a path /foo/bar are stored in the /foo/.virtfs_metadata/bar file. This is okay for all paths unless they end with '.' or '..', because we cannot create the corresponding file in the metadata directory. This patch ensures that '.' and '..' are resolved in all paths. The core code only passes path elements (no '/') to the backend, with the notable exception of the '/' path, which refers to the virtfs root. This patch preserve the current behavior of converting it to '.' so that it can be passed to "*at()" syscalls ('/' would mean the host root). Signed-off-by: Greg Kurz --- hw/9pfs/9p-local.c | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c index f3ebca4f7a56..92262f3c3e37 100644 --- a/hw/9pfs/9p-local.c +++ b/hw/9pfs/9p-local.c @@ -1097,14 +1097,30 @@ static int local_name_to_path(FsContext *ctx, V9fsP= ath *dir_path, const char *name, V9fsPath *target) { if (dir_path) { - v9fs_path_sprintf(target, "%s/%s", dir_path->data, name); - } else if (strcmp(name, "/")) { - v9fs_path_sprintf(target, "%s", name); + if (!strcmp(name, ".")) { + /* "." relative to "foo/bar" is "foo/bar" */ + v9fs_path_copy(target, dir_path); + } else if (!strcmp(name, "..")) { + if (!strcmp(dir_path->data, ".")) { + /* ".." relative to the root is "." */ + v9fs_path_sprintf(target, "."); + } else { + char *tmp =3D g_path_get_dirname(dir_path->data); + /* ".." relative to "foo/bar" is equivalent to "foo" */ + v9fs_path_sprintf(target, "%s", tmp); + g_free(tmp); + } + } else { + assert(!strchr(name, '/')); + v9fs_path_sprintf(target, "%s/%s", dir_path->data, name); + } + } else if (!strcmp(name, "/") || !strcmp(name, ".") || + !strcmp(name, "..")) { + /* This is the root fid */ + v9fs_path_sprintf(target, "."); } else { - /* We want the path of the export root to be relative, otherwise - * "*at()" syscalls would treat it as "/" in the host. - */ - v9fs_path_sprintf(target, "%s", "."); + assert(!strchr(name, '/')); + v9fs_path_sprintf(target, "./%s", name); } return 0; } From nobody Mon May 6 23:39:58 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1493997663516733.4916494561584; Fri, 5 May 2017 08:21:03 -0700 (PDT) Received: from localhost ([::1]:47481 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1d6f2S-0001Rn-5q for importer@patchew.org; Fri, 05 May 2017 11:21:00 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33534) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1d6f1G-0000mH-2A for qemu-devel@nongnu.org; Fri, 05 May 2017 11:19:47 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1d6f1C-00008x-QU for qemu-devel@nongnu.org; Fri, 05 May 2017 11:19:46 -0400 Received: from 17.mo5.mail-out.ovh.net ([46.105.56.132]:51145) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1d6f1C-00007H-JH for qemu-devel@nongnu.org; Fri, 05 May 2017 11:19:42 -0400 Received: from player786.ha.ovh.net (b6.ovh.net [213.186.33.56]) by mo5.mail-out.ovh.net (Postfix) with ESMTP id 17A90EB6DE for ; Fri, 5 May 2017 17:19:41 +0200 (CEST) Received: from bahia.lan (gar31-1-82-66-74-139.fbx.proxad.net [82.66.74.139]) (Authenticated sender: groug@kaod.org) by player786.ha.ovh.net (Postfix) with ESMTPA id 934CB80857; Fri, 5 May 2017 16:37:21 +0200 (CEST) From: Greg Kurz To: qemu-devel@nongnu.org Date: Fri, 05 May 2017 16:37:21 +0200 Message-ID: <149399504137.29022.4985100698645275511.stgit@bahia.lan> In-Reply-To: <149399500677.29022.12340124231191204194.stgit@bahia.lan> References: <149399500677.29022.12340124231191204194.stgit@bahia.lan> User-Agent: StGit/0.17.1-20-gc0b1b-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Ovh-Tracer-Id: 10242311453152614728 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrfeeliedrieeggdekjecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 46.105.56.132 Subject: [Qemu-devel] [PATCH 3/5] 9pfs: local: simplify file opening X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?L=C3=A9o?= Gaspard , Greg Kurz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 All paths in the virtfs directory now start with "./" (except the virtfs root itself which is exactly "."). We hence don't need to skip leading '/' characters anymore, nor to handle the empty path case. Also, since virtfs will only ever be supported on linux+glibc hosts, we can use strchrnul() and come up with a much simplier code to walk through the path elements. And we don't need to dup() the passed directory fd. Signed-off-by: Greg Kurz --- hw/9pfs/9p-local.c | 5 ----- hw/9pfs/9p-util.c | 26 ++++++++++---------------- 2 files changed, 10 insertions(+), 21 deletions(-) diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c index 92262f3c3e37..bb6e296df317 100644 --- a/hw/9pfs/9p-local.c +++ b/hw/9pfs/9p-local.c @@ -54,11 +54,6 @@ int local_open_nofollow(FsContext *fs_ctx, const char *p= ath, int flags, { LocalData *data =3D fs_ctx->private; =20 - /* All paths are relative to the path data->mountfd points to */ - while (*path =3D=3D '/') { - path++; - } - return relative_openat_nofollow(data->mountfd, path, flags, mode); } =20 diff --git a/hw/9pfs/9p-util.c b/hw/9pfs/9p-util.c index fdb4d5737635..e46399a9119d 100644 --- a/hw/9pfs/9p-util.c +++ b/hw/9pfs/9p-util.c @@ -17,14 +17,11 @@ int relative_openat_nofollow(int dirfd, const char *path, int flags, mode_t mode) { - int fd; + int fd =3D dirfd; =20 - fd =3D dup(dirfd); - if (fd =3D=3D -1) { - return -1; - } + assert(*path); =20 - while (*path) { + while (*path && fd !=3D -1) { const char *c; int next_fd; char *head; @@ -33,25 +30,22 @@ int relative_openat_nofollow(int dirfd, const char *pat= h, int flags, assert(path[0] !=3D '/'); =20 head =3D g_strdup(path); - c =3D strchr(path, '/'); - if (c) { + c =3D strchrnul(path, '/'); + if (*c) { + /* Intermediate path element */ head[c - path] =3D 0; + path =3D c + 1; next_fd =3D openat_dir(fd, head); } else { + /* Rightmost path element */ next_fd =3D openat_file(fd, head, flags, mode); + path =3D c; } g_free(head); - if (next_fd =3D=3D -1) { + if (dirfd !=3D fd) { close_preserve_errno(fd); - return -1; } - close(fd); fd =3D next_fd; - - if (!c) { - break; - } - path =3D c + 1; } =20 return fd; From nobody Mon May 6 23:39:58 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1493997783551466.59681072051626; Fri, 5 May 2017 08:23:03 -0700 (PDT) Received: from localhost ([::1]:47489 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1d6f4N-0003Vm-Qh for importer@patchew.org; Fri, 05 May 2017 11:22:59 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33696) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1d6f22-0001Of-KJ for qemu-devel@nongnu.org; Fri, 05 May 2017 11:20:36 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1d6f1z-0000si-BZ for qemu-devel@nongnu.org; Fri, 05 May 2017 11:20:34 -0400 Received: from 16.mo5.mail-out.ovh.net ([87.98.174.144]:48754) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1d6f1z-0000r0-1l for qemu-devel@nongnu.org; Fri, 05 May 2017 11:20:31 -0400 Received: from player786.ha.ovh.net (b6.ovh.net [213.186.33.56]) by mo5.mail-out.ovh.net (Postfix) with ESMTP id A652EEC735 for ; Fri, 5 May 2017 17:20:29 +0200 (CEST) Received: from bahia.lan (gar31-1-82-66-74-139.fbx.proxad.net [82.66.74.139]) (Authenticated sender: groug@kaod.org) by player786.ha.ovh.net (Postfix) with ESMTPA id 1B4868056E; Fri, 5 May 2017 16:37:30 +0200 (CEST) From: Greg Kurz To: qemu-devel@nongnu.org Date: Fri, 05 May 2017 16:37:29 +0200 Message-ID: <149399504988.29022.13818395938763860712.stgit@bahia.lan> In-Reply-To: <149399500677.29022.12340124231191204194.stgit@bahia.lan> References: <149399500677.29022.12340124231191204194.stgit@bahia.lan> User-Agent: StGit/0.17.1-20-gc0b1b-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" X-Ovh-Tracer-Id: 10244844730233362760 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrfeeliedrieeggdeklecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 87.98.174.144 Subject: [Qemu-devel] [PATCH 4/5] 9pfs: local: metadata file for the VirtFS root X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?L=C3=A9o?= Gaspard , Greg Kurz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 When using the mapped-file security, credentials are stored in a metadata directory located in the parent directory. This is okay for all paths with the notable exception of the root path, since we don't want and probably can't create a metadata directory above the virtfs directory on the host. This patch introduces a dedicated metadata file, sitting in the virtfs root for this purpose. It relies on the fact that the "." name necessarily refer to the virtfs root. As for the metadata directory, we don't want the client to see this file. The current code only cares for readdir() but there are many other places to fix actually. The filtering logic is hence put in a separate function. Before: # ls -ld drwxr-xr-x. 3 greg greg 4096 May 5 12:49 . # chown root.root . chown: changing ownership of '.': Is a directory # ls -ld drwxr-xr-x. 3 greg greg 4096 May 5 12:49 . After: # ls -ld drwxr-xr-x. 3 greg greg 4096 May 5 12:49 . # chown bin.bin . # ls -ld drwxr-xr-x. 3 root root 4096 May 5 12:50 . and from the host: ls -al .virtfs_metadata_root -rwx------. 1 greg greg 26 May 5 12:50 .virtfs_metadata_root $ cat .virtfs_metadata_root virtfs.uid=3D0 virtfs.gid=3D0 Reported-by: L=C3=A9o Gaspard Signed-off-by: Greg Kurz --- hw/9pfs/9p-local.c | 88 ++++++++++++++++++++++++++++++++++++------------= ---- 1 file changed, 61 insertions(+), 27 deletions(-) diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c index bb6e296df317..b427d2928800 100644 --- a/hw/9pfs/9p-local.c +++ b/hw/9pfs/9p-local.c @@ -78,6 +78,7 @@ static void unlinkat_preserve_errno(int dirfd, const char= *path, int flags) } =20 #define VIRTFS_META_DIR ".virtfs_metadata" +#define VIRTFS_META_ROOT_FILE VIRTFS_META_DIR "_root" =20 static FILE *local_fopenat(int dirfd, const char *name, const char *mode) { @@ -114,13 +115,17 @@ static void local_mapped_file_attr(int dirfd, const c= har *name, char buf[ATTR_MAX]; int map_dirfd; =20 - map_dirfd =3D openat_dir(dirfd, VIRTFS_META_DIR); - if (map_dirfd =3D=3D -1) { - return; - } + if (strcmp(name, ".")) { + map_dirfd =3D openat_dir(dirfd, VIRTFS_META_DIR); + if (map_dirfd =3D=3D -1) { + return; + } =20 - fp =3D local_fopenat(map_dirfd, name, "r"); - close_preserve_errno(map_dirfd); + fp =3D local_fopenat(map_dirfd, name, "r"); + close_preserve_errno(map_dirfd); + } else { + fp =3D local_fopenat(dirfd, VIRTFS_META_ROOT_FILE, "r"); + } if (!fp) { return; } @@ -198,26 +203,38 @@ static int local_set_mapped_file_attrat(int dirfd, co= nst char *name, int ret; char buf[ATTR_MAX]; int uid =3D -1, gid =3D -1, mode =3D -1, rdev =3D -1; - int map_dirfd; - - ret =3D mkdirat(dirfd, VIRTFS_META_DIR, 0700); - if (ret < 0 && errno !=3D EEXIST) { - return -1; - } - - map_dirfd =3D openat_dir(dirfd, VIRTFS_META_DIR); - if (map_dirfd =3D=3D -1) { - return -1; - } + int map_dirfd, map_fd; + bool is_root =3D !strcmp(name, "."); + + if (is_root) { + fp =3D local_fopenat(dirfd, VIRTFS_META_ROOT_FILE, "r"); + if (!fp) { + if (errno =3D=3D ENOENT) { + goto update_map_file; + } else { + return -1; + } + } + } else { + ret =3D mkdirat(dirfd, VIRTFS_META_DIR, 0700); + if (ret < 0 && errno !=3D EEXIST) { + return -1; + } =20 - fp =3D local_fopenat(map_dirfd, name, "r"); - if (!fp) { - if (errno =3D=3D ENOENT) { - goto update_map_file; - } else { - close_preserve_errno(map_dirfd); + map_dirfd =3D openat_dir(dirfd, VIRTFS_META_DIR); + if (map_dirfd =3D=3D -1) { return -1; } + + fp =3D local_fopenat(map_dirfd, name, "r"); + if (!fp) { + if (errno =3D=3D ENOENT) { + goto update_map_file; + } else { + close_preserve_errno(map_dirfd); + return -1; + } + } } memset(buf, 0, ATTR_MAX); while (fgets(buf, ATTR_MAX, fp)) { @@ -235,12 +252,21 @@ static int local_set_mapped_file_attrat(int dirfd, co= nst char *name, fclose(fp); =20 update_map_file: - fp =3D local_fopenat(map_dirfd, name, "w"); - close_preserve_errno(map_dirfd); + if (is_root) { + fp =3D local_fopenat(dirfd, VIRTFS_META_ROOT_FILE, "w"); + } else { + fp =3D local_fopenat(map_dirfd, name, "w"); + close_preserve_errno(map_dirfd); + } if (!fp) { return -1; } =20 + map_fd =3D fileno(fp); + assert(map_fd !=3D -1); + ret =3D fchmod(map_fd, 0700); + assert(ret =3D=3D 0); + if (credp->fc_uid !=3D -1) { uid =3D credp->fc_uid; } @@ -447,6 +473,14 @@ static off_t local_telldir(FsContext *ctx, V9fsFidOpen= State *fs) return telldir(fs->dir.stream); } =20 +static bool local_must_skip_metadata(FsContext *fs_ctx, const char *name) +{ + return + fs_ctx->export_flags & V9FS_SM_MAPPED_FILE && + (!strcmp(name, VIRTFS_META_DIR) || + !strcmp(name, VIRTFS_META_ROOT_FILE)); +} + static struct dirent *local_readdir(FsContext *ctx, V9fsFidOpenState *fs) { struct dirent *entry; @@ -460,8 +494,8 @@ again: if (ctx->export_flags & V9FS_SM_MAPPED) { entry->d_type =3D DT_UNKNOWN; } else if (ctx->export_flags & V9FS_SM_MAPPED_FILE) { - if (!strcmp(entry->d_name, VIRTFS_META_DIR)) { - /* skp the meta data directory */ + if (local_must_skip_metadata(ctx, entry->d_name)) { + /* skip the meta data stuff */ goto again; } entry->d_type =3D DT_UNKNOWN; From nobody Mon May 6 23:39:58 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1493997760760117.82017473137762; Fri, 5 May 2017 08:22:40 -0700 (PDT) Received: from localhost ([::1]:47488 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1d6f3y-0002y3-Bo for importer@patchew.org; Fri, 05 May 2017 11:22:34 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33917) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1d6f2a-0001mz-Ul for qemu-devel@nongnu.org; Fri, 05 May 2017 11:21:10 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1d6f2X-0001dZ-Mm for qemu-devel@nongnu.org; Fri, 05 May 2017 11:21:08 -0400 Received: from 18.mo5.mail-out.ovh.net ([178.33.45.10]:37126) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1d6f2X-0001d2-G9 for qemu-devel@nongnu.org; Fri, 05 May 2017 11:21:05 -0400 Received: from player786.ha.ovh.net (b6.ovh.net [213.186.33.56]) by mo5.mail-out.ovh.net (Postfix) with ESMTP id CA6CFDE7DB for ; Fri, 5 May 2017 17:21:03 +0200 (CEST) Received: from bahia.lan (gar31-1-82-66-74-139.fbx.proxad.net [82.66.74.139]) (Authenticated sender: groug@kaod.org) by player786.ha.ovh.net (Postfix) with ESMTPA id 9CDC38086C; Fri, 5 May 2017 16:37:38 +0200 (CEST) From: Greg Kurz To: qemu-devel@nongnu.org Date: Fri, 05 May 2017 16:37:38 +0200 Message-ID: <149399505841.29022.17760460736155165332.stgit@bahia.lan> In-Reply-To: <149399500677.29022.12340124231191204194.stgit@bahia.lan> References: <149399500677.29022.12340124231191204194.stgit@bahia.lan> User-Agent: StGit/0.17.1-20-gc0b1b-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Ovh-Tracer-Id: 10247096530046064968 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrfeeliedrieeggdeklecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 178.33.45.10 Subject: [Qemu-devel] [PATCH 5/5] 9pfs: local: forbid client access to metadata X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?L=C3=A9o?= Gaspard , Greg Kurz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 When using the mapped-file security mode, we shouldn't let the client mess with the metadata. The current code already hides it but the client can still access the metadata through several operations. This patch fixes the issue by: - preventing the creation of fids pointing to the metadata (name_to_path) - failing various operations taking a dirpath and a name arguments if name is a metadata reserved name Signed-off-by: Greg Kurz --- hw/9pfs/9p-local.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c index b427d2928800..93cadac302c9 100644 --- a/hw/9pfs/9p-local.c +++ b/hw/9pfs/9p-local.c @@ -588,6 +588,11 @@ static int local_mknod(FsContext *fs_ctx, V9fsPath *di= r_path, int err =3D -1; int dirfd; =20 + if (local_must_skip_metadata(fs_ctx, name)) { + errno =3D EINVAL; + return -1; + } + dirfd =3D local_opendir_nofollow(fs_ctx, dir_path->data); if (dirfd =3D=3D -1) { return -1; @@ -634,6 +639,11 @@ static int local_mkdir(FsContext *fs_ctx, V9fsPath *di= r_path, int err =3D -1; int dirfd; =20 + if (local_must_skip_metadata(fs_ctx, name)) { + errno =3D EINVAL; + return -1; + } + dirfd =3D local_opendir_nofollow(fs_ctx, dir_path->data); if (dirfd =3D=3D -1) { return -1; @@ -723,6 +733,11 @@ static int local_open2(FsContext *fs_ctx, V9fsPath *di= r_path, const char *name, int err =3D -1; int dirfd; =20 + if (local_must_skip_metadata(fs_ctx, name)) { + errno =3D EINVAL; + return -1; + } + /* * Mark all the open to not follow symlinks */ @@ -781,6 +796,11 @@ static int local_symlink(FsContext *fs_ctx, const char= *oldpath, int err =3D -1; int dirfd; =20 + if (local_must_skip_metadata(fs_ctx, name)) { + errno =3D EINVAL; + return -1; + } + dirfd =3D local_opendir_nofollow(fs_ctx, dir_path->data); if (dirfd =3D=3D -1) { return -1; @@ -855,6 +875,11 @@ static int local_link(FsContext *ctx, V9fsPath *oldpat= h, int ret =3D -1; int odirfd, ndirfd; =20 + if (local_must_skip_metadata(ctx, name)) { + errno =3D EINVAL; + return -1; + } + odirfd =3D local_opendir_nofollow(ctx, odirpath); if (odirfd =3D=3D -1) { goto out; @@ -983,6 +1008,11 @@ static int local_unlinkat_common(FsContext *ctx, int = dirfd, const char *name, { int ret =3D -1; =20 + if (local_must_skip_metadata(ctx, name)) { + errno =3D EINVAL; + return -1; + } + if (ctx->export_flags & V9FS_SM_MAPPED_FILE) { int map_dirfd; =20 @@ -1125,6 +1155,11 @@ static int local_lremovexattr(FsContext *ctx, V9fsPa= th *fs_path, static int local_name_to_path(FsContext *ctx, V9fsPath *dir_path, const char *name, V9fsPath *target) { + if (local_must_skip_metadata(ctx, name)) { + errno =3D EINVAL; + return -1; + } + if (dir_path) { if (!strcmp(name, ".")) { /* "." relative to "foo/bar" is "foo/bar" */ @@ -1161,6 +1196,12 @@ static int local_renameat(FsContext *ctx, V9fsPath *= olddir, int ret; int odirfd, ndirfd; =20 + if (local_must_skip_metadata(ctx, old_name) || + local_must_skip_metadata(ctx, new_name)) { + errno =3D EINVAL; + return -1; + } + odirfd =3D local_opendir_nofollow(ctx, olddir->data); if (odirfd =3D=3D -1) { return -1;