From nobody Fri May 3 10:21:53 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.zohomail.com; dkim=fail; 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 1505406662406515.4495448900612; Thu, 14 Sep 2017 09:31:02 -0700 (PDT) Received: from localhost ([::1]:48860 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsX2a-0006ge-12 for importer@patchew.org; Thu, 14 Sep 2017 12:31:00 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53572) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsX1m-0005z6-0Q for qemu-devel@nongnu.org; Thu, 14 Sep 2017 12:30:11 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dsX1h-0003sk-0R for qemu-devel@nongnu.org; Thu, 14 Sep 2017 12:30:10 -0400 Received: from mail-lf0-x244.google.com ([2a00:1450:4010:c07::244]:37666) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1dsX1g-0003qU-Q3 for qemu-devel@nongnu.org; Thu, 14 Sep 2017 12:30:04 -0400 Received: by mail-lf0-x244.google.com with SMTP id q132so1862013lfe.4 for ; Thu, 14 Sep 2017 09:30:03 -0700 (PDT) Received: from localhost.localdomain (home.eubridge.org. [194.28.30.174]) by smtp.gmail.com with ESMTPSA id f26sm3095216lfl.44.2017.09.14.09.30.00 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 14 Sep 2017 09:30:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=zCgLKJX6B7B0M5P8LGUaQGDqRWN7cy7/0sEGx0Taqbc=; b=IZpT//Z1QSdDBTRc+Ui8TRzrQG54ZgIJ+Fng5rh2cEB71QkQYVuBFSJDWCnvoYl3zm Gwr4nYiuRh+o5uLxdcnMRJSKMtMImmpYYxERBup8vU58APQE+MT2E+xznPsNzoiV1lNp FFOq2hIEdYHjhOKwnVJ4Le7FhyxOale+QTudkSRE26Y1JQifh5chfCx3+6WbODqSlSmQ qhhpC2NHboYv/dRVVPfQQ9cNm4mgtKJQgtflvdP+fZHCM72GHdIRoLdiPJhspy0G42sC MNubM0diDGQfgd2rJHxNJfGCe4QUybhp/gI7+GJ1QbQLYk3LXIlZigWkmkUmURFkTkMV K4fA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=zCgLKJX6B7B0M5P8LGUaQGDqRWN7cy7/0sEGx0Taqbc=; b=Lh3O3EOkxJt6OmAvrWqbTCIX56J56Py+Dux9mKw1Kvqv0OU/YArhtDGhnNfeRt2vXP 5N6v6GXvKyS4JI2Zl9+dbTLWPkpT+xYHheQPeUDj6E9ouy1O3czVQjuXky3dd1P3YTk1 wMK5N/HZyc3zRyaq+dX/AFgnArGWfwU2dAfQWjoE/TN0tHjhv3UDe1OORrFTcVwia6LT 5Juk0WzuZP8bb6UhSIAfgoGVkR23zro3KAAZWhhYKfk9tol+5ZiodZ9nSH/d5GaPAlWD aU//FzjgSIsQ5y7cgEAdabvSEHaKtFMNyRR8S6uc0TFawk0GE9AvR6wqWMl3twFvrSEZ ctUA== X-Gm-Message-State: AHPjjUhkfmyE9kmVfspbiG7ixbf8enNgYn9uCeLULghGuY0DdRKLENCX xv3NCU0l8djRqg== X-Google-Smtp-Source: AOwi7QBtrTRAtBmDT6H4psQxq7NLWNK03Us36TE8haMxvqhVOGyf3VarUtcYmyEeHY+bw56kqPr6BQ== X-Received: by 10.25.223.65 with SMTP id q1mr2221165lfj.260.1505406602162; Thu, 14 Sep 2017 09:30:02 -0700 (PDT) From: Jan Dakinevich To: Greg Kurz , qemu-devel@nongnu.org Date: Thu, 14 Sep 2017 19:31:36 +0300 Message-Id: <1505406696-2260-1-git-send-email-jan.dakinevich@gmail.com> X-Mailer: git-send-email 2.1.4 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4010:c07::244 Subject: [Qemu-devel] [PATCH] 9pfs: check the size of transport buffer before marshaling 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: Jan Dakinevich , "Aneesh Kumar K.V" Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" v9fs_do_readdir_with_stat() and v9fs_do_readdir() stores as much data in the buffer as can fit unless marshaling erorr occurs. However, after commit 23a006d the behavior pdu_marshal was changed, and on error the routine assumes that buffers are misconfigured and breaks communication. Signed-off-by: Jan Dakinevich --- hw/9pfs/9p.c | 44 ++++++++++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c index 1e38109..8e0b87e 100644 --- a/hw/9pfs/9p.c +++ b/hw/9pfs/9p.c @@ -1679,6 +1679,16 @@ static void v9fs_init_qiov_from_pdu(QEMUIOVector *qi= ov, V9fsPDU *pdu, qemu_iovec_concat(qiov, &elem, skip, size); } =20 +static size_t v9fs_marshal_size(V9fsPDU *pdu) +{ + struct iovec *iov; + unsigned int niov; + + pdu->s->transport->init_in_iov_from_pdu(pdu, &iov, &niov, 0); + + return iov_size(iov, niov); +} + static int v9fs_xattr_read(V9fsState *s, V9fsPDU *pdu, V9fsFidState *fidp, uint64_t off, uint32_t max_count) { @@ -1725,6 +1735,10 @@ static int coroutine_fn v9fs_do_readdir_with_stat(V9= fsPDU *pdu, off_t saved_dir_pos; struct dirent *dent; =20 + /* 11 =3D 7 + 4 (7 =3D start offset, 4 =3D space for storing count) */ + size_t offset =3D 11; + size_t marshal_size =3D v9fs_marshal_size(pdu); + /* save the directory position */ saved_dir_pos =3D v9fs_co_telldir(pdu, fidp); if (saved_dir_pos < 0) { @@ -1752,18 +1766,23 @@ static int coroutine_fn v9fs_do_readdir_with_stat(V= 9fsPDU *pdu, if (err < 0) { break; } - /* 11 =3D 7 + 4 (7 =3D start offset, 4 =3D space for storing count= ) */ - len =3D pdu_marshal(pdu, 11 + count, "S", &v9stat); =20 - v9fs_readdir_unlock(&fidp->fs.dir); + if (v9stat.size + 2 > MIN(marshal_size - offset, max_count - count= )) { + v9fs_readdir_unlock(&fidp->fs.dir); =20 - if ((len !=3D (v9stat.size + 2)) || ((count + len) > max_count)) { /* Ran out of buffer. Set dir back to old position and return = */ v9fs_co_seekdir(pdu, fidp, saved_dir_pos); v9fs_stat_free(&v9stat); v9fs_path_free(&path); return count; } + + len =3D pdu_marshal(pdu, offset, "S", &v9stat); + BUG_ON(len !=3D v9stat.size + 2); + + v9fs_readdir_unlock(&fidp->fs.dir); + + offset +=3D len; count +=3D len; v9fs_stat_free(&v9stat); v9fs_path_free(&path); @@ -1884,6 +1903,10 @@ static int coroutine_fn v9fs_do_readdir(V9fsPDU *pdu= , V9fsFidState *fidp, off_t saved_dir_pos; struct dirent *dent; =20 + /* 11 =3D 7 + 4 (7 =3D start offset, 4 =3D space for storing count) */ + size_t offset =3D 11; + size_t marshal_size =3D v9fs_marshal_size(pdu); + /* save the directory position */ saved_dir_pos =3D v9fs_co_telldir(pdu, fidp); if (saved_dir_pos < 0) { @@ -1899,7 +1922,8 @@ static int coroutine_fn v9fs_do_readdir(V9fsPDU *pdu,= V9fsFidState *fidp, } v9fs_string_init(&name); v9fs_string_sprintf(&name, "%s", dent->d_name); - if ((count + v9fs_readdir_data_size(&name)) > max_count) { + if (v9fs_readdir_data_size(&name) > MIN(marshal_size - offset, + max_count - count)) { v9fs_readdir_unlock(&fidp->fs.dir); =20 /* Ran out of buffer. Set dir back to old position and return = */ @@ -1918,18 +1942,14 @@ static int coroutine_fn v9fs_do_readdir(V9fsPDU *pd= u, V9fsFidState *fidp, qid.type =3D 0; qid.version =3D 0; =20 - /* 11 =3D 7 + 4 (7 =3D start offset, 4 =3D space for storing count= ) */ - len =3D pdu_marshal(pdu, 11 + count, "Qqbs", + len =3D pdu_marshal(pdu, offset, "Qqbs", &qid, dent->d_off, dent->d_type, &name); + BUG_ON(len !=3D v9fs_readdir_data_size(&name)); =20 v9fs_readdir_unlock(&fidp->fs.dir); =20 - if (len < 0) { - v9fs_co_seekdir(pdu, fidp, saved_dir_pos); - v9fs_string_free(&name); - return len; - } + offset +=3D len; count +=3D len; v9fs_string_free(&name); saved_dir_pos =3D dent->d_off; --=20 2.1.4