From nobody Thu Nov 6 19:55:37 2025 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 1488149557238448.1165841531389; Sun, 26 Feb 2017 14:52:37 -0800 (PST) Received: from localhost ([::1]:48789 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ci7gB-0004q9-LP for importer@patchew.org; Sun, 26 Feb 2017 17:52:35 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50462) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ci7WR-0004ng-66 for qemu-devel@nongnu.org; Sun, 26 Feb 2017 17:42:34 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ci7WO-0002mq-0y for qemu-devel@nongnu.org; Sun, 26 Feb 2017 17:42:31 -0500 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:44394) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ci7WN-0002mb-NG for qemu-devel@nongnu.org; Sun, 26 Feb 2017 17:42:27 -0500 Received: from pps.filterd (m0098404.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.20/8.16.0.20) with SMTP id v1QMcPda120614 for ; Sun, 26 Feb 2017 17:42:26 -0500 Received: from e17.ny.us.ibm.com (e17.ny.us.ibm.com [129.33.205.207]) by mx0a-001b2d01.pphosted.com with ESMTP id 28u6wa42ur-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Sun, 26 Feb 2017 17:42:26 -0500 Received: from localhost by e17.ny.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Sun, 26 Feb 2017 17:42:25 -0500 Received: from d01dlp01.pok.ibm.com (9.56.250.166) by e17.ny.us.ibm.com (146.89.104.204) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Sun, 26 Feb 2017 17:42:21 -0500 Received: from b01cxnp23033.gho.pok.ibm.com (b01cxnp23033.gho.pok.ibm.com [9.57.198.28]) by d01dlp01.pok.ibm.com (Postfix) with ESMTP id 26C8038C8041; Sun, 26 Feb 2017 17:42:22 -0500 (EST) Received: from b01ledav006.gho.pok.ibm.com (b01ledav006.gho.pok.ibm.com [9.57.199.111]) by b01cxnp23033.gho.pok.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id v1QMgLVv29032514; Sun, 26 Feb 2017 22:42:21 GMT Received: from b01ledav006.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 6DC76AC043; Sun, 26 Feb 2017 17:42:17 -0500 (EST) Received: from [192.168.66.23] (unknown [9.164.183.34]) by b01ledav006.gho.pok.ibm.com (Postfix) with ESMTP id 2A2F1AC03A; Sun, 26 Feb 2017 17:42:16 -0500 (EST) From: Greg Kurz To: qemu-devel@nongnu.org Date: Sun, 26 Feb 2017 23:42:18 +0100 In-Reply-To: <148814889214.28146.16915712763478774662.stgit@bahia> References: <148814889214.28146.16915712763478774662.stgit@bahia> 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-TM-AS-GCONF: 00 X-Content-Scanned: Fidelis XPS MAILER x-cbid: 17022622-0040-0000-0000-000002B84C99 X-IBM-SpamModules-Scores: X-IBM-SpamModules-Versions: BY=3.00006689; HX=3.00000240; KW=3.00000007; PH=3.00000004; SC=3.00000204; SDB=6.00827424; UDB=6.00405424; IPR=6.00604939; BA=6.00005172; NDR=6.00000001; ZLA=6.00000005; ZF=6.00000009; ZB=6.00000000; ZP=6.00000000; ZH=6.00000000; ZU=6.00000002; MB=3.00014449; XFM=3.00000011; UTC=2017-02-26 22:42:23 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 17022622-0041-0000-0000-000006AB78E8 Message-Id: <148814893846.28146.10539730675852394601.stgit@bahia> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2017-02-26_11:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=3 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1612050000 definitions=main-1702260233 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [generic] [fuzzy] X-Received-From: 148.163.156.1 Subject: [Qemu-devel] [PATCH v2 06/28] 9pfs: local: open/opendir: don't follow symlinks 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: Jann Horn , Prasad J Pandit , Greg Kurz , "Aneesh Kumar K.V" , Stefan Hajnoczi Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 The local_open() and local_opendir() callbacks are vulnerable to symlink attacks because they call: (1) open(O_NOFOLLOW) which follows symbolic links in all path elements but the rightmost one (2) opendir() which follows symbolic links in all path elements This patch converts both callbacks to use new helpers based on openat_nofollow() to only open files and directories if they are below the virtfs shared folder This partly fixes CVE-2016-9602. Signed-off-by: Greg Kurz Reviewed-by: Stefan Hajnoczi --- v2: - use LocalData type - strip leading '/' characters in local_open_nofollow() --- hw/9pfs/9p-local.c | 37 +++++++++++++++++++++++++++---------- hw/9pfs/9p-local.h | 20 ++++++++++++++++++++ 2 files changed, 47 insertions(+), 10 deletions(-) create mode 100644 hw/9pfs/9p-local.h diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c index be6be615149b..74b921e65316 100644 --- a/hw/9pfs/9p-local.c +++ b/hw/9pfs/9p-local.c @@ -13,6 +13,7 @@ =20 #include "qemu/osdep.h" #include "9p.h" +#include "9p-local.h" #include "9p-xattr.h" #include "9p-util.h" #include "fsdev/qemu-fsdev.h" /* local_ops */ @@ -48,6 +49,24 @@ typedef struct { int mountfd; } LocalData; =20 +int local_open_nofollow(FsContext *fs_ctx, const char *path, int flags, + mode_t mode) +{ + LocalData *data =3D fs_ctx->private; + + /* All paths are relative to the path data->mountfd points to */ + while (*path =3D=3D '/') { + path++; + } + + return openat_nofollow(data->mountfd, path, flags, mode); +} + +int local_opendir_nofollow(FsContext *fs_ctx, const char *path) +{ + return local_open_nofollow(fs_ctx, path, O_DIRECTORY | O_RDONLY, 0); +} + #define VIRTFS_META_DIR ".virtfs_metadata" =20 static char *local_mapped_attr_path(FsContext *ctx, const char *path) @@ -359,13 +378,9 @@ static int local_closedir(FsContext *ctx, V9fsFidOpenS= tate *fs) static int local_open(FsContext *ctx, V9fsPath *fs_path, int flags, V9fsFidOpenState *fs) { - char *buffer; - char *path =3D fs_path->data; int fd; =20 - buffer =3D rpath(ctx, path); - fd =3D open(buffer, flags | O_NOFOLLOW); - g_free(buffer); + fd =3D local_open_nofollow(ctx, fs_path->data, flags, 0); if (fd =3D=3D -1) { return -1; } @@ -376,13 +391,15 @@ static int local_open(FsContext *ctx, V9fsPath *fs_pa= th, static int local_opendir(FsContext *ctx, V9fsPath *fs_path, V9fsFidOpenState *fs) { - char *buffer; - char *path =3D fs_path->data; + int dirfd; DIR *stream; =20 - buffer =3D rpath(ctx, path); - stream =3D opendir(buffer); - g_free(buffer); + dirfd =3D local_opendir_nofollow(ctx, fs_path->data); + if (dirfd =3D=3D -1) { + return -1; + } + + stream =3D fdopendir(dirfd); if (!stream) { return -1; } diff --git a/hw/9pfs/9p-local.h b/hw/9pfs/9p-local.h new file mode 100644 index 000000000000..32c72749d9df --- /dev/null +++ b/hw/9pfs/9p-local.h @@ -0,0 +1,20 @@ +/* + * 9p local backend utilities + * + * Copyright IBM, Corp. 2017 + * + * Authors: + * Greg Kurz + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#ifndef QEMU_9P_LOCAL_H +#define QEMU_9P_LOCAL_H + +int local_open_nofollow(FsContext *fs_ctx, const char *path, int flags, + mode_t mode); +int local_opendir_nofollow(FsContext *fs_ctx, const char *path); + +#endif