From nobody Tue Feb 10 12:43:10 2026 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 1522891484223788.7369549679572; Wed, 4 Apr 2018 18:24:44 -0700 (PDT) Received: from localhost ([::1]:45494 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1f3tdm-0006CI-54 for importer@patchew.org; Wed, 04 Apr 2018 21:24:38 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55826) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1f3tcD-0004zI-Ux for qemu-devel@nongnu.org; Wed, 04 Apr 2018 21:23:03 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1f3tcC-0002zw-LK for qemu-devel@nongnu.org; Wed, 04 Apr 2018 21:23:01 -0400 Received: from mail-qt0-x243.google.com ([2607:f8b0:400d:c0d::243]:44639) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1f3tcC-0002zl-GA for qemu-devel@nongnu.org; Wed, 04 Apr 2018 21:23:00 -0400 Received: by mail-qt0-x243.google.com with SMTP id j26so25269803qtl.11 for ; Wed, 04 Apr 2018 18:23:00 -0700 (PDT) Received: from x1.lan ([138.117.48.212]) by smtp.gmail.com with ESMTPSA id l124sm4940094qkc.1.2018.04.04.18.22.57 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 04 Apr 2018 18:22:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=AusDXdiIRKmEbhZcR3EVhf+Gn0KkCAlcFPyLNAgdi80=; b=DuaNdFH0QMCEguI3dQ6VhtH6hpfqAi3722R9aIv0372ly3nLGsM1TqAGTy+98ucbED 4N3sCvCN7IAgWmHQtROd1OHPlYGpKTFl/4fNANV3qqsuCYY8ndifvds2nYMBvBl4wKtF fb1f6UZ51J4pe95LCz3PBTQ3fC0BTzfxamz1FGvrIgZK0u5df+dVuF67jzusOeHgwn2k SXBOZuFfjs1yZC8T9tggQCZUcf4mhovw+/Wq5cgA/XL2o6NOq81XlPpJMcU7AfLpLUCv Ymj8A1sh1e7NstG+bt70dAkVrVs+S8Vadffkk27TZ/57YQ4dJSSX6D4t6Kiha4nneETq pkCw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=AusDXdiIRKmEbhZcR3EVhf+Gn0KkCAlcFPyLNAgdi80=; b=s5I0N8UGcGxkR+4473ZPxOg961qej9f1GVisaTLrAZF7wGE2rwyege0tm8Mph80mGc 51G4YSPT0Gtgm8zy+jZT92MyFD247Yng6jW9uh41zDv6W9tqjKuHqXGh9N/vDu4Sncio pxDGXfe7wQGN64AxgOPe3PoRIylz0yo6vd+dOmAQYK/eOAfyeQqKuWR+3Ea7Q2cMg27i s/tD5n13Jtsl7mCi6gvt0DAykciygl8mcX2LfgfjxJeQTkZLDxCDpwS67eRCfLOn6DIy fV3HnFNffozPWNQQYEuzIqzrdYWLn3dU2tz7HT7ZqX1WT5HYgQicmXtm3sbNpABbExx2 PdLQ== X-Gm-Message-State: ALQs6tCHozcRDMdVbJ5c31974B9RRmeJrukm2zduD4piyaXk5yQ1fk5K I44PwMbrgUM9Q6ickpdnxm0= X-Google-Smtp-Source: AIpwx48ECWN1QRPebanFDvpnJNCACbAi9T5iuez3dono8hu5qIS/gp8ER9CS89/rAA7hL29YMeP0cw== X-Received: by 10.237.61.162 with SMTP id i31mr29553917qtf.34.1522891379913; Wed, 04 Apr 2018 18:22:59 -0700 (PDT) From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= To: Paolo Bonzini , Alexey Kardashevskiy , KONRAD Frederic Date: Wed, 4 Apr 2018 22:22:39 -0300 Message-Id: <20180405012241.25714-3-f4bug@amsat.org> X-Mailer: git-send-email 2.16.3 In-Reply-To: <20180405012241.25714-1-f4bug@amsat.org> References: <20180405012241.25714-1-f4bug@amsat.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400d:c0d::243 Subject: [Qemu-devel] [NOTFORMERGE PATCH v2 2/4] memory: Fix access_with_adjusted_size() when size < access_size_min 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?Philippe=20Mathieu-Daud=C3=A9?= , qemu-devel@nongnu.org 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 ASan reported: shift exponent 4294967280 is too large for 64-bit type 'long unsigned i= nt' ... runtime error: shift exponent -16 is negative This can occurs when MemoryRegionOps .valid.min_access_size < .impl.min_acc= ess_size, for example if a guest uses a 16-bit operand to access a 32-bit register. The current code is limited to right shifting. Use a signed shift, to allow shifting left when the value is negative. Reported-by: AddressSanitizer Signed-off-by: Philippe Mathieu-Daud=C3=A9 --- memory.c | 74 +++++++++++++++++++++++++++++++++++++++++++++---------------= ---- 1 file changed, 52 insertions(+), 22 deletions(-) diff --git a/memory.c b/memory.c index 51d27b7b26..e77f9e4036 100644 --- a/memory.c +++ b/memory.c @@ -404,7 +404,7 @@ static MemTxResult memory_region_oldmmio_read_accessor(= MemoryRegion *mr, hwaddr addr, uint64_t *value, unsigned size, - unsigned shift, + signed shift, uint64_t mask, MemTxAttrs attrs) { @@ -422,7 +422,11 @@ static MemTxResult memory_region_oldmmio_read_accessor= (MemoryRegion *mr, hwaddr abs_addr =3D memory_region_to_absolute_addr(mr, addr); trace_memory_region_ops_read(get_cpu_index(), mr, abs_addr, tmp, s= ize); } - *value |=3D (tmp & mask) << shift; + if (likely(shift >=3D 0)) { + *value |=3D (tmp & mask) << shift; + } else { + *value |=3D (tmp >> -shift) & mask; + } return MEMTX_OK; } =20 @@ -430,7 +434,7 @@ static MemTxResult memory_region_read_accessor(MemoryR= egion *mr, hwaddr addr, uint64_t *value, unsigned size, - unsigned shift, + signed shift, uint64_t mask, MemTxAttrs attrs) { @@ -448,7 +452,11 @@ static MemTxResult memory_region_read_accessor(Memory= Region *mr, hwaddr abs_addr =3D memory_region_to_absolute_addr(mr, addr); trace_memory_region_ops_read(get_cpu_index(), mr, abs_addr, tmp, s= ize); } - *value |=3D (tmp & mask) << shift; + if (likely(shift >=3D 0)) { + *value |=3D (tmp & mask) << shift; + } else { + *value |=3D (tmp >> -shift) & mask; + } return MEMTX_OK; } =20 @@ -456,7 +464,7 @@ static MemTxResult memory_region_read_with_attrs_access= or(MemoryRegion *mr, hwaddr addr, uint64_t *value, unsigned size, - unsigned shift, + signed shift, uint64_t mask, MemTxAttrs attrs) { @@ -475,7 +483,11 @@ static MemTxResult memory_region_read_with_attrs_acces= sor(MemoryRegion *mr, hwaddr abs_addr =3D memory_region_to_absolute_addr(mr, addr); trace_memory_region_ops_read(get_cpu_index(), mr, abs_addr, tmp, s= ize); } - *value |=3D (tmp & mask) << shift; + if (likely(shift >=3D 0)) { + *value |=3D (tmp & mask) << shift; + } else { + *value |=3D (tmp >> -shift) & mask; + } return r; } =20 @@ -483,13 +495,17 @@ static MemTxResult memory_region_oldmmio_write_access= or(MemoryRegion *mr, hwaddr addr, uint64_t *value, unsigned size, - unsigned shift, + signed shift, uint64_t mask, MemTxAttrs attrs) { uint64_t tmp; =20 - tmp =3D (*value >> shift) & mask; + if (likely(shift >=3D 0)) { + tmp =3D (*value >> shift) & mask; + } else { + tmp =3D (*value & mask) << -shift; + } if (mr->subpage) { trace_memory_region_subpage_write(get_cpu_index(), mr, addr, tmp, = size); } else if (mr =3D=3D &io_mem_notdirty) { @@ -509,13 +525,17 @@ static MemTxResult memory_region_write_accessor(Memor= yRegion *mr, hwaddr addr, uint64_t *value, unsigned size, - unsigned shift, + signed shift, uint64_t mask, MemTxAttrs attrs) { uint64_t tmp; =20 - tmp =3D (*value >> shift) & mask; + if (likely(shift >=3D 0)) { + tmp =3D (*value >> shift) & mask; + } else { + tmp =3D (*value & mask) << -shift; + } if (mr->subpage) { trace_memory_region_subpage_write(get_cpu_index(), mr, addr, tmp, = size); } else if (mr =3D=3D &io_mem_notdirty) { @@ -535,13 +555,17 @@ static MemTxResult memory_region_write_with_attrs_acc= essor(MemoryRegion *mr, hwaddr addr, uint64_t *value, unsigned size, - unsigned shift, + signed shift, uint64_t mask, MemTxAttrs attr= s) { uint64_t tmp; =20 - tmp =3D (*value >> shift) & mask; + if (likely(shift >=3D 0)) { + tmp =3D (*value >> shift) & mask; + } else { + tmp =3D (*value & mask) << -shift; + } if (mr->subpage) { trace_memory_region_subpage_write(get_cpu_index(), mr, addr, tmp, = size); } else if (mr =3D=3D &io_mem_notdirty) { @@ -566,7 +590,7 @@ static MemTxResult access_with_adjusted_size(hwaddr add= r, hwaddr addr, uint64_t *value, unsigned size, - unsigned shift, + signed shift, uint64_t mask, MemTxAttrs attrs), MemoryRegion *mr, @@ -574,7 +598,9 @@ static MemTxResult access_with_adjusted_size(hwaddr add= r, { uint64_t access_mask; unsigned access_size; - unsigned i; + hwaddr access_addr; + unsigned offset; + signed shift; MemTxResult r =3D MEMTX_OK; =20 if (!access_size_min) { @@ -586,16 +612,20 @@ static MemTxResult access_with_adjusted_size(hwaddr a= ddr, =20 /* FIXME: support unaligned access? */ access_size =3D MAX(MIN(size, access_size_max), access_size_min); - access_mask =3D -1ULL >> (64 - access_size * 8); - if (memory_region_big_endian(mr)) { - for (i =3D 0; i < size; i +=3D access_size) { - r |=3D access_fn(mr, addr + i, value, access_size, - (size - access_size - i) * 8, access_mask, attrs); + access_mask =3D -1ULL >> (64 - size * 8); + access_addr =3D addr & ~(access_size - 1); + if (likely(size >=3D access_size)) { + offset =3D addr & (access_size - 1); + shift =3D access_size - size - offset; + if (!memory_region_big_endian(mr)) { + shift =3D -shift; } + r =3D access_fn(mr, access_addr, value, access_size, + shift * 8, access_mask, attrs); } else { - for (i =3D 0; i < size; i +=3D access_size) { - r |=3D access_fn(mr, addr + i, value, access_size, i * 8, - access_mask, attrs); + for (offset =3D 0; offset < size; offset +=3D access_size) { + r |=3D access_fn(mr, access_addr + offset, value, access_size, + offset * 8, access_mask, attrs); } } return r; --=20 2.16.3