Received: by 2002:ac0:a581:0:0:0:0:0 with SMTP id m1-v6csp3680521imm; Mon, 25 Jun 2018 02:50:33 -0700 (PDT) X-Google-Smtp-Source: ADUXVKLCyYNj94b/5HMYKAOxvRizUIdtm3dwtSYz8Bs8lYFBckXdIyyhHbuxsnMfqMu+KEbZL4Gl X-Received: by 2002:a65:6031:: with SMTP id p17-v6mr9203978pgu.140.1529920233458; Mon, 25 Jun 2018 02:50:33 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1529920233; cv=none; d=google.com; s=arc-20160816; b=Jrs3KJhm4zPU4V7Iai7CItsZrPbpJk4Cu/kEdkVJVW/gydP8lH9lax4WrnlbMNGHgI e+Uwvpx7tZ0kpSEPlCXbB2f65uKLF5YsJlU+EYYVXcu0+z7Z1uNkvo1SmV454SdceXqj 16jGkjA235Ca3LQvTQqKmvhs+bkZB+u8G9pYQL3uBNbRVFtihWiVBZduc8/BfTr/AHLT v5xZFe2AYAf9MdwCTNPLjKiOk2sUFl5BUdCpgpYIOtqQejtmNj/+onWuBRA15mcEYNC9 0+37epIoekWLknIX3fOqR/tefZhLe3Wi6DSbmS+LV0kg5lJta3OphKZdKqaUSclVgFeT Lkzg== 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=Vu8ZHErtfKovci6cUlf2zTI1mDoW3GdMZVESpj+UYZE=; b=LFn5tVd+VgT5tBoZXiYmUUJ71RQlPc2fpGi6sIGYWxYOZhhqQgUjTGYxFm5gQhyDUW wV3HrAwtPWdQ1P5ydGSWlGjnBS47GppmhbPzBLrJsAqzJMZeitm6yfkvTmFMB5UYSlL0 zVQ+gxdiqyb5gt378XRFh2ShUVFJBq0NsqqdzIBuU3HFuCRkhpr5g646u+c6DrgeF52u A8HfJ3pzpvhy5AgtaakP//sRpxQN/weodEE6Ysagbq/qeN3fFAR5YLuHslHNoZRFJH+I YSN/2eZY88bIobmoUWikEDgOhZXY7iRBBMuss9ZkLdpoCHUuwiqjKhKmHw9N6b3PKwmz 0Brg== 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 91-v6si13194196ply.296.2018.06.25.02.50.18; Mon, 25 Jun 2018 02:50:33 -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; 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 S1755034AbeFYJth (ORCPT + 99 others); Mon, 25 Jun 2018 05:49:37 -0400 Received: from mail09.linbit.com ([212.69.161.110]:60767 "EHLO mail09.linbit.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754786AbeFYJtg (ORCPT ); Mon, 25 Jun 2018 05:49:36 -0400 X-Greylist: delayed 581 seconds by postgrey-1.27 at vger.kernel.org; Mon, 25 Jun 2018 05:49:35 EDT Received: from soda.linbit (212-186-191-219.static.upcbusiness.at [212.186.191.219]) by mail09.linbit.com (LINBIT Mail Daemon) with ESMTP id 0A4031012A9A; Mon, 25 Jun 2018 11:39:52 +0200 (CEST) From: Lars Ellenberg To: Jens Axboe Cc: drbd-dev@lists.linbit.com, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, Philipp Reisner , Lars Ellenberg Subject: [PATCH] drbd: fix access after free Date: Mon, 25 Jun 2018 11:39:52 +0200 Message-Id: <20180625093952.20220-1-lars.ellenberg@linbit.com> X-Mailer: git-send-email 2.17.1 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org We have struct drbd_requests { ... struct bio *private_bio; ... } to hold a bio clone for local submission. On local IO completion, we put that bio, and in case we want to use the result later, we overload that member to hold the ERR_PTR() of the completion result, Which, before v4.3, used to be the passed in "int error", so we could first bio_put(), then assign. v4.3-rc1~100^2~21 4246a0b63bd8 block: add a bi_error field to struct bio changed that: bio_put(req->private_bio); - req->private_bio = ERR_PTR(error); + req->private_bio = ERR_PTR(bio->bi_error); Which introduces an access after free, because it was non obvious that req->private_bio == bio. Impact of that was mostly unnoticable, because we only use that value in a multiple-failure case, and even then map any "unexpected" error code to EIO, so worst case we could potentially mask a more specific error with EIO in a multiple failure case. Unless the pointed to memory region was unmapped, as is the case with CONFIG_DEBUG_PAGEALLOC, in which case this results in BUG: unable to handle kernel paging request v4.13-rc1~70^2~75 4e4cbee93d56 block: switch bios to blk_status_t changes it further to bio_put(req->private_bio); req->private_bio = ERR_PTR(blk_status_to_errno(bio->bi_status)); And blk_status_to_errno() now contains a WARN_ON_ONCE() for unexpected values, which catches this "sometimes", if the memory has been reused quickly enough for other things. Should also go into stable since 4.3, with the trivial change around 4.13. Cc: stable@vger.kernel.org Fixes: 4246a0b63bd8 block: add a bi_error field to struct bio Reported-by: Sarah Newman Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_worker.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c index 1476cb3439f4..5e793dd7adfb 100644 --- a/drivers/block/drbd/drbd_worker.c +++ b/drivers/block/drbd/drbd_worker.c @@ -282,8 +282,8 @@ void drbd_request_endio(struct bio *bio) what = COMPLETED_OK; } - bio_put(req->private_bio); req->private_bio = ERR_PTR(blk_status_to_errno(bio->bi_status)); + bio_put(bio); /* not req_mod(), we need irqsave here! */ spin_lock_irqsave(&device->resource->req_lock, flags); -- 2.17.1