Received: by 2002:a25:ab43:0:0:0:0:0 with SMTP id u61csp310289ybi; Wed, 29 May 2019 22:00:57 -0700 (PDT) X-Google-Smtp-Source: APXvYqzIkgSW/4jZFbyrNxe5YBkz16s0ADnqMhpmaq6dPRkbm1s9zYw+VIbTgAy54CCmvI7kcVsg X-Received: by 2002:a17:902:868a:: with SMTP id g10mr1963909plo.205.1559192457423; Wed, 29 May 2019 22:00:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1559192457; cv=none; d=google.com; s=arc-20160816; b=nwXPBqHppjHogXYLFpeuz7s8E111//Mb2M5ackeB6vG23/IR9aqzZrGYaBSZDAwjvl zinMhCpuKrkgcSegrrvGQ398wVzgRyDylrjGqduDB99l8g5G1RTh1o2JUEKNkKRt2YG9 GCr4eXdTS5iVJnJRepAR0EmQlO56+y3wcmXV0LQs4hbuQf15wWqNkaDRLUOov+5DP1PS lavlNFwtDLI2j2+ciT38nZBgfpfryTIi/jJwDmF2upA01gJe2wmfTglTTaSuH28f7Dtt r312Y+UirVpZ4kvsqfRV0BHnWtmDdMdQmqxSv1uMqiphzKvQ4idbB69GaUbMFVE8NK92 REXA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=hbYqUAbZnpBYK+xvXs0KUv75nIKu46Z9yDS1W9PTdrA=; b=jfjZnK9WKs3qQbjWl4Lhh/5nMEB76YBm94isnaMma93BsRyi3JRM5xwl0jwEN3FYpa enDCHyy2TXr0wZBKs/f80IKqrWnwi7xRJLk9OI2qfMij83xkUeQK/cigf67hz5MhN6wz Eed+1iJInub0ikbjeBumWxtn5w30RhqiZgAHiBBH0kv+ZQSkD6N6n0dNIAKDtpayEkNZ 7d+ZsOaiW8GNMUwjOPZeA6eRu6K9a7WRL/yfs49X7OQbnO+7ol/gWnOar/erD5mVCj/+ CL3FTcCf/XG0BHWJmWRE7jSNgn9TRUfgadsvqxm6ktr6GrcusyK3LgnF7hJC8GWDUmwK QM2g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b="q/m9O0eh"; 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 p24si2038373plr.269.2019.05.29.22.00.41; Wed, 29 May 2019 22:00:57 -0700 (PDT) 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; dkim=pass header.i=@kernel.org header.s=default header.b="q/m9O0eh"; 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 S2388866AbfE3E6r (ORCPT + 99 others); Thu, 30 May 2019 00:58:47 -0400 Received: from mail.kernel.org ([198.145.29.99]:45250 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727767AbfE3DJs (ORCPT ); Wed, 29 May 2019 23:09:48 -0400 Received: from localhost (ip67-88-213-2.z213-88-67.customer.algx.net [67.88.213.2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 6D02E24490; Thu, 30 May 2019 03:09:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1559185787; bh=2tai9SaB6+Ar6w+cqsaRceMO4vIi6bU87Bu09RCKnFY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=q/m9O0ehO2r+mXMoyULQ401E3QUN6I+3SluOr5EsSJb2lpQ/n4NVGSKb8kp9M+z6G IdrbYGL04VUlkL9tVokFDG8UKlte0uoYYvBr78dG58jlmle7Fk1JHvebI3zFPTzmCl ZjS/aEDRtZuWMsFAmT6jeoXNYJwwBbZfrbeT/ync= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, William Tu , =?UTF-8?q?Bj=C3=B6rn=20T=C3=B6pel?= , Alexei Starovoitov , Sasha Levin Subject: [PATCH 5.1 056/405] libbpf: fix invalid munmap call Date: Wed, 29 May 2019 20:00:54 -0700 Message-Id: <20190530030543.695689262@linuxfoundation.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190530030540.291644921@linuxfoundation.org> References: <20190530030540.291644921@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org [ Upstream commit 0e6741f092979535d159d5a851f12c88bfb7cb9a ] When unmapping the AF_XDP memory regions used for the rings, an invalid address was passed to the munmap() calls. Instead of passing the beginning of the memory region, the descriptor region was passed to munmap. When the userspace application tried to tear down an AF_XDP socket, the operation failed and the application would still have a reference to socket it wished to get rid of. Reported-by: William Tu Fixes: 1cad07884239 ("libbpf: add support for using AF_XDP sockets") Signed-off-by: Björn Töpel Tested-by: William Tu Signed-off-by: Alexei Starovoitov Signed-off-by: Sasha Levin --- tools/lib/bpf/xsk.c | 77 +++++++++++++++++++++++---------------------- 1 file changed, 40 insertions(+), 37 deletions(-) diff --git a/tools/lib/bpf/xsk.c b/tools/lib/bpf/xsk.c index 8d0078b65486f..af5f310ecca1c 100644 --- a/tools/lib/bpf/xsk.c +++ b/tools/lib/bpf/xsk.c @@ -248,8 +248,7 @@ int xsk_umem__create(struct xsk_umem **umem_ptr, void *umem_area, __u64 size, return 0; out_mmap: - munmap(umem->fill, - off.fr.desc + umem->config.fill_size * sizeof(__u64)); + munmap(map, off.fr.desc + umem->config.fill_size * sizeof(__u64)); out_socket: close(umem->fd); out_umem_alloc: @@ -523,11 +522,11 @@ int xsk_socket__create(struct xsk_socket **xsk_ptr, const char *ifname, struct xsk_ring_cons *rx, struct xsk_ring_prod *tx, const struct xsk_socket_config *usr_config) { + void *rx_map = NULL, *tx_map = NULL; struct sockaddr_xdp sxdp = {}; struct xdp_mmap_offsets off; struct xsk_socket *xsk; socklen_t optlen; - void *map; int err; if (!umem || !xsk_ptr || !rx || !tx) @@ -593,40 +592,40 @@ int xsk_socket__create(struct xsk_socket **xsk_ptr, const char *ifname, } if (rx) { - map = xsk_mmap(NULL, off.rx.desc + - xsk->config.rx_size * sizeof(struct xdp_desc), - PROT_READ | PROT_WRITE, - MAP_SHARED | MAP_POPULATE, - xsk->fd, XDP_PGOFF_RX_RING); - if (map == MAP_FAILED) { + rx_map = xsk_mmap(NULL, off.rx.desc + + xsk->config.rx_size * sizeof(struct xdp_desc), + PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_POPULATE, + xsk->fd, XDP_PGOFF_RX_RING); + if (rx_map == MAP_FAILED) { err = -errno; goto out_socket; } rx->mask = xsk->config.rx_size - 1; rx->size = xsk->config.rx_size; - rx->producer = map + off.rx.producer; - rx->consumer = map + off.rx.consumer; - rx->ring = map + off.rx.desc; + rx->producer = rx_map + off.rx.producer; + rx->consumer = rx_map + off.rx.consumer; + rx->ring = rx_map + off.rx.desc; } xsk->rx = rx; if (tx) { - map = xsk_mmap(NULL, off.tx.desc + - xsk->config.tx_size * sizeof(struct xdp_desc), - PROT_READ | PROT_WRITE, - MAP_SHARED | MAP_POPULATE, - xsk->fd, XDP_PGOFF_TX_RING); - if (map == MAP_FAILED) { + tx_map = xsk_mmap(NULL, off.tx.desc + + xsk->config.tx_size * sizeof(struct xdp_desc), + PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_POPULATE, + xsk->fd, XDP_PGOFF_TX_RING); + if (tx_map == MAP_FAILED) { err = -errno; goto out_mmap_rx; } tx->mask = xsk->config.tx_size - 1; tx->size = xsk->config.tx_size; - tx->producer = map + off.tx.producer; - tx->consumer = map + off.tx.consumer; - tx->ring = map + off.tx.desc; + tx->producer = tx_map + off.tx.producer; + tx->consumer = tx_map + off.tx.consumer; + tx->ring = tx_map + off.tx.desc; tx->cached_cons = xsk->config.tx_size; } xsk->tx = tx; @@ -653,13 +652,11 @@ int xsk_socket__create(struct xsk_socket **xsk_ptr, const char *ifname, out_mmap_tx: if (tx) - munmap(xsk->tx, - off.tx.desc + + munmap(tx_map, off.tx.desc + xsk->config.tx_size * sizeof(struct xdp_desc)); out_mmap_rx: if (rx) - munmap(xsk->rx, - off.rx.desc + + munmap(rx_map, off.rx.desc + xsk->config.rx_size * sizeof(struct xdp_desc)); out_socket: if (--umem->refcount) @@ -684,10 +681,12 @@ int xsk_umem__delete(struct xsk_umem *umem) optlen = sizeof(off); err = getsockopt(umem->fd, SOL_XDP, XDP_MMAP_OFFSETS, &off, &optlen); if (!err) { - munmap(umem->fill->ring, - off.fr.desc + umem->config.fill_size * sizeof(__u64)); - munmap(umem->comp->ring, - off.cr.desc + umem->config.comp_size * sizeof(__u64)); + (void)munmap(umem->fill->ring - off.fr.desc, + off.fr.desc + + umem->config.fill_size * sizeof(__u64)); + (void)munmap(umem->comp->ring - off.cr.desc, + off.cr.desc + + umem->config.comp_size * sizeof(__u64)); } close(umem->fd); @@ -698,6 +697,7 @@ int xsk_umem__delete(struct xsk_umem *umem) void xsk_socket__delete(struct xsk_socket *xsk) { + size_t desc_sz = sizeof(struct xdp_desc); struct xdp_mmap_offsets off; socklen_t optlen; int err; @@ -710,14 +710,17 @@ void xsk_socket__delete(struct xsk_socket *xsk) optlen = sizeof(off); err = getsockopt(xsk->fd, SOL_XDP, XDP_MMAP_OFFSETS, &off, &optlen); if (!err) { - if (xsk->rx) - munmap(xsk->rx->ring, - off.rx.desc + - xsk->config.rx_size * sizeof(struct xdp_desc)); - if (xsk->tx) - munmap(xsk->tx->ring, - off.tx.desc + - xsk->config.tx_size * sizeof(struct xdp_desc)); + if (xsk->rx) { + (void)munmap(xsk->rx->ring - off.rx.desc, + off.rx.desc + + xsk->config.rx_size * desc_sz); + } + if (xsk->tx) { + (void)munmap(xsk->tx->ring - off.tx.desc, + off.tx.desc + + xsk->config.tx_size * desc_sz); + } + } xsk->umem->refcount--; -- 2.20.1