From nobody Sun Feb 8 13:27:20 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1639063703; cv=none; d=zohomail.com; s=zohoarc; b=jc64F6g3c34lZH9gXGYkWwbGYgwB7aawx5O5Nl+nuPwcFhb7AtpYPThNWpuMoWdZ+iXgqIH8XUFCwCl/FFrOA8IX74WcOgy33ButuVewQOXFv6CP8JPoW/5+Lhx0JbHNzsU8bG9XoVgpxDDGPa/igadiGIMaan2oA3KXHC0Nqas= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1639063703; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Sender:Subject:To; bh=HzYBszSg3MVNf/0Fe+fTHK8ckxr3/OG0Uw/mmgq+oPo=; b=Bxvab6qKz/kyMzj3PyFJtqbxaDhlLiHDlQ4SbZIPbPq++lXl5jvJa/qMqQjpjm8lmJZFGhjk7onc3EbyKL4cHmvNcZep66LxpHwUBN9FxYiw29AeZJzpZXBTrC68/2gOnXQEV35mPAn5NB0g/EbZ461Y4lIjOAOQ4ikvP1YS0ic= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1639063703023827.6652936203591; Thu, 9 Dec 2021 07:28:23 -0800 (PST) Received: from localhost ([::1]:39844 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mvLLK-0006RP-2r for importer@patchew.org; Thu, 09 Dec 2021 10:28:22 -0500 Received: from eggs.gnu.org ([209.51.188.92]:39534) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mvLFp-0006Wp-0R for qemu-devel@nongnu.org; Thu, 09 Dec 2021 10:22:41 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]:42956) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mvLFm-0000Rw-2P for qemu-devel@nongnu.org; Thu, 09 Dec 2021 10:22:40 -0500 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-425-B8vG3XHTO92572q4VIUfyQ-1; Thu, 09 Dec 2021 10:22:34 -0500 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 7CBD1760C0; Thu, 9 Dec 2021 15:22:33 +0000 (UTC) Received: from merkur.fritz.box (unknown [10.39.193.205]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9B2B719D9F; Thu, 9 Dec 2021 15:22:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1639063357; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=HzYBszSg3MVNf/0Fe+fTHK8ckxr3/OG0Uw/mmgq+oPo=; b=Z25DszOIqYeY50YWfLM2Dc115iIYnu0bOhuPqdC6Upd/U7YuYQNY4LhPm2tcxw2RcWAftK RQkGm+dQx2Lg7SlYcTgI+6BQxz0jBHUoxqBekpgdiYhF7isxBJf6yAqjmolhy04nHHT7RU kXQtMrVY1YQc6Pcg4Fy+HCVIuMpcvm0= X-MC-Unique: B8vG3XHTO92572q4VIUfyQ-1 From: Kevin Wolf To: qemu-block@nongnu.org Subject: [PATCH] vvfat: Fix vvfat_write() for writes before the root directory Date: Thu, 9 Dec 2021 16:22:31 +0100 Message-Id: <20211209152231.23756-1-kwolf@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=kwolf@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.129.124; envelope-from=kwolf@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -33 X-Spam_score: -3.4 X-Spam_bar: --- X-Spam_report: (-3.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.618, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1639063704682100001 Content-Type: text/plain; charset="utf-8" The calculation in sector2cluster() is done relative to the offset of the root directory. Any writes to blocks before the start of the root directory (in particular, writes to the FAT) result in negative values, which are not handled correctly in vvfat_write(). This changes sector2cluster() to return a signed value, and makes sure that vvfat_write() doesn't try to find mappings for negative cluster number. It clarifies the code in vvfat_write() to make it more obvious that the cluster numbers can be negative. Signed-off-by: Kevin Wolf --- block/vvfat.c | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/block/vvfat.c b/block/vvfat.c index 9deb552e0e..99a3bc2568 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -882,7 +882,7 @@ static int read_directory(BDRVVVFATState* s, int mappin= g_index) return 0; } =20 -static inline uint32_t sector2cluster(BDRVVVFATState* s,off_t sector_num) +static inline int32_t sector2cluster(BDRVVVFATState* s,off_t sector_num) { return (sector_num - s->offset_to_root_dir) / s->sectors_per_cluster; } @@ -2971,6 +2971,7 @@ static int vvfat_write(BlockDriverState *bs, int64_t = sector_num, { BDRVVVFATState *s =3D bs->opaque; int i, ret; + int first_cluster, last_cluster; =20 DLOG(checkpoint()); =20 @@ -2989,9 +2990,20 @@ DLOG(checkpoint()); if (sector_num < s->offset_to_fat) return -1; =20 - for (i =3D sector2cluster(s, sector_num); - i <=3D sector2cluster(s, sector_num + nb_sectors - 1);) { - mapping_t* mapping =3D find_mapping_for_cluster(s, i); + /* + * Values will be negative for writes to the FAT, which is located bef= ore + * the root directory. + */ + first_cluster =3D sector2cluster(s, sector_num); + last_cluster =3D sector2cluster(s, sector_num + nb_sectors - 1); + + for (i =3D first_cluster; i <=3D last_cluster;) { + mapping_t *mapping =3D NULL; + + if (i >=3D 0) { + mapping =3D find_mapping_for_cluster(s, i); + } + if (mapping) { if (mapping->read_only) { fprintf(stderr, "Tried to write to write-protected file %s= \n", @@ -3031,8 +3043,9 @@ DLOG(checkpoint()); } } i =3D mapping->end; - } else + } else { i++; + } } =20 /* @@ -3046,10 +3059,11 @@ DLOG(fprintf(stderr, "Write to qcow backend: %d + %= d\n", (int)sector_num, nb_sec return ret; } =20 - for (i =3D sector2cluster(s, sector_num); - i <=3D sector2cluster(s, sector_num + nb_sectors - 1); i++) - if (i >=3D 0) + for (i =3D first_cluster; i <=3D last_cluster; i++) { + if (i >=3D 0) { s->used_clusters[i] |=3D USED_ALLOCATED; + } + } =20 DLOG(checkpoint()); /* TODO: add timeout */ --=20 2.31.1