From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
stable@vger.kernel.org, Dmitrii Tcvetkov <demfloro@demfloro.ru>,
Douglas Anderson <dianders@chromium.org>,
Paolo Valente <paolo.valente@linaro.org>,
Jens Axboe <axboe@kernel.dk>, Yu Kuai <yukuai3@huawei.com>
Subject: [PATCH 4.19 06/38] block, bfq: fix use after free in bfq_bfqq_expire
Date: Mon, 27 Dec 2021 16:30:43 +0100 [thread overview]
Message-ID: <20211227151319.590190184@linuxfoundation.org> (raw)
In-Reply-To: <20211227151319.379265346@linuxfoundation.org>
From: Paolo Valente <paolo.valente@linaro.org>
commit eed47d19d9362bdd958e4ab56af480b9dbf6b2b6 upstream.
The function bfq_bfqq_expire() invokes the function
__bfq_bfqq_expire(), and the latter may free the in-service bfq-queue.
If this happens, then no other instruction of bfq_bfqq_expire() must
be executed, or a use-after-free will occur.
Basing on the assumption that __bfq_bfqq_expire() invokes
bfq_put_queue() on the in-service bfq-queue exactly once, the queue is
assumed to be freed if its refcounter is equal to one right before
invoking __bfq_bfqq_expire().
But, since commit 9dee8b3b057e ("block, bfq: fix queue removal from
weights tree") this assumption is false. __bfq_bfqq_expire() may also
invoke bfq_weights_tree_remove() and, since commit 9dee8b3b057e
("block, bfq: fix queue removal from weights tree"), also
the latter function may invoke bfq_put_queue(). So __bfq_bfqq_expire()
may invoke bfq_put_queue() twice, and this is the actual case where
the in-service queue may happen to be freed.
To address this issue, this commit moves the check on the refcounter
of the queue right around the last bfq_put_queue() that may be invoked
on the queue.
Fixes: 9dee8b3b057e ("block, bfq: fix queue removal from weights tree")
Reported-by: Dmitrii Tcvetkov <demfloro@demfloro.ru>
Reported-by: Douglas Anderson <dianders@chromium.org>
Tested-by: Dmitrii Tcvetkov <demfloro@demfloro.ru>
Tested-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: Paolo Valente <paolo.valente@linaro.org>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Yu Kuai <yukuai3@huawei.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
block/bfq-iosched.c | 15 +++++++--------
block/bfq-iosched.h | 2 +-
block/bfq-wf2q.c | 17 +++++++++++++++--
3 files changed, 23 insertions(+), 11 deletions(-)
--- a/block/bfq-iosched.c
+++ b/block/bfq-iosched.c
@@ -2816,7 +2816,7 @@ static void bfq_dispatch_remove(struct r
bfq_remove_request(q, rq);
}
-static void __bfq_bfqq_expire(struct bfq_data *bfqd, struct bfq_queue *bfqq)
+static bool __bfq_bfqq_expire(struct bfq_data *bfqd, struct bfq_queue *bfqq)
{
/*
* If this bfqq is shared between multiple processes, check
@@ -2849,9 +2849,11 @@ static void __bfq_bfqq_expire(struct bfq
/*
* All in-service entities must have been properly deactivated
* or requeued before executing the next function, which
- * resets all in-service entites as no more in service.
+ * resets all in-service entities as no more in service. This
+ * may cause bfqq to be freed. If this happens, the next
+ * function returns true.
*/
- __bfq_bfqd_reset_in_service(bfqd);
+ return __bfq_bfqd_reset_in_service(bfqd);
}
/**
@@ -3256,7 +3258,6 @@ void bfq_bfqq_expire(struct bfq_data *bf
bool slow;
unsigned long delta = 0;
struct bfq_entity *entity = &bfqq->entity;
- int ref;
/*
* Check whether the process is slow (see bfq_bfqq_is_slow).
@@ -3325,10 +3326,8 @@ void bfq_bfqq_expire(struct bfq_data *bf
* reason.
*/
__bfq_bfqq_recalc_budget(bfqd, bfqq, reason);
- ref = bfqq->ref;
- __bfq_bfqq_expire(bfqd, bfqq);
-
- if (ref == 1) /* bfqq is gone, no more actions on it */
+ if (__bfq_bfqq_expire(bfqd, bfqq))
+ /* bfqq is gone, no more actions on it */
return;
bfqq->injected_service = 0;
--- a/block/bfq-iosched.h
+++ b/block/bfq-iosched.h
@@ -993,7 +993,7 @@ bool __bfq_deactivate_entity(struct bfq_
bool ins_into_idle_tree);
bool next_queue_may_preempt(struct bfq_data *bfqd);
struct bfq_queue *bfq_get_next_queue(struct bfq_data *bfqd);
-void __bfq_bfqd_reset_in_service(struct bfq_data *bfqd);
+bool __bfq_bfqd_reset_in_service(struct bfq_data *bfqd);
void bfq_deactivate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq,
bool ins_into_idle_tree, bool expiration);
void bfq_activate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq);
--- a/block/bfq-wf2q.c
+++ b/block/bfq-wf2q.c
@@ -1600,7 +1600,8 @@ struct bfq_queue *bfq_get_next_queue(str
return bfqq;
}
-void __bfq_bfqd_reset_in_service(struct bfq_data *bfqd)
+/* returns true if the in-service queue gets freed */
+bool __bfq_bfqd_reset_in_service(struct bfq_data *bfqd)
{
struct bfq_queue *in_serv_bfqq = bfqd->in_service_queue;
struct bfq_entity *in_serv_entity = &in_serv_bfqq->entity;
@@ -1624,8 +1625,20 @@ void __bfq_bfqd_reset_in_service(struct
* service tree either, then release the service reference to
* the queue it represents (taken with bfq_get_entity).
*/
- if (!in_serv_entity->on_st)
+ if (!in_serv_entity->on_st) {
+ /*
+ * If no process is referencing in_serv_bfqq any
+ * longer, then the service reference may be the only
+ * reference to the queue. If this is the case, then
+ * bfqq gets freed here.
+ */
+ int ref = in_serv_bfqq->ref;
bfq_put_queue(in_serv_bfqq);
+ if (ref == 1)
+ return true;
+ }
+
+ return false;
}
void bfq_deactivate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq,
next prev parent reply other threads:[~2021-12-27 15:33 UTC|newest]
Thread overview: 47+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-12-27 15:30 [PATCH 4.19 00/38] 4.19.223-rc1 review Greg Kroah-Hartman
2021-12-27 15:30 ` [PATCH 4.19 01/38] net: usb: lan78xx: add Allied Telesis AT29M2-AF Greg Kroah-Hartman
2021-12-27 15:30 ` [PATCH 4.19 02/38] block, bfq: improve asymmetric scenarios detection Greg Kroah-Hartman
2021-12-27 15:30 ` [PATCH 4.19 03/38] block, bfq: fix " Greg Kroah-Hartman
2021-12-27 15:30 ` [PATCH 4.19 04/38] block, bfq: fix decrement of num_active_groups Greg Kroah-Hartman
2021-12-27 15:30 ` [PATCH 4.19 05/38] block, bfq: fix queue removal from weights tree Greg Kroah-Hartman
2021-12-27 15:30 ` Greg Kroah-Hartman [this message]
2021-12-27 15:30 ` [PATCH 4.19 07/38] HID: holtek: fix mouse probing Greg Kroah-Hartman
2021-12-27 15:30 ` [PATCH 4.19 08/38] arm64: dts: allwinner: orangepi-zero-plus: fix PHY mode Greg Kroah-Hartman
2021-12-27 15:30 ` [PATCH 4.19 09/38] spi: change clk_disable_unprepare to clk_unprepare Greg Kroah-Hartman
2021-12-27 15:30 ` [PATCH 4.19 10/38] IB/qib: Fix memory leak in qib_user_sdma_queue_pkts() Greg Kroah-Hartman
2021-12-27 15:30 ` [PATCH 4.19 11/38] netfilter: fix regression in looped (broad|multi)casts MAC handling Greg Kroah-Hartman
2021-12-27 15:30 ` [PATCH 4.19 12/38] qlcnic: potential dereference null pointer of rx_queue->page_ring Greg Kroah-Hartman
2021-12-27 15:30 ` [PATCH 4.19 13/38] net: accept UFOv6 packages in virtio_net_hdr_to_skb Greg Kroah-Hartman
2021-12-27 15:30 ` [PATCH 4.19 14/38] net: skip virtio_net_hdr_set_proto if protocol already set Greg Kroah-Hartman
2021-12-27 15:30 ` [PATCH 4.19 15/38] ipmi: Fix UAF when uninstall ipmi_si and ipmi_msghandler module Greg Kroah-Hartman
2021-12-27 15:30 ` [PATCH 4.19 16/38] bonding: fix ad_actor_system option setting to default Greg Kroah-Hartman
2021-12-27 15:30 ` [PATCH 4.19 17/38] fjes: Check for error irq Greg Kroah-Hartman
2021-12-27 15:30 ` [PATCH 4.19 18/38] drivers: net: smc911x: " Greg Kroah-Hartman
2021-12-27 15:30 ` [PATCH 4.19 19/38] sfc: falcon: Check null pointer of rx_queue->page_ring Greg Kroah-Hartman
2021-12-29 11:21 ` Pavel Machek
2021-12-27 15:30 ` [PATCH 4.19 20/38] hwmon: (lm90) Fix usage of CONFIG2 register in detect function Greg Kroah-Hartman
2021-12-27 15:30 ` [PATCH 4.19 21/38] ALSA: jack: Check the return value of kstrdup() Greg Kroah-Hartman
2021-12-27 15:30 ` [PATCH 4.19 22/38] ALSA: drivers: opl3: Fix incorrect use of vp->state Greg Kroah-Hartman
2021-12-27 15:31 ` [PATCH 4.19 23/38] Input: atmel_mxt_ts - fix double free in mxt_read_info_block Greg Kroah-Hartman
2021-12-27 15:31 ` [PATCH 4.19 24/38] ipmi: bail out if init_srcu_struct fails Greg Kroah-Hartman
2021-12-27 15:31 ` [PATCH 4.19 25/38] ipmi: fix initialization when workqueue allocation fails Greg Kroah-Hartman
2021-12-27 15:31 ` [PATCH 4.19 26/38] parisc: Correct completer in lws start Greg Kroah-Hartman
2021-12-27 15:31 ` [PATCH 4.19 27/38] x86/pkey: Fix undefined behaviour with PKRU_WD_BIT Greg Kroah-Hartman
2021-12-27 15:31 ` [PATCH 4.19 28/38] pinctrl: stm32: consider the GPIO offset to expose all the GPIO lines Greg Kroah-Hartman
2021-12-27 15:31 ` [PATCH 4.19 29/38] ARM: 9169/1: entry: fix Thumb2 bug in iWMMXt exception handling Greg Kroah-Hartman
2021-12-27 15:31 ` [PATCH 4.19 30/38] f2fs: fix to do sanity check on last xattr entry in __f2fs_setxattr() Greg Kroah-Hartman
2021-12-30 10:52 ` Pavel Machek
2021-12-27 15:31 ` [PATCH 4.19 31/38] usb: gadget: u_ether: fix race in setting MAC address in setup phase Greg Kroah-Hartman
2021-12-27 15:31 ` [PATCH 4.19 32/38] KVM: VMX: Fix stale docs for kvm-intel.emulate_invalid_guest_state Greg Kroah-Hartman
2021-12-27 15:31 ` [PATCH 4.19 33/38] Input: i8042 - enable deferred probe quirk for ASUS UM325UA Greg Kroah-Hartman
2021-12-27 15:31 ` [PATCH 4.19 34/38] hwmon: (lm90) Do not report busy status bit as alarm Greg Kroah-Hartman
2021-12-27 15:31 ` [PATCH 4.19 35/38] ax25: NPD bug when detaching AX25 device Greg Kroah-Hartman
2021-12-27 15:31 ` [PATCH 4.19 36/38] hamradio: defer ax25 kfree after unregister_netdev Greg Kroah-Hartman
2021-12-27 15:31 ` [PATCH 4.19 37/38] hamradio: improve the incomplete fix to avoid NPD Greg Kroah-Hartman
2021-12-27 15:31 ` [PATCH 4.19 38/38] phonet/pep: refuse to enable an unbound pipe Greg Kroah-Hartman
2021-12-27 21:16 ` [PATCH 4.19 00/38] 4.19.223-rc1 review Pavel Machek
2021-12-28 0:55 ` Samuel Zou
2021-12-28 11:19 ` Naresh Kamboju
2021-12-28 13:18 ` Sudip Mukherjee
2021-12-28 17:06 ` Guenter Roeck
2021-12-28 21:29 ` Shuah Khan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20211227151319.590190184@linuxfoundation.org \
--to=gregkh@linuxfoundation.org \
--cc=axboe@kernel.dk \
--cc=demfloro@demfloro.ru \
--cc=dianders@chromium.org \
--cc=linux-kernel@vger.kernel.org \
--cc=paolo.valente@linaro.org \
--cc=stable@vger.kernel.org \
--cc=yukuai3@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.