Received: by 2002:a25:6193:0:0:0:0:0 with SMTP id v141csp3829056ybb; Mon, 23 Mar 2020 08:26:08 -0700 (PDT) X-Google-Smtp-Source: ADFU+vsymG5zPaIgChaAewPs5NRs/vo0Tb+5kso95jI79/xf59GlX/kTFgG79glH+NRkXzm1/pts X-Received: by 2002:a9d:6b98:: with SMTP id b24mr2848619otq.242.1584977168043; Mon, 23 Mar 2020 08:26:08 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1584977168; cv=none; d=google.com; s=arc-20160816; b=ViLDibRsVh4JPGEB7ftUnfdEUWya4c7XxSkk8uYaKrr7byEb58ovXz6nHlWSzlxeT/ VgQ8J1aPA8V6Couu4zuAbht6/iK4qqaGKz++PncNwphl37CTt2ha8FXO3wBN8rqRNLMc r/Ki7lPDnS3h015XwJE7Jzx3NKU1A7Ve+Natvm/xur0ErhFmxE1avkzeCEF4f9u5h/bi RYmwbqhA/t8RIUsJWNl5EsTZ4IvsusJ39n16bCq73ROk6KWJd2K1GDZkAamSTtwb77sV iK2hjQUuOwwNrGNXb843UhLbcAPiN7LQDsJT//Tq5duJpY2Hh5a8P3clcrOgpAaxl9Ax bgfQ== 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 :references:in-reply-to:message-id:date:subject:cc:to:from; bh=Rv6QVaqRMt9Wu3NzegS1SsKkzIcLUKODVrio9vDOB2Y=; b=U7FzxPz5JhcBe8b17d6RPOSP5uSqVR5FVRGRphaFG0ucywknxjqyF5sFtmiwLW85JO kcReZWIvuASCmoHw17Dj1XrIRzcTGisi7AS16Uby0CnsvnW9m38zHVjiykpEYC/rZbOZ Rl34TMr6GNL5irT4w6GfxnupsJylNQcS+lK+/uDdRM9Er0SSUoVomkTaP3wzrU7+sZOO YZnGeqft+c3iUOn84SDLYdUYK7Z2wOrsVMrE6bZ/2GBWHpoqRKo8C2vI22J57FHqHiLX BIvRtjh09wo3XA5sJMx5EjlrTVKp5cNjwUMnFxgtjJk6Zwjf3TPwKxoKs7zWSNPVoEI/ NH6A== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-wireless-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-wireless-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 r21si4193597otp.320.2020.03.23.08.25.56; Mon, 23 Mar 2020 08:26:08 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-wireless-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-wireless-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-wireless-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727302AbgCWPZu (ORCPT + 99 others); Mon, 23 Mar 2020 11:25:50 -0400 Received: from s3.sipsolutions.net ([144.76.43.62]:49292 "EHLO sipsolutions.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727228AbgCWPZt (ORCPT ); Mon, 23 Mar 2020 11:25:49 -0400 Received: by sipsolutions.net with esmtpsa (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.93) (envelope-from ) id 1jGOxX-002WVN-RR; Mon, 23 Mar 2020 16:25:47 +0100 From: Johannes Berg To: linux-wireless@vger.kernel.org Cc: me@bobcopeland.com, Johannes Berg Subject: [PATCH 3/7] wmediumd: fix use-after-free Date: Mon, 23 Mar 2020 16:25:38 +0100 Message-Id: <20200323162245.3c73cce10e60.I075866ca98e0f5633baef99efdcb8276962c198b@changeid> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200323152542.68696-1-johannes@sipsolutions.net> References: <20200323152542.68696-1-johannes@sipsolutions.net> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Johannes Berg When a client (vhost-user) disconnects when there's a frame from it on the queue, we have a use-after-free on actually sending it. Avoid this by clearing all the stations->client pointers that go away, and removing frames where the source goes away. Also, while at it, remove the unused frame->dest pointer. Fixes: 5b4cebfbf6d9 ("wmediumd: add vhost-user support") --- wmediumd/wmediumd.c | 35 ++++++++++++++++++++++++++++++++--- wmediumd/wmediumd.h | 2 +- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/wmediumd/wmediumd.c b/wmediumd/wmediumd.c index e7374d9b9639..39797e58f277 100644 --- a/wmediumd/wmediumd.c +++ b/wmediumd/wmediumd.c @@ -368,7 +368,6 @@ static void queue_frame(struct wmediumd *ctx, struct station *station, target += send_time; frame->duration = send_time; - frame->dest = deststa ? deststa->client : NULL; frame->src = station->client; frame->job.start = target; frame->job.callback = wmediumd_deliver_frame; @@ -399,6 +398,37 @@ static void wmediumd_send_to_client(struct wmediumd *ctx, } } +static void wmediumd_remove_client(struct wmediumd *ctx, struct client *client) +{ + struct frame *frame, *tmp; + struct wqueue *queue; + struct station *station; + int ac; + + list_for_each_entry(station, &ctx->stations, list) { + if (station->client == client) + station->client = NULL; + } + + list_for_each_entry(station, &ctx->stations, list) { + for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { + queue = &station->queues[ac]; + list_for_each_entry_safe(frame, tmp, &queue->frames, + list) { + if (frame->src == client) { + list_del(&frame->list); + usfstl_sched_del_job(&frame->job); + free(frame); + } + } + } + } + + if (!list_empty(&client->list)) + list_del(&client->list); + free(client); +} + /* * Report transmit status to the kernel. */ @@ -719,8 +749,7 @@ static void wmediumd_vu_disconnected(struct usfstl_vhost_user_dev *dev) struct client *client = dev->data; dev->data = NULL; - list_del(&client->list); - free(client); + wmediumd_remove_client(dev->server->data, client); } static const struct usfstl_vhost_user_ops wmediumd_vu_ops = { diff --git a/wmediumd/wmediumd.h b/wmediumd/wmediumd.h index d4ce3a1df15d..06b356516a15 100644 --- a/wmediumd/wmediumd.h +++ b/wmediumd/wmediumd.h @@ -210,7 +210,7 @@ struct hwsim_tx_rate { struct frame { struct list_head list; /* frame queue list */ struct usfstl_job job; - struct client *src, *dest; + struct client *src; bool acked; u64 cookie; u32 freq; -- 2.25.1