From nobody Tue May 14 22:25:07 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 216.205.24.124 as permitted sender) client-ip=216.205.24.124; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-124.mimecast.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 216.205.24.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1608144383; cv=none; d=zohomail.com; s=zohoarc; b=T808Xnu3YLbiOmU3V3iGAjjw1dAUGelSxyzwIJ8jVQHi80KZhQVPwANYN3KwHoww240nG4GyIjDVBE2txt8HDCt6zcL8Mx+oKRPABV+9dfsNRGb5RXjzkPxjkjP2Ci8u9YWysN3+2SiX/aHfvsvp21kJtBaV/cExnlYQh6H5UxI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1608144383; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=YoOx3yhIHEIxdzrr9/9+yeT9QyP6GOLxElgOdqI6EMA=; b=Dp0XWvnsBMrtBsyGnuRqedbKTaFsf+K1YoECVLNAOHBqH4inYwfIU835CZ47dQonojvGcKPMSGa5JbuKn5H1mk/lZOLVBOYAhoCrJkV+ODucHbAdW8vzqEJZJ/fD3Wt95eUR/gu57Ydr0501noVdT9TSYUfM3RRkkrV8T9BCzqE= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 216.205.24.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [216.205.24.124]) by mx.zohomail.com with SMTPS id 1608144382977354.8295395345059; Wed, 16 Dec 2020 10:46:22 -0800 (PST) Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-533-dSsB3TaPNka9vNypWRvt8A-1; Wed, 16 Dec 2020 13:46:17 -0500 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 160A8800D53; Wed, 16 Dec 2020 18:46:11 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 5B1C060861; Wed, 16 Dec 2020 18:46:10 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id E9E504BB7B; Wed, 16 Dec 2020 18:46:09 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 0BGIjjKm020816 for ; Wed, 16 Dec 2020 13:45:45 -0500 Received: by smtp.corp.redhat.com (Postfix) id 78724629DB; Wed, 16 Dec 2020 18:45:45 +0000 (UTC) Received: from localhost.localdomain (unknown [10.40.193.177]) by smtp.corp.redhat.com (Postfix) with ESMTP id EDA7962953 for ; Wed, 16 Dec 2020 18:45:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1608144379; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=YoOx3yhIHEIxdzrr9/9+yeT9QyP6GOLxElgOdqI6EMA=; b=h05C39L3KhS6TaZWNZtgmIhkm9e/PlEDgb242ikPOXq0r2ESX1DiNClvikrEwXDEOfkU93 87FdYKuaHs/Ud/sJw3YuCkxm1RrA+wKO19zTmpIa4sH66CuxoKTH/mjB6EbonJdKZCCgC6 41cCOhGmSbVhb5zbvVMEe++4qcGDDrA= X-MC-Unique: dSsB3TaPNka9vNypWRvt8A-1 From: Michal Privoznik To: libvir-list@redhat.com Subject: [PATCH 1/2] virNetDevOpenvswitchGetVhostuserIfname: Actually use @path to lookup interface Date: Wed, 16 Dec 2020 19:45:37 +0100 Message-Id: <5e9cf60e4562aaf02d33adddab1d96bd27909c91.1608144157.git.mprivozn@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-loop: libvir-list@redhat.com X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=libvir-list-bounces@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) Content-Type: text/plain; charset="utf-8" In v6.10.0-rc1~221 I wanted to make virNetDevOpenvswitchGetVhostuserIfname() lookup interface name even for vhostuser interfaces with mode=3D'server'. F= or these, were are given a socket path which is then created by QEMU and to wh= ich OpenVSwitch connects to and creates an interface. Because of this, we don't know the name of the interface upfront (when starting QEMU) and have to use the path to query OpenVSwitch later (using ovs-vsctl). What I intended to u= se was: ovs-vsctl --no-headings --columns=3Dname find Interface options:vhost-ser= ver-path=3D$path But what my code does is: ovs-vsctl --no-headings --columns=3Dname find Interface options:vhost-ser= ver-path=3Dpath and it's all because the argument to the function is named "path" which I then enclosed in double quotes while it should have been used as a variable. Fixes: e4c29e2904197472919d050c67acfd59f0144bbc Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=3D1767013 Signed-off-by: Michal Privoznik Reviewed-by: Laine Stump --- src/util/virnetdevopenvswitch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/virnetdevopenvswitch.c b/src/util/virnetdevopenvswitc= h.c index d380b0cf22..7eabaa763d 100644 --- a/src/util/virnetdevopenvswitch.c +++ b/src/util/virnetdevopenvswitch.c @@ -494,7 +494,7 @@ virNetDevOpenvswitchGetVhostuserIfname(const char *path, if (server) { virCommandAddArgList(cmd, "--no-headings", "--columns=3Dname", "fi= nd", "Interface", NULL); - virCommandAddArgPair(cmd, "options:vhost-server-path", "path"); + virCommandAddArgPair(cmd, "options:vhost-server-path", path); } else { const char *tmpIfname =3D NULL; =20 --=20 2.26.2 From nobody Tue May 14 22:25:07 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 216.205.24.124 as permitted sender) client-ip=216.205.24.124; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-124.mimecast.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 216.205.24.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1608144390; cv=none; d=zohomail.com; s=zohoarc; b=gRyThnMwRwcAgJcocKAJOdI26fiL3tCZEPNo89UkREpb+TfhX7RECtMEj+3HxvIt4MsNTDRYFamEhHtRBr4gcQSGzDgSCZIHEon8CLJad1rz9uv/Bn3ctzSH6zaKLeVb1GG6QnYO02z5r9J/Ea1DOxJZW7H6ImyFV7D0lFzPT5s= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1608144390; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=Qv90L1dyOOR+UL6gF/tNlb50hR01mBldaYC6Rrkgtho=; b=HjZX8C7HTPkj216hR1iAgyVm2Z2S3IF2/KFG51kQGzi3CCXFttooDffoQXl2cxr+bGkLEv9grik/PMVTotjVlR9Ni7pcoa+kmDWGt+xkKibrb+ALlwPx+qkULOgeUARfVgePRv43kbUYW+uEPIB4Ode97Nf7CoxIfJFGiuEsaFU= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 216.205.24.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [216.205.24.124]) by mx.zohomail.com with SMTPS id 1608144390125974.4153386656673; Wed, 16 Dec 2020 10:46:30 -0800 (PST) Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-511-vOnEhOUJNoi9wbn3TVkcaQ-1; Wed, 16 Dec 2020 13:46:22 -0500 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 0F5679CC11; Wed, 16 Dec 2020 18:46:16 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id B5C545D9CD; Wed, 16 Dec 2020 18:46:15 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 81AB21C98; Wed, 16 Dec 2020 18:46:15 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 0BGIjkTl020826 for ; Wed, 16 Dec 2020 13:45:46 -0500 Received: by smtp.corp.redhat.com (Postfix) id 53514629DB; Wed, 16 Dec 2020 18:45:46 +0000 (UTC) Received: from localhost.localdomain (unknown [10.40.193.177]) by smtp.corp.redhat.com (Postfix) with ESMTP id C909962953 for ; Wed, 16 Dec 2020 18:45:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1608144385; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=Qv90L1dyOOR+UL6gF/tNlb50hR01mBldaYC6Rrkgtho=; b=jQtcxz68nKmIyN9rvP4e0Q69fA9Y9UnBWrv46wF2x6aikKYC5KOuR1Y2gx7aE3T7GSfJm9 UpOdCHmnMJWol0OOGospqNaJCLKB1wfLqYn8qknovVlBb0zoaD8iJxLade9Ba2vNnti3u2 ujxjgvG9DcxhjsWPlFibZYRF+a9y8Wc= X-MC-Unique: vOnEhOUJNoi9wbn3TVkcaQ-1 From: Michal Privoznik To: libvir-list@redhat.com Subject: [PATCH 2/2] virnetdevopenvswitch: Try to unescape ovs-vsctl reply in one specific case Date: Wed, 16 Dec 2020 19:45:38 +0100 Message-Id: <45f506f2eca9c6b348528010ba2a5bbdf251f14a.1608144157.git.mprivozn@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-loop: libvir-list@redhat.com X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=libvir-list-bounces@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) Content-Type: text/plain; charset="utf-8" During testing of my patch v6.10.0-rc1~221 it was found that 'ovs-vsctl get Interface $name name' or 'ovs-vsctl find Interface options:vhost-server-path=3D$path' may return a string in double quotes, e.g. "vhost-user1". Later investigation of openvswitch code showed, that early versions (like 1.3.0) have somewhat restrictive set of safe characters (isalpha() || '_' || '-' || '.'), which is then refined with increasing version. For instance, version 2.11.4 has: isalnum() || '_' || '-' || '.'. If the string that ovs-vsctl wants to output contains any other character it is escaped. You want to be looking at ovsdb_atom_to_string() which handles outputting of a single string and calls string_needs_quotes() and possibly json_serialize_string() in openvswitch code base. Since the interfaces are usually named "vhost-userN" we are facing a problem where with one version we get the name in double quotes and with another we get plain name without funny business. Because of json involved I thought, let's make ovs-vsctl output into JSON format and then use our JSON parser, but guess what - ovs-vsctl ignores --format=3Djson. But with a little help of g_strdup_printf() it can be turned into JSON. Fixes: e4c29e2904197472919d050c67acfd59f0144bbc Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=3D1767013 Signed-off-by: Michal Privoznik Reviewed-by: Laine Stump --- src/libvirt_private.syms | 1 + src/util/virnetdevopenvswitch.c | 47 +++++++++++++++++++++++++++++ src/util/virnetdevopenvswitch.h | 4 +++ tests/virnetdevopenvswitchtest.c | 52 ++++++++++++++++++++++++++++++++ 4 files changed, 104 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index c7c37d9689..583fc5800e 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2676,6 +2676,7 @@ virNetDevOpenvswitchGetVhostuserIfname; virNetDevOpenvswitchInterfaceGetMaster; virNetDevOpenvswitchInterfaceParseStats; virNetDevOpenvswitchInterfaceStats; +virNetDevOpenvswitchMaybeUnescapeReply; virNetDevOpenvswitchRemovePort; virNetDevOpenvswitchSetMigrateData; virNetDevOpenvswitchSetTimeout; diff --git a/src/util/virnetdevopenvswitch.c b/src/util/virnetdevopenvswitc= h.c index 7eabaa763d..14fa294ae1 100644 --- a/src/util/virnetdevopenvswitch.c +++ b/src/util/virnetdevopenvswitch.c @@ -460,6 +460,48 @@ virNetDevOpenvswitchInterfaceGetMaster(const char *ifn= ame, char **master) } =20 =20 +/** + * virNetDevOpenvswitchMaybeUnescapeReply: + * @reply: a string to unescape + * + * Depending on ovs-vsctl version a string might be escaped. For instance: + * -version 2.11.4 allows only is_alpha(), an underscore, a dash or a dot, + * -version 2.14.0 allows only is_alnum(), an underscore, a dash or a dot, + * any other character causes the string to be escaped. + * + * What this function does, is it checks whether @reply string consists so= lely + * from safe, not escaped characters (as defined by version 2.14.0) and if= not + * an error is reported. If @reply is a string enclosed in double quotes, = but + * otherwise safe those double quotes are removed. + * + * Returns: 0 on success, + * -1 otherwise (with error reported). + */ +int +virNetDevOpenvswitchMaybeUnescapeReply(char *reply) +{ + g_autoptr(virJSONValue) json =3D NULL; + g_autofree char *jsonStr =3D NULL; + const char *tmp =3D NULL; + size_t replyLen =3D strlen(reply); + + if (*reply !=3D '"') + return 0; + + jsonStr =3D g_strdup_printf("{\"name\": %s}", reply); + if (!(json =3D virJSONValueFromString(jsonStr))) + return -1; + + if (!(tmp =3D virJSONValueObjectGetString(json, "name"))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Malformed ovs-vsctl output")); + return -1; + } + + return virStrcpy(reply, tmp, replyLen); +} + + /** * virNetDevOpenvswitchGetVhostuserIfname: * @path: the path of the unix socket @@ -522,6 +564,11 @@ virNetDevOpenvswitchGetVhostuserIfname(const char *pat= h, return 0; } =20 + if (virNetDevOpenvswitchMaybeUnescapeReply(*ifname) < 0) { + VIR_FREE(*ifname); + return -1; + } + return 1; } =20 diff --git a/src/util/virnetdevopenvswitch.h b/src/util/virnetdevopenvswitc= h.h index 8409aa92ac..3571708582 100644 --- a/src/util/virnetdevopenvswitch.h +++ b/src/util/virnetdevopenvswitch.h @@ -60,6 +60,10 @@ int virNetDevOpenvswitchInterfaceStats(const char *ifnam= e, int virNetDevOpenvswitchInterfaceGetMaster(const char *ifname, char **mast= er) ATTRIBUTE_NONNULL(1) G_GNUC_WARN_UNUSED_RESULT; =20 +int +virNetDevOpenvswitchMaybeUnescapeReply(char *reply) + ATTRIBUTE_NONNULL(1) G_GNUC_WARN_UNUSED_RESULT; + int virNetDevOpenvswitchGetVhostuserIfname(const char *path, bool server, char **ifname) diff --git a/tests/virnetdevopenvswitchtest.c b/tests/virnetdevopenvswitcht= est.c index fd47e927ea..46172dae90 100644 --- a/tests/virnetdevopenvswitchtest.c +++ b/tests/virnetdevopenvswitchtest.c @@ -75,6 +75,42 @@ testInterfaceParseStats(const void *opaque) } =20 =20 +typedef struct _escapeData escapeData; +struct _escapeData { + const char *input; + const char *expect; +}; + + +static int +testNameEscape(const void *opaque) +{ + const escapeData *data =3D opaque; + g_autofree char *reply =3D g_strdup(data->input); + int rv; + + rv =3D virNetDevOpenvswitchMaybeUnescapeReply(reply); + + if (data->expect) { + if (rv < 0 || STRNEQ(reply, data->expect)) { + fprintf(stderr, + "Unexpected failure, expected: %s for input %s got %s\= n", + data->expect, data->input, reply); + return -1; + } + } else { + if (rv >=3D 0) { + fprintf(stderr, + "Unexpected success, input %s got %s\n", + data->input, reply); + return -1; + } + } + + return 0; +} + + static int mymain(void) { @@ -94,6 +130,22 @@ mymain(void) TEST_INTERFACE_STATS("stats1.json", 9, 12, 11, 10, 2, 8, 5, 4); TEST_INTERFACE_STATS("stats2.json", 12406, 173, 0, 0, 0, 0, 0, 0); =20 +#define TEST_NAME_ESCAPE(str, fail) \ + do { \ + const escapeData data =3D {str, fail};\ + if (virTestRun("Name escape " str, testNameEscape, &data) < 0) \ + ret =3D -1; \ + } while (0) + + TEST_NAME_ESCAPE("", ""); + TEST_NAME_ESCAPE("\"\"", ""); + TEST_NAME_ESCAPE("vhost-user1", "vhost-user1"); + TEST_NAME_ESCAPE("\"vhost-user1\"", "vhost-user1"); + TEST_NAME_ESCAPE("\"vhost_user-name.to.escape1", NULL); + TEST_NAME_ESCAPE("\"vhost_user-name.to\\\"escape1\"", "vhost_user-name= .to\"escape1"); + TEST_NAME_ESCAPE("\"vhost\"user1\"", NULL); + TEST_NAME_ESCAPE("\"\\\\", NULL); + return ret =3D=3D 0 ? EXIT_SUCCESS : EXIT_FAILURE; } =20 --=20 2.26.2