Message ID | 20230202110543.27548-1-zyytlz.wz@163.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:eb09:0:0:0:0:0 with SMTP id s9csp172958wrn; Thu, 2 Feb 2023 03:07:30 -0800 (PST) X-Google-Smtp-Source: AK7set8+OwFC6zcJ84+DlUQ/AX8+ee7zkIR2lvKoygvJxt2+nF5JSyOECpwfixdTYhMZt+jNqHMH X-Received: by 2002:a05:6402:448c:b0:4a0:e31a:434 with SMTP id er12-20020a056402448c00b004a0e31a0434mr5689825edb.27.1675336049901; Thu, 02 Feb 2023 03:07:29 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1675336049; cv=none; d=google.com; s=arc-20160816; b=Xxi2NRdPoI/Blisk9xTqGyKx1K40+jN3AfjGNAyYhGt+fvxpUkrZQuBCceU01KqnYG XQ9dVU05r7qp+cCNjY9dhWgIRvXDrlMFqQ5bocIJXexmMwnDuk32YfH0ug9FQiWvX+XR 3xZRZ3lqidS06XR6NQcG0jr4pNar8nx4GM+P6JO1WJ04NkSxFGR2RyJljkwD1gqMbUnT /UiJ1h0zy48zJKRDM89GqibCEFypjfJyqGjVbt1lpDYy9h+DKBwK1tH+u9hvf2B5BgjM 2MaSGB871rW4oyc0fTjdMZvdZQWui8fMX2CRSEGz1S/M+d+c71cHF/WEiW4NyB+f6jtP KO4w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from:dkim-signature; bh=5BWjLd1/jaEBccjludNTfPy3Z/B05OXtOx+r4AztbjY=; b=yZ/RFWBc1qHRm+2eNRHcx3cgWuiogqBERpPe4hYB/xIpHXcVrNSofyAhFTnF5KUlQT Nm7+v04SMhgzCMwhJ55/pIq1gZFGfblwyr4jgbv/lOkEdaNxPfb61a84Kb5SyM8V3Dst /P92LYBMFKHNBx/IpW/y4Vi/7iEbDyxwq4O0TiHiBdpAogtD8v7AbskdRg03LP8EKnIi dVIXWBpSoNNHNR04xrAQ9Y3y/xTgA7KtC8eOZMRRXm4UfbEDOxNerr4JzeYC4B2jFmOd Yol/LhYQWb4Cbtu/YBenlbn+LKntT+MHumrNWpP6C2Rh86f41ie12hUe3p66oCbfzcIF G3yg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@163.com header.s=s110527 header.b=qdBYC9xR; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=163.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id u24-20020a170906109800b00877a8ff6a11si24096755eju.902.2023.02.02.03.07.06; Thu, 02 Feb 2023 03:07:29 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@163.com header.s=s110527 header.b=qdBYC9xR; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=163.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229801AbjBBLHC (ORCPT <rfc822;il.mystafa@gmail.com> + 99 others); Thu, 2 Feb 2023 06:07:02 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36210 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229991AbjBBLGw (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Thu, 2 Feb 2023 06:06:52 -0500 Received: from m12.mail.163.com (m12.mail.163.com [220.181.12.214]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 4980E1206E; Thu, 2 Feb 2023 03:06:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com; s=s110527; h=From:Subject:Date:Message-Id:MIME-Version; bh=5BWjL d1/jaEBccjludNTfPy3Z/B05OXtOx+r4AztbjY=; b=qdBYC9xRAg87mLEPd00qD 9hXuyHGWQuuURF/BRRb3NHeWzBNMq2xVOGlGTjd8D4KfEFXYtq5xPoj5OT6BuCd2 brWwhlKen3/gOhDp4qPfSursxccvyOmpm8Yyfj5L8EglB2yEJ3xCThMrDQWpIfl0 9UMTDOmFJOn9hVs2+wO4Zk= Received: from leanderwang-LC2.localdomain (unknown [111.206.145.21]) by zwqz-smtp-mta-g4-0 (Coremail) with SMTP id _____wDX0+8ImdtjYQxBCg--.48198S2; Thu, 02 Feb 2023 19:05:44 +0800 (CST) From: Zheng Wang <zyytlz.wz@163.com> To: colyli@suse.de Cc: hackerzheng666@gmail.com, kent.overstreet@gmail.com, linux-bcache@vger.kernel.org, linux-kernel@vger.kernel.org, security@kernel.org, alex000young@gmail.com, Zheng Wang <zyytlz.wz@163.com> Subject: [PATCH] bcache: Fix a NULL or wild pointer dereference in btree_split Date: Thu, 2 Feb 2023 19:05:43 +0800 Message-Id: <20230202110543.27548-1-zyytlz.wz@163.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-CM-TRANSID: _____wDX0+8ImdtjYQxBCg--.48198S2 X-Coremail-Antispam: 1Uf129KBjvJXoW7tF1UXF1xZw15CFWDJFW3GFg_yoW8Wr4xpF 4xWFy3trW8Xr4jk3y5X3W0vF9Yv3WaqFWYk3s5ua48ZasxZr1fCFy0k34jvryUurs7Xa17 tr1Fvw15XF1UtaUanT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x0ziaLv_UUUUU= X-Originating-IP: [111.206.145.21] X-CM-SenderInfo: h2113zf2oz6qqrwthudrp/xtbBzg4KU2I0XNTkLgAAsN X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1756717174046447391?= X-GMAIL-MSGID: =?utf-8?q?1756717174046447391?= |
Series |
bcache: Fix a NULL or wild pointer dereference in btree_split
|
|
Commit Message
Zheng Wang
Feb. 2, 2023, 11:05 a.m. UTC
In btree_split, btree_node_alloc_replacement() is assigned to
n1 and return error code or NULL on failure. n1->c->cache is
passed to block_bytes. So there is a dereference of it
without checks, which may lead to wild pointer dereference or
NULL pointer dereference depending on n1. The initial code only
judge the error code but igore the NULL pointer.
So does n2 and n3.
Fix this bug by adding IS_ERR_OR_NULL check of n1, n2 and n3.
Note that, as a bug found by static analysis, it can be a false
positive or hard to trigger.
Fixes: cafe56359144 ("bcache: A block layer cache")
Signed-off-by: Zheng Wang <zyytlz.wz@163.com>
---
drivers/md/bcache/btree.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
Comments
On Thu, Feb 02, 2023 at 07:05:43PM +0800, Zheng Wang wrote: > In btree_split, btree_node_alloc_replacement() is assigned to > n1 and return error code or NULL on failure. n1->c->cache is > passed to block_bytes. So there is a dereference of it > without checks, which may lead to wild pointer dereference or > NULL pointer dereference depending on n1. The initial code only > judge the error code but igore the NULL pointer. > So does n2 and n3. > > Fix this bug by adding IS_ERR_OR_NULL check of n1, n2 and n3. > > Note that, as a bug found by static analysis, it can be a false > positive or hard to trigger. > > Fixes: cafe56359144 ("bcache: A block layer cache") > Signed-off-by: Zheng Wang <zyytlz.wz@163.com> > --- > drivers/md/bcache/btree.c | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) Note, there is no need to cc: security@k.o on any of these patches that you send to public mailing lists, as the development and discussion of them should happen there instead. thanks, greg k-h
> 2023年2月2日 19:05,Zheng Wang <zyytlz.wz@163.com> 写道: > > In btree_split, btree_node_alloc_replacement() is assigned to > n1 and return error code or NULL on failure. n1->c->cache is > passed to block_bytes. So there is a dereference of it > without checks, which may lead to wild pointer dereference or > NULL pointer dereference depending on n1. The initial code only > judge the error code but igore the NULL pointer. > So does n2 and n3. > > Fix this bug by adding IS_ERR_OR_NULL check of n1, n2 and n3. > > Note that, as a bug found by static analysis, it can be a false > positive or hard to trigger. > > Fixes: cafe56359144 ("bcache: A block layer cache") > Signed-off-by: Zheng Wang <zyytlz.wz@163.com> Hmm, there should be something to be fixed, but not the non-exist NULL dereference. If you look inside btree_node_alloc_replacement(), you may find __bch_btree_node_alloc() which does the real work indeed. And yes, I would suggest you to improve a bit inside __bch_btree_node_alloc(). 1088 struct btree *__bch_btree_node_alloc(struct cache_set *c, struct btree_op *op, [snipped] 1093 struct btree *b = ERR_PTR(-EAGAIN); 1094 1095 mutex_lock(&c->bucket_lock); 1096 retry: 1097 if (__bch_bucket_alloc_set(c, RESERVE_BTREE, &k.key, wait)) 1098 goto err; [snipped] 1102 1103 b = mca_alloc(c, op, &k.key, level); 1104 if (IS_ERR(b)) 1105 goto err_free; 1106 1107 if (!b) { 1108 cache_bug(c, 1109 "Tried to allocate bucket that was in btree cache"); 1110 goto retry; 1111 } 1112 From the above code, at line 1097 if __bch_bucket_alloc_set() returns non-zero value, the code will jump to label err: and returns ERR_PTR(-EAGAIN). But if the code fails at line 1103 and b is set to NULL, at line 1110 the code will jump back to label retry: and calls __bch_bucket_alloc_set() again. If the second time __bch_bucket_alloc_set() returns non-zero value and the code jumps to label err:, a NULL pointer other than ERR_PTR(-EAGAIN) will be returned. This inconsistent return value on same location at line 1097 seems incorrect, where ERR_PTR(-EAGAIN) should be returned IMHO. Therefore I feel that “b = ERR_PTR(-EAGAIN)” should be moved to the location after label retry:, then btree_node_alloc_replacement() will only return error code, and no NULL pointer returned. After this change, all following IS_ERR_OR_NULL() checks to btree_node_alloc_replacement() are unnecessary and IS_ERR() just enough, because no NULL will be returned. This is a nice catch. I’d like to have it to be fixed. I do appreciate if you want to compose two patches for the fix. Otherwise I can handle it myself. Thanks. Coly Li > --- > drivers/md/bcache/btree.c | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > > diff --git a/drivers/md/bcache/btree.c b/drivers/md/bcache/btree.c > index 147c493a989a..d5ed382fc43c 100644 > --- a/drivers/md/bcache/btree.c > +++ b/drivers/md/bcache/btree.c > @@ -2206,7 +2206,7 @@ static int btree_split(struct btree *b, struct btree_op *op, > } > > n1 = btree_node_alloc_replacement(b, op); > - if (IS_ERR(n1)) > + if (IS_ERR_OR_NULL(n1)) > goto err; > > split = set_blocks(btree_bset_first(n1), > @@ -2218,12 +2218,12 @@ static int btree_split(struct btree *b, struct btree_op *op, > trace_bcache_btree_node_split(b, btree_bset_first(n1)->keys); > > n2 = bch_btree_node_alloc(b->c, op, b->level, b->parent); > - if (IS_ERR(n2)) > + if (IS_ERR_OR_NULL(n2)) > goto err_free1; > > if (!b->parent) { > n3 = bch_btree_node_alloc(b->c, op, b->level + 1, NULL); > - if (IS_ERR(n3)) > + if (IS_ERR_OR_NULL(n3)) > goto err_free2; > } > > -- > 2.25.1 >
Greg KH <greg@kroah.com> 于2023年2月2日周四 20:08写道: > > Note, there is no need to cc: security@k.o on any of these patches that > you send to public mailing lists, as the development and discussion of > them should happen there instead. > Hi Greg, Thanks for your kind reminding. I'll remember that in the future. Best regards, Zheng Wang
Coly Li <colyli@suse.de> 于2023年2月2日周四 20:22写道: > Hmm, there should be something to be fixed, but not the non-exist NULL dereference. > > If you look inside btree_node_alloc_replacement(), you may find __bch_btree_node_alloc() which does the real work indeed. And yes, I would suggest you to improve a bit inside __bch_btree_node_alloc(). > > 1088 struct btree *__bch_btree_node_alloc(struct cache_set *c, struct btree_op *op, > [snipped] > 1093 struct btree *b = ERR_PTR(-EAGAIN); > 1094 > 1095 mutex_lock(&c->bucket_lock); > 1096 retry: > 1097 if (__bch_bucket_alloc_set(c, RESERVE_BTREE, &k.key, wait)) > 1098 goto err; > [snipped] > 1102 > 1103 b = mca_alloc(c, op, &k.key, level); > 1104 if (IS_ERR(b)) > 1105 goto err_free; > 1106 > 1107 if (!b) { > 1108 cache_bug(c, > 1109 "Tried to allocate bucket that was in btree cache"); > 1110 goto retry; > 1111 } > 1112 > > From the above code, at line 1097 if __bch_bucket_alloc_set() returns non-zero value, the code will jump to label err: and returns ERR_PTR(-EAGAIN). But if the code fails at line 1103 and b is set to NULL, at line 1110 the code will jump back to label retry: and calls __bch_bucket_alloc_set() again. If the second time __bch_bucket_alloc_set() returns non-zero value and the code jumps to label err:, a NULL pointer other than ERR_PTR(-EAGAIN) will be returned. This inconsistent return value on same location at line 1097 seems incorrect, where ERR_PTR(-EAGAIN) should be returned IMHO. > > Therefore I feel that “b = ERR_PTR(-EAGAIN)” should be moved to the location after label retry:, then btree_node_alloc_replacement() will only return error code, and no NULL pointer returned. > > After this change, all following IS_ERR_OR_NULL() checks to btree_node_alloc_replacement() are unnecessary and IS_ERR() just enough, because no NULL will be returned. > > This is a nice catch. I’d like to have it to be fixed. I do appreciate if you want to compose two patches for the fix. Otherwise I can handle it myself. > Hi Coly, Thanks for your reply and detailed explaination! As you explain, I found __bch_btree_node_alloc may return NULL in some situation. So I add some more check in upper code. Your suggestion is more constructive. It'll make the function more clear for other developer. I'd like to help with the patch. And you have kindly pointed the right way to fix. May I merge fix it in one patch with the commit msg "refactor __bch_btree_node_alloc to avoid poential NULL dereference"? Because I think if __bch_btree_node_alloc returns NULL to bch_btree_node_alloc, the function btree_node_alloc_replacement will strill return NULL to n1 in btree_split. I think the possibility is low, if it's not proper, please feel free to let me know. Best regards, Zheng Wang
> 2023年2月2日 22:11,Zheng Hacker <hackerzheng666@gmail.com> 写道: > > Coly Li <colyli@suse.de> 于2023年2月2日周四 20:22写道: > >> Hmm, there should be something to be fixed, but not the non-exist NULL dereference. >> >> If you look inside btree_node_alloc_replacement(), you may find __bch_btree_node_alloc() which does the real work indeed. And yes, I would suggest you to improve a bit inside __bch_btree_node_alloc(). >> >> 1088 struct btree *__bch_btree_node_alloc(struct cache_set *c, struct btree_op *op, >> [snipped] >> 1093 struct btree *b = ERR_PTR(-EAGAIN); >> 1094 >> 1095 mutex_lock(&c->bucket_lock); >> 1096 retry: >> 1097 if (__bch_bucket_alloc_set(c, RESERVE_BTREE, &k.key, wait)) >> 1098 goto err; >> [snipped] >> 1102 >> 1103 b = mca_alloc(c, op, &k.key, level); >> 1104 if (IS_ERR(b)) >> 1105 goto err_free; >> 1106 >> 1107 if (!b) { >> 1108 cache_bug(c, >> 1109 "Tried to allocate bucket that was in btree cache"); >> 1110 goto retry; >> 1111 } >> 1112 >> >> From the above code, at line 1097 if __bch_bucket_alloc_set() returns non-zero value, the code will jump to label err: and returns ERR_PTR(-EAGAIN). But if the code fails at line 1103 and b is set to NULL, at line 1110 the code will jump back to label retry: and calls __bch_bucket_alloc_set() again. If the second time __bch_bucket_alloc_set() returns non-zero value and the code jumps to label err:, a NULL pointer other than ERR_PTR(-EAGAIN) will be returned. This inconsistent return value on same location at line 1097 seems incorrect, where ERR_PTR(-EAGAIN) should be returned IMHO. >> >> Therefore I feel that “b = ERR_PTR(-EAGAIN)” should be moved to the location after label retry:, then btree_node_alloc_replacement() will only return error code, and no NULL pointer returned. >> >> After this change, all following IS_ERR_OR_NULL() checks to btree_node_alloc_replacement() are unnecessary and IS_ERR() just enough, because no NULL will be returned. >> >> This is a nice catch. I’d like to have it to be fixed. I do appreciate if you want to compose two patches for the fix. Otherwise I can handle it myself. >> > Hi Coly, > > Thanks for your reply and detailed explaination! As you explain, I > found __bch_btree_node_alloc may return NULL in some situation. So I > add some more check in upper code. > Your suggestion is more constructive. It'll make the function more > clear for other developer. I'd like to help with the patch. And you > have kindly pointed the right way to fix. > May I merge fix it in one patch with the commit msg "refactor > __bch_btree_node_alloc to avoid poential NULL dereference"? Because I > think if __bch_btree_node_alloc returns > NULL to bch_btree_node_alloc, the function > btree_node_alloc_replacement will strill return NULL to n1 in > btree_split. I think the possibility is low, if it's not proper, > please feel free > to let me know. This is not a refactor indeed, just a simple fix to __bch_btree_node_alloc() to make the failure behavior of calling __bch_bucket_alloc_set() at line 1097 to be consistent. A.K.A always returning ERR_PTR(-EAGAIN) when it returns failure. Another optional patch is to change the unnecessary IS_ERR_OR_NULL() to IS_ERR() in proper locations, because after the first fix, NULL won’t be returned indeed. And extra code comments on why IS_ERR() is sufficient might be preferred IMHO. Thanks. Coly Li
Coly Li <colyli@suse.de> 于2023年2月2日周四 22:18写道: > > > > > 2023年2月2日 22:11,Zheng Hacker <hackerzheng666@gmail.com> 写道: > > > > Coly Li <colyli@suse.de> 于2023年2月2日周四 20:22写道: > > > >> Hmm, there should be something to be fixed, but not the non-exist NULL dereference. > >> > >> If you look inside btree_node_alloc_replacement(), you may find __bch_btree_node_alloc() which does the real work indeed. And yes, I would suggest you to improve a bit inside __bch_btree_node_alloc(). > >> > >> 1088 struct btree *__bch_btree_node_alloc(struct cache_set *c, struct btree_op *op, > >> [snipped] > >> 1093 struct btree *b = ERR_PTR(-EAGAIN); > >> 1094 > >> 1095 mutex_lock(&c->bucket_lock); > >> 1096 retry: > >> 1097 if (__bch_bucket_alloc_set(c, RESERVE_BTREE, &k.key, wait)) > >> 1098 goto err; > >> [snipped] > >> 1102 > >> 1103 b = mca_alloc(c, op, &k.key, level); > >> 1104 if (IS_ERR(b)) > >> 1105 goto err_free; > >> 1106 > >> 1107 if (!b) { > >> 1108 cache_bug(c, > >> 1109 "Tried to allocate bucket that was in btree cache"); > >> 1110 goto retry; > >> 1111 } > >> 1112 > >> > >> From the above code, at line 1097 if __bch_bucket_alloc_set() returns non-zero value, the code will jump to label err: and returns ERR_PTR(-EAGAIN). But if the code fails at line 1103 and b is set to NULL, at line 1110 the code will jump back to label retry: and calls __bch_bucket_alloc_set() again. If the second time __bch_bucket_alloc_set() returns non-zero value and the code jumps to label err:, a NULL pointer other than ERR_PTR(-EAGAIN) will be returned. This inconsistent return value on same location at line 1097 seems incorrect, where ERR_PTR(-EAGAIN) should be returned IMHO. > >> > >> Therefore I feel that “b = ERR_PTR(-EAGAIN)” should be moved to the location after label retry:, then btree_node_alloc_replacement() will only return error code, and no NULL pointer returned. > >> > >> After this change, all following IS_ERR_OR_NULL() checks to btree_node_alloc_replacement() are unnecessary and IS_ERR() just enough, because no NULL will be returned. > >> > >> This is a nice catch. I’d like to have it to be fixed. I do appreciate if you want to compose two patches for the fix. Otherwise I can handle it myself. > >> > > Hi Coly, > > > > Thanks for your reply and detailed explaination! As you explain, I > > found __bch_btree_node_alloc may return NULL in some situation. So I > > add some more check in upper code. > > Your suggestion is more constructive. It'll make the function more > > clear for other developer. I'd like to help with the patch. And you > > have kindly pointed the right way to fix. > > May I merge fix it in one patch with the commit msg "refactor > > __bch_btree_node_alloc to avoid poential NULL dereference"? Because I > > think if __bch_btree_node_alloc returns > > NULL to bch_btree_node_alloc, the function > > btree_node_alloc_replacement will strill return NULL to n1 in > > btree_split. I think the possibility is low, if it's not proper, > > please feel free > > to let me know. > > This is not a refactor indeed, just a simple fix to __bch_btree_node_alloc() to make the failure behavior of calling __bch_bucket_alloc_set() at line 1097 to be consistent. A.K.A always returning ERR_PTR(-EAGAIN) when it returns failure. > > Another optional patch is to change the unnecessary IS_ERR_OR_NULL() to IS_ERR() in proper locations, because after the first fix, NULL won’t be returned indeed. And extra code comments on why IS_ERR() is sufficient might be preferred IMHO. > Got it! Will do right now. Thanks agagin for your clear description about the fix. Thanks, Zheng Wang
diff --git a/drivers/md/bcache/btree.c b/drivers/md/bcache/btree.c index 147c493a989a..d5ed382fc43c 100644 --- a/drivers/md/bcache/btree.c +++ b/drivers/md/bcache/btree.c @@ -2206,7 +2206,7 @@ static int btree_split(struct btree *b, struct btree_op *op, } n1 = btree_node_alloc_replacement(b, op); - if (IS_ERR(n1)) + if (IS_ERR_OR_NULL(n1)) goto err; split = set_blocks(btree_bset_first(n1), @@ -2218,12 +2218,12 @@ static int btree_split(struct btree *b, struct btree_op *op, trace_bcache_btree_node_split(b, btree_bset_first(n1)->keys); n2 = bch_btree_node_alloc(b->c, op, b->level, b->parent); - if (IS_ERR(n2)) + if (IS_ERR_OR_NULL(n2)) goto err_free1; if (!b->parent) { n3 = bch_btree_node_alloc(b->c, op, b->level + 1, NULL); - if (IS_ERR(n3)) + if (IS_ERR_OR_NULL(n3)) goto err_free2; }