From nobody Mon Feb 9 00:42:38 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.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 1488286322106367.72579395713876; Tue, 28 Feb 2017 04:52:02 -0800 (PST) Received: from localhost ([::1]:60760 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cihG4-0000np-Tm for importer@patchew.org; Tue, 28 Feb 2017 07:52:00 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39924) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cih5Z-0007zV-Jl for qemu-devel@nongnu.org; Tue, 28 Feb 2017 07:41:13 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cih5Y-0000DK-G1 for qemu-devel@nongnu.org; Tue, 28 Feb 2017 07:41:09 -0500 Received: from mx1.redhat.com ([209.132.183.28]:54790) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cih5Y-0000Cr-7z for qemu-devel@nongnu.org; Tue, 28 Feb 2017 07:41:08 -0500 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 5A86B81239; Tue, 28 Feb 2017 12:41:08 +0000 (UTC) Received: from dgilbert-t530.redhat.com (ovpn-117-149.ams2.redhat.com [10.36.117.149]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v1SCewt4019858; Tue, 28 Feb 2017 07:41:06 -0500 From: "Dr. David Alan Gilbert (git)" To: qemu-devel@nongnu.org Date: Tue, 28 Feb 2017 12:40:33 +0000 Message-Id: <20170228124056.5074-5-dgilbert@redhat.com> In-Reply-To: <20170228124056.5074-1-dgilbert@redhat.com> References: <20170228124056.5074-1-dgilbert@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Tue, 28 Feb 2017 12:41:08 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 04/27] migration/vmstate: fix array of ptr with nullptrs 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: lvivier@redhat.com, pasic@linux.vnet.ibm.com, vsementsov@virtuozzo.com, quintela@redhat.com, ashijeetacharya@gmail.com, marcandre.lureau@redhat.com, danielhb@linux.vnet.ibm.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Halil Pasic Make VMS_ARRAY_OF_POINTER cope with null pointers. Previously the reward for trying to migrate an array with some null pointers in it was an illegal memory access, that is a swift and painless death of the process. Let's make vmstate cope with this scenario. The general approach is, when we encounter a null pointer (element), instead of following the pointer to save/load the data behind it, we save/load a placeholder. This way we can detect if we expected a null pointer at the load side but not null data was saved instead. Signed-off-by: Halil Pasic Reviewed-by: Guenther Hutzl Reviewed-by: Dr. David Alan Gilbert Message-Id: <20170222160119.52771-4-pasic@linux.vnet.ibm.com> Signed-off-by: Dr. David Alan Gilbert --- include/migration/vmstate.h | 4 ++++ migration/vmstate.c | 40 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h index 63e7b02..f2dbf84 100644 --- a/include/migration/vmstate.h +++ b/include/migration/vmstate.h @@ -253,6 +253,10 @@ extern const VMStateInfo vmstate_info_uint16; extern const VMStateInfo vmstate_info_uint32; extern const VMStateInfo vmstate_info_uint64; =20 +/** Put this in the stream when migrating a null pointer.*/ +#define VMS_NULLPTR_MARKER (0x30U) /* '0' */ +extern const VMStateInfo vmstate_info_nullptr; + extern const VMStateInfo vmstate_info_float64; extern const VMStateInfo vmstate_info_cpudouble; =20 diff --git a/migration/vmstate.c b/migration/vmstate.c index 836a7a4..78b3cd4 100644 --- a/migration/vmstate.c +++ b/migration/vmstate.c @@ -117,7 +117,11 @@ int vmstate_load_state(QEMUFile *f, const VMStateDescr= iption *vmsd, if (field->flags & VMS_ARRAY_OF_POINTER) { curr_elem =3D *(void **)curr_elem; } - if (field->flags & VMS_STRUCT) { + if (!curr_elem) { + /* if null pointer check placeholder and do not follow= */ + assert(field->flags & VMS_ARRAY_OF_POINTER); + ret =3D vmstate_info_nullptr.get(f, curr_elem, size, N= ULL); + } else if (field->flags & VMS_STRUCT) { ret =3D vmstate_load_state(f, field->vmsd, curr_elem, field->vmsd->version_id); } else { @@ -332,7 +336,11 @@ void vmstate_save_state(QEMUFile *f, const VMStateDesc= ription *vmsd, assert(curr_elem); curr_elem =3D *(void **)curr_elem; } - if (field->flags & VMS_STRUCT) { + if (!curr_elem) { + /* if null pointer write placeholder and do not follow= */ + assert(field->flags & VMS_ARRAY_OF_POINTER); + vmstate_info_nullptr.put(f, curr_elem, size, NULL, NUL= L); + } else if (field->flags & VMS_STRUCT) { vmstate_save_state(f, field->vmsd, curr_elem, vmdesc_l= oop); } else { field->info->put(f, curr_elem, size, field, vmdesc_loo= p); @@ -747,6 +755,34 @@ const VMStateInfo vmstate_info_uint64 =3D { .put =3D put_uint64, }; =20 +static int get_nullptr(QEMUFile *f, void *pv, size_t size, VMStateField *f= ield) + +{ + if (qemu_get_byte(f) =3D=3D VMS_NULLPTR_MARKER) { + return 0; + } + error_report("vmstate: get_nullptr expected VMS_NULLPTR_MARKER"); + return -EINVAL; +} + +static int put_nullptr(QEMUFile *f, void *pv, size_t size, + VMStateField *field, QJSON *vmdesc) + +{ + if (pv =3D=3D NULL) { + qemu_put_byte(f, VMS_NULLPTR_MARKER); + return 0; + } + error_report("vmstate: put_nullptr must be called with pv =3D=3D NULL"= ); + return -EINVAL; +} + +const VMStateInfo vmstate_info_nullptr =3D { + .name =3D "uint64", + .get =3D get_nullptr, + .put =3D put_nullptr, +}; + /* 64 bit unsigned int. See that the received value is the same than the o= ne in the field */ =20 --=20 2.9.3