Received: by 10.223.176.5 with SMTP id f5csp879010wra; Fri, 2 Feb 2018 07:34:16 -0800 (PST) X-Google-Smtp-Source: AH8x224ObtTvuC7MGJoj+P+6GTx2LO4cPOu45h4nFdOlP4Yfk/RUg+8KzBXQfv3uLkJZzZeHVKmF X-Received: by 10.98.141.199 with SMTP id p68mr39135999pfk.25.1517585656451; Fri, 02 Feb 2018 07:34:16 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1517585656; cv=none; d=google.com; s=arc-20160816; b=xbHxrLLeJwRT+QTY70ku1ey6ngdJepG8zyERC8E0+mWbFgU96Gyb2eXiUDB70eXwFz JgqoDYe0xYGHE7RqAjAG7TMLlRtswsNzAKdLW/uKDouY/8qGwcD180sdZb6osvr1EGU0 1rH3WPqr0MGRBXb7lB1JBW83kivPoQ2t/fTPm0zDz+MGxfLzPvbXayvwGkfjemitof6p LKXdLyIvOj/SOYQvBe4Ay9puJ6LsWQEMfwmml2kwUJY41A61ceBNysgxvqAZVAsqXZ1b 59h/VGjXGbAq5lKio3Tk0mUKeDQjDg4wLC67JFw7AY6beDgQhA3KS2ifz5T6b2GCQ1uw PG6w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from :arc-authentication-results; bh=lHZ82l4ZP2rdLzX5Ue8/Vgm7tRuKOMlDvXLn0oORRDM=; b=xaF64bAfsHyDBD/SxzUUx4ylvzcS1i5NV/BmlIG9r4jwC1GVNXfWD5ARcyIqdHoRNn 18pFkCVpWTx3+6VVTw5uNoJroP44jBU+Q3mkHMXYGprof0g0mIj8irE8uR8gKLQq+Coq 1d6lSf8JAUsMn8mR/WHOm37UpOpb7lPRUZNepi6pnqWHEE9ZxnfNc+MVDSmH4V8wLYWg KMA1iEHT8shrSLpH89gZ0nzuOdU9saTtaxSqDEVkfFSwszYm6oHNbPIhr2N8qnRQneWn 1IdpFbh7jrsMUUvOe5bGsQfYjmR186DoRJWNDdN1Q6w3S/BmRz6g26fX1tb3/9AcJewb /68A== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id x18si1613220pgv.124.2018.02.02.07.34.01; Fri, 02 Feb 2018 07:34:16 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752000AbeBBPdQ (ORCPT + 99 others); Fri, 2 Feb 2018 10:33:16 -0500 Received: from mout.kundenserver.de ([212.227.126.133]:64790 "EHLO mout.kundenserver.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751470AbeBBPdK (ORCPT ); Fri, 2 Feb 2018 10:33:10 -0500 Received: from wuerfel.lan ([95.208.111.237]) by mrelayeu.kundenserver.de (mreue002 [212.227.15.129]) with ESMTPA (Nemesis) id 0LmzQD-1fDgtt1gzt-00hRHz; Fri, 02 Feb 2018 16:32:52 +0100 From: Arnd Bergmann To: Boris Ostrovsky , Juergen Gross Cc: Nicolas Pitre , Andi Kleen , Dan Carpenter , Jan Beulich , Arnd Bergmann , xen-devel@lists.xenproject.org, linux-kernel@vger.kernel.org Subject: [PATCH] xen: hypercall: fix out-of-bounds memcpy Date: Fri, 2 Feb 2018 16:32:31 +0100 Message-Id: <20180202153240.1190361-1-arnd@arndb.de> X-Mailer: git-send-email 2.9.0 X-Provags-ID: V03:K0:XPC/aBNTJ6HoMhdxlkHQWX43Zp9Rk9lzA+Jp2LMeYW+JRKf6MmD fAYYoWi17colqZjaUtEaHtgZcerT0JGLkcVcPRAbXwcQcvGjyeEU46PTPali23tMAw7c4PX Z9fvKHIPjJPaIeBJLnfNraTyXh/z8A84RAsaYm9TeFoJgs3xeRhMdrR1HbTSrB2zyXlupke DMFyWvWwKJIQ3f18FLlhQ== X-UI-Out-Filterresults: notjunk:1;V01:K0:FivGfNiSDGg=:8zZE5M376lioGU98EZRiH8 rx0G4FGCSpae26RX4DoT+6GiZoMYf0b5qrscYKrrTri+radqR4V9u1ra5nhHhhBcwdwddkydf Xm0WIc0wAAD3aUGpMt/EBSJjP32g6iXz3eUYYhz96RnsTTFUZTbXgGUagK9Icf+/7yT1kXCh3 YKds26rfCfQXYm3SucosOMB7dCny1cEJNX5kvpOnGxEeFzxz+OOancqfRQACtm63lCVY1rZdX 9sKcg4q2d0qWBC5934pII9uh7WrugpE6Cmvr1uFKPUANxo+4xmerRDSpvmGAMFOMJk0cRob+w LSlgi/iJvAwmJ4PP63eIcvrFLpfG9AtWjWZKnW9WLW+KdKYccCk9vTUJnyzwBV0e65l7mId3A J+LBPkkgLdLq88HYXKvEjsGixlFETBMJeGbwSKO3LzzkB+DOHxmgbaB4rZugjJzvl+FvVhQzQ mk79HgxYV6l90KqwKQKiNytznRvu4Dn9tHPbZ+/Smea8vE9egcnhOdYP5KBj5woFqy/r2UpfS 8B0z0W2wn8THNPNbkt2cKvRFen2gwyPnB8hmtRXXna30E9wTeic7EWQwx/6Xnl/DixC3JKwEI 8SwDmRaagHbESLuOyuggWd9FKwPqMpTqLciYRXcsAcWfchX4z7H2ctFATiifWWgP3+v8uerDE eU1imj42+jfgjQRsWiJ4aZWd0BkvEGG/ruDW/toFMtrFebY9GBIaXpzDqmaWAvXhES7HZxkqe Sdlz2HqxH8PgAUI9g30K1ASVQIwPl2uhw14XsA== Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The legacy hypercall handlers were originally added with a comment explaining that "copying the argument structures in HYPERVISOR_event_channel_op() and HYPERVISOR_physdev_op() into the local variable is sufficiently safe" and only made sure to not write past the end of the argument structure, the checks in linux/string.h disagree with that, when link-time optimizations are used: In function 'memcpy', inlined from 'pirq_query_unmask' at drivers/xen/fallback.c:53:2, inlined from '__startup_pirq' at drivers/xen/events/events_base.c:529:2, inlined from 'restore_pirqs' at drivers/xen/events/events_base.c:1439:3, inlined from 'xen_irq_resume' at drivers/xen/events/events_base.c:1581:2: include/linux/string.h:350:3: error: call to '__read_overflow2' declared with attribute error: detected read beyond size of object passed as 2nd parameter __read_overflow2(); ^ make[3]: *** [ccLujFNx.ltrans15.ltrans.o] Error 1 make[3]: Target 'all' not remade because of errors. lto-wrapper: fatal error: make returned 2 exit status compilation terminated. ld: error: lto-wrapper failed This changes the functions so that each argument is accessed with exactly the correct length based on the command code. Fixes: cf47a83fb06e ("xen/hypercall: fix hypercall fallback code for very old hypervisors") Signed-off-by: Arnd Bergmann --- drivers/xen/fallback.c | 94 ++++++++++++++++++++++++++++---------------------- 1 file changed, 53 insertions(+), 41 deletions(-) diff --git a/drivers/xen/fallback.c b/drivers/xen/fallback.c index b04fb64c5a91..eded8dd821ad 100644 --- a/drivers/xen/fallback.c +++ b/drivers/xen/fallback.c @@ -7,75 +7,87 @@ int xen_event_channel_op_compat(int cmd, void *arg) { - struct evtchn_op op; + struct evtchn_op op = { .cmd = cmd, }; + size_t len; int rc; - op.cmd = cmd; - memcpy(&op.u, arg, sizeof(op.u)); - rc = _hypercall1(int, event_channel_op_compat, &op); - switch (cmd) { + case EVTCHNOP_bind_interdomain: + len = sizeof(struct evtchn_bind_interdomain); + break; + case EVTCHNOP_bind_virq: + len = sizeof(struct evtchn_bind_virq); + break; + case EVTCHNOP_bind_pirq: + len = sizeof(struct evtchn_bind_pirq); + break; case EVTCHNOP_close: + len = sizeof(struct evtchn_close); + break; case EVTCHNOP_send: + len = sizeof(struct evtchn_send); + break; + case EVTCHNOP_alloc_unbound: + len = sizeof(struct evtchn_alloc_unbound); + break; + case EVTCHNOP_bind_ipi: + len = sizeof(struct evtchn_bind_ipi); + break; + case EVTCHNOP_status: + len = sizeof(struct evtchn_status); + break; case EVTCHNOP_bind_vcpu: + len = sizeof(struct evtchn_bind_vcpu); + break; case EVTCHNOP_unmask: - /* no output */ + len = sizeof(struct evtchn_unmask); break; - -#define COPY_BACK(eop) \ - case EVTCHNOP_##eop: \ - memcpy(arg, &op.u.eop, sizeof(op.u.eop)); \ - break - - COPY_BACK(bind_interdomain); - COPY_BACK(bind_virq); - COPY_BACK(bind_pirq); - COPY_BACK(status); - COPY_BACK(alloc_unbound); - COPY_BACK(bind_ipi); -#undef COPY_BACK - default: - WARN_ON(rc != -ENOSYS); - break; + return -ENOSYS; } + memcpy(&op.u, arg, len); + rc = _hypercall1(int, event_channel_op_compat, &op); + memcpy(arg, &op.u, len); + return rc; } EXPORT_SYMBOL_GPL(xen_event_channel_op_compat); int xen_physdev_op_compat(int cmd, void *arg) { - struct physdev_op op; + struct physdev_op op = { .cmd = cmd, }; + size_t len; int rc; - op.cmd = cmd; - memcpy(&op.u, arg, sizeof(op.u)); - rc = _hypercall1(int, physdev_op_compat, &op); - switch (cmd) { case PHYSDEVOP_IRQ_UNMASK_NOTIFY: + len = 0; + break; + case PHYSDEVOP_irq_status_query: + len = sizeof(struct physdev_irq_status_query); + break; case PHYSDEVOP_set_iopl: + len = sizeof(struct physdev_set_iopl); + break; case PHYSDEVOP_set_iobitmap: + len = sizeof(struct physdev_set_iobitmap); + break; + case PHYSDEVOP_apic_read: case PHYSDEVOP_apic_write: - /* no output */ + len = sizeof(struct physdev_apic); break; - -#define COPY_BACK(pop, fld) \ - case PHYSDEVOP_##pop: \ - memcpy(arg, &op.u.fld, sizeof(op.u.fld)); \ - break - - COPY_BACK(irq_status_query, irq_status_query); - COPY_BACK(apic_read, apic_op); - COPY_BACK(ASSIGN_VECTOR, irq_op); -#undef COPY_BACK - - default: - WARN_ON(rc != -ENOSYS); + case PHYSDEVOP_ASSIGN_VECTOR: + len = sizeof(struct physdev_irq); break; + default: + return -ENOSYS; } + memcpy(&op.u, arg, len); + rc = _hypercall1(int, physdev_op_compat, &op); + memcpy(arg, &op.u, len); + return rc; } EXPORT_SYMBOL_GPL(xen_physdev_op_compat); -- 2.9.0