Message ID | 20221022203913.264855-1-linux@treblig.org |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4242:0:0:0:0:0 with SMTP id s2csp1356108wrr; Sat, 22 Oct 2022 14:13:58 -0700 (PDT) X-Google-Smtp-Source: AMsMyM4wK1wdjt0KiHXzmYZOsGQy2HxCJETrOT68x7ZuIWfLNH1MDX9m99SOFmixXPRbLFGSSpLr X-Received: by 2002:a05:6402:34d0:b0:460:96c4:94af with SMTP id w16-20020a05640234d000b0046096c494afmr14044385edc.365.1666473238243; Sat, 22 Oct 2022 14:13:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1666473238; cv=none; d=google.com; s=arc-20160816; b=lTVT+Dz0dx4peIaAemFVBmoIcvlz/02kXUmO5acO8Rf9TAjpmgIPjm6YTDUCOda1g0 p5+/HGR/4FoM1Lsl1yq7rjU7gPlCHCAOxucE7gtemYK15iYuXxr2AXLqmJMR+N3APHxA KJ74+mmBmHTGM5LP2Kr7zUYWR8yldTfNio3jNOkmQ8fQ+0qPkm9rC+5bILbAG2dmIu68 QVkXm6gesgQmAzqx1s5jqGElpnVkB6dXFFntOOIExIgURHqq4PthuiHTEkdQnBFBDK0G 7qFwzV5F9/Wo7nzFGi+66bUxe9PcdpyRYt5Mp6qPcNE929bDKW1+ObZY69RCsZ41PQsN t0NQ== 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=mZ7ZhD4cvnKSycRl1+l3M39tGHDRpDCkJZSVTXRFl8w=; b=SjYaqLhOQW4QDoOkYGTN7LYaZeYVwhbFXvTvavoQywI1nT+FJ+zzfIkxpwoBwr9R/Y hmXRhHpMYpk82/BMca3b/MNiXdBfUsOl4b54xdkJMhyfzIja9BrB5aYMVnYP8URw9atS i1jzwoqenHtdsSpyQjiZwhyAC25Prf9YGmFUlWrQnIxP17pj9hWWdRWMM4IJCxNtolKk 3TWGgwOo/y+KY4hPbFP4lD+LUewTpwhVcVrRhSe+KzLVOy97BCZLWoV1gM1OuPvwaD4v FTTyCpE4oJf+Wi0Tx5chSQ2+LS9Jst0Ci5+6F14keeUiiZgJW00lrWPUHLh0vXzB15qm ocJQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@treblig.org header.s=bytemarkmx header.b=WJKfcJmu; 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 Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id n15-20020aa7d04f000000b0046109fd5943si2345557edo.544.2022.10.22.14.13.34; Sat, 22 Oct 2022 14:13:58 -0700 (PDT) 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=fail header.i=@treblig.org header.s=bytemarkmx header.b=WJKfcJmu; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229707AbiJVVEk (ORCPT <rfc822;pwkd43@gmail.com> + 99 others); Sat, 22 Oct 2022 17:04:40 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48836 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229634AbiJVVEi (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Sat, 22 Oct 2022 17:04:38 -0400 X-Greylist: delayed 1474 seconds by postgrey-1.37 at lindbergh.monkeyblade.net; Sat, 22 Oct 2022 14:04:35 PDT Received: from mx.treblig.org (mx.treblig.org [46.43.15.161]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 61B7D1B797 for <linux-kernel@vger.kernel.org>; Sat, 22 Oct 2022 14:04:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=treblig.org ; s=bytemarkmx; h=Content-Transfer-Encoding:MIME-Version:Message-Id:Date: Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=mZ7ZhD4cvnKSycRl1+l3M39tGHDRpDCkJZSVTXRFl8w=; b=WJKfcJmuhyS3Dp1MiLdjvyeksT VYgoPFLU1O+GHcSt2FfvvS36yWVasgGv8oHusCk+fnHV+CPjX4KOeHjLZduy/o6pm3+2/BNOmfVuT TQaK+/t8dCl6hbhOO5PVkPryza29I+Vz9a/yRHjocI0b5UX92kGgKjT9t2ejYTOwp+lGEqidBybeE k1WfMvmAE1pVR65MTCaQuXbQohxOWQeI3Mh8cj/GD466J16FyZbk/DrCCpsMp6H2gBQTcNm8sMhYN 2qfZFHyR7QOdwFV4iXf5vyj2vXfBwoVKlBRLHU7t/v1aeiELZG8L1jnQ5yta8K14JwmkaaDxqeFPF 8E8vfbNA==; Received: from localhost ([127.0.0.1] helo=dalek.home.treblig.org) by mx.treblig.org with esmtp (Exim 4.94.2) (envelope-from <linux@treblig.org>) id 1omLHV-005mx1-2y; Sat, 22 Oct 2022 21:39:44 +0100 From: linux@treblig.org To: linux@treblig.org, shaggy@kernel.org, jfs-discussion@lists.sourceforge.net, linux-kernel@vger.kernel.org Cc: syzbot+5fc38b2ddbbca7f5c680@syzkaller.appspotmail.com Subject: [PATCH] jfs: Fix fortify moan in symlink Date: Sat, 22 Oct 2022 21:39:14 +0100 Message-Id: <20221022203913.264855-1-linux@treblig.org> X-Mailer: git-send-email 2.37.3 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,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?1747423842518769619?= X-GMAIL-MSGID: =?utf-8?q?1747423842518769619?= |
Series |
jfs: Fix fortify moan in symlink
|
|
Commit Message
Dr. David Alan Gilbert
Oct. 22, 2022, 8:39 p.m. UTC
From: "Dr. David Alan Gilbert" <linux@treblig.org> JFS has in jfs_incore.h: /* _inline may overflow into _inline_ea when needed */ /* _inline_ea may overlay the last part of * file._xtroot if maxentry = XTROOTINITSLOT */ union { struct { /* 128: inline symlink */ unchar _inline[128]; /* 128: inline extended attr */ unchar _inline_ea[128]; }; unchar _inline_all[256]; and currently the symlink code copies into _inline; if this is larger than 128 bytes it triggers a fortify warning of the form: memcpy: detected field-spanning write (size 132) of single field "ip->i_link" at fs/jfs/namei.c:950 (size 18446744073709551615) when it's actually OK. Copy it into _inline_all instead. Reported-by: syzbot+5fc38b2ddbbca7f5c680@syzkaller.appspotmail.com Signed-off-by: Dr. David Alan Gilbert <linux@treblig.org> --- fs/jfs/namei.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
Comments
On Sat, Oct 22, 2022 at 09:39:14PM +0100, linux@treblig.org wrote: > From: "Dr. David Alan Gilbert" <linux@treblig.org> > > JFS has in jfs_incore.h: > > /* _inline may overflow into _inline_ea when needed */ > /* _inline_ea may overlay the last part of > * file._xtroot if maxentry = XTROOTINITSLOT > */ > union { > struct { > /* 128: inline symlink */ > unchar _inline[128]; > /* 128: inline extended attr */ > unchar _inline_ea[128]; > }; > unchar _inline_all[256]; > > and currently the symlink code copies into _inline; > if this is larger than 128 bytes it triggers a fortify warning of the > form: > > memcpy: detected field-spanning write (size 132) of single field > "ip->i_link" at fs/jfs/namei.c:950 (size 18446744073709551615) Which compiler are you using for this build? This size report (SIZE_MAX) should be impossible to reach. But also, the size is just wrong -- i_inline is 128 bytes, not SIZE_MAX. So, the detection is working (132 > 128), but the report is broken, and I can't see how... > > when it's actually OK. > > Copy it into _inline_all instead. > > Reported-by: syzbot+5fc38b2ddbbca7f5c680@syzkaller.appspotmail.com > Signed-off-by: Dr. David Alan Gilbert <linux@treblig.org> > --- > fs/jfs/namei.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c > index 9db4f5789c0ec..4fbbf88435e69 100644 > --- a/fs/jfs/namei.c > +++ b/fs/jfs/namei.c > @@ -946,7 +946,7 @@ static int jfs_symlink(struct user_namespace *mnt_userns, struct inode *dip, > if (ssize <= IDATASIZE) { > ip->i_op = &jfs_fast_symlink_inode_operations; > > - ip->i_link = JFS_IP(ip)->i_inline; > + ip->i_link = JFS_IP(ip)->i_inline_all; > memcpy(ip->i_link, name, ssize); > ip->i_size = ssize - 1; > Regardless, the fix looks correct to me! Reviewed-by: Kees Cook <keescook@chromium.org>
* Kees Cook (keescook@chromium.org) wrote: > On Sat, Oct 22, 2022 at 09:39:14PM +0100, linux@treblig.org wrote: > > From: "Dr. David Alan Gilbert" <linux@treblig.org> > > > > JFS has in jfs_incore.h: > > > > /* _inline may overflow into _inline_ea when needed */ > > /* _inline_ea may overlay the last part of > > * file._xtroot if maxentry = XTROOTINITSLOT > > */ > > union { > > struct { > > /* 128: inline symlink */ > > unchar _inline[128]; > > /* 128: inline extended attr */ > > unchar _inline_ea[128]; > > }; > > unchar _inline_all[256]; > > > > and currently the symlink code copies into _inline; > > if this is larger than 128 bytes it triggers a fortify warning of the > > form: > > > > memcpy: detected field-spanning write (size 132) of single field > > "ip->i_link" at fs/jfs/namei.c:950 (size 18446744073709551615) > > Which compiler are you using for this build? I think that report was the same on gcc on Fedora 37 and whatever syzkaller was running. > This size report (SIZE_MAX) > should be impossible to reach. But also, the size is just wrong -- > i_inline is 128 bytes, not SIZE_MAX. So, the detection is working > (132 > 128), but the report is broken, and I can't see how... Yeh, and led me down a blind alley for a while thinking something had really managed to screwup the strlen somehow. > > > > > when it's actually OK. > > > > Copy it into _inline_all instead. > > > > Reported-by: syzbot+5fc38b2ddbbca7f5c680@syzkaller.appspotmail.com > > Signed-off-by: Dr. David Alan Gilbert <linux@treblig.org> > > --- > > fs/jfs/namei.c | 2 +- > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c > > index 9db4f5789c0ec..4fbbf88435e69 100644 > > --- a/fs/jfs/namei.c > > +++ b/fs/jfs/namei.c > > @@ -946,7 +946,7 @@ static int jfs_symlink(struct user_namespace *mnt_userns, struct inode *dip, > > if (ssize <= IDATASIZE) { > > ip->i_op = &jfs_fast_symlink_inode_operations; > > > > - ip->i_link = JFS_IP(ip)->i_inline; > > + ip->i_link = JFS_IP(ip)->i_inline_all; > > memcpy(ip->i_link, name, ssize); > > ip->i_size = ssize - 1; > > > > Regardless, the fix looks correct to me! > > Reviewed-by: Kees Cook <keescook@chromium.org> Thanks! Dave > -- > Kees Cook
Applied. Thanks, Shaggy On 10/24/22 1:49PM, Dr. David Alan Gilbert wrote: > * Kees Cook (keescook@chromium.org) wrote: >> On Sat, Oct 22, 2022 at 09:39:14PM +0100, linux@treblig.org wrote: >>> From: "Dr. David Alan Gilbert" <linux@treblig.org> >>> >>> JFS has in jfs_incore.h: >>> >>> /* _inline may overflow into _inline_ea when needed */ >>> /* _inline_ea may overlay the last part of >>> * file._xtroot if maxentry = XTROOTINITSLOT >>> */ >>> union { >>> struct { >>> /* 128: inline symlink */ >>> unchar _inline[128]; >>> /* 128: inline extended attr */ >>> unchar _inline_ea[128]; >>> }; >>> unchar _inline_all[256]; >>> >>> and currently the symlink code copies into _inline; >>> if this is larger than 128 bytes it triggers a fortify warning of the >>> form: >>> >>> memcpy: detected field-spanning write (size 132) of single field >>> "ip->i_link" at fs/jfs/namei.c:950 (size 18446744073709551615) >> >> Which compiler are you using for this build? > > I think that report was the same on gcc on Fedora 37 and whatever > syzkaller was running. > >> This size report (SIZE_MAX) >> should be impossible to reach. But also, the size is just wrong -- >> i_inline is 128 bytes, not SIZE_MAX. So, the detection is working >> (132 > 128), but the report is broken, and I can't see how... > > Yeh, and led me down a blind alley for a while thinking something had > really managed to screwup the strlen somehow. > >> >>> >>> when it's actually OK. >>> >>> Copy it into _inline_all instead. >>> >>> Reported-by: syzbot+5fc38b2ddbbca7f5c680@syzkaller.appspotmail.com >>> Signed-off-by: Dr. David Alan Gilbert <linux@treblig.org> >>> --- >>> fs/jfs/namei.c | 2 +- >>> 1 file changed, 1 insertion(+), 1 deletion(-) >>> >>> diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c >>> index 9db4f5789c0ec..4fbbf88435e69 100644 >>> --- a/fs/jfs/namei.c >>> +++ b/fs/jfs/namei.c >>> @@ -946,7 +946,7 @@ static int jfs_symlink(struct user_namespace *mnt_userns, struct inode *dip, >>> if (ssize <= IDATASIZE) { >>> ip->i_op = &jfs_fast_symlink_inode_operations; >>> >>> - ip->i_link = JFS_IP(ip)->i_inline; >>> + ip->i_link = JFS_IP(ip)->i_inline_all; >>> memcpy(ip->i_link, name, ssize); >>> ip->i_size = ssize - 1; >>> >> >> Regardless, the fix looks correct to me! >> >> Reviewed-by: Kees Cook <keescook@chromium.org> > > Thanks! > > Dave > >> -- >> Kees Cook
On Mon, Oct 24, 2022 at 07:49:17PM +0100, Dr. David Alan Gilbert wrote: > * Kees Cook (keescook@chromium.org) wrote: > > On Sat, Oct 22, 2022 at 09:39:14PM +0100, linux@treblig.org wrote: > > > From: "Dr. David Alan Gilbert" <linux@treblig.org> > > > > > > JFS has in jfs_incore.h: > > > > > > /* _inline may overflow into _inline_ea when needed */ > > > /* _inline_ea may overlay the last part of > > > * file._xtroot if maxentry = XTROOTINITSLOT > > > */ > > > union { > > > struct { > > > /* 128: inline symlink */ > > > unchar _inline[128]; > > > /* 128: inline extended attr */ > > > unchar _inline_ea[128]; > > > }; > > > unchar _inline_all[256]; > > > > > > and currently the symlink code copies into _inline; > > > if this is larger than 128 bytes it triggers a fortify warning of the > > > form: > > > > > > memcpy: detected field-spanning write (size 132) of single field > > > "ip->i_link" at fs/jfs/namei.c:950 (size 18446744073709551615) > > > > Which compiler are you using for this build? > > I think that report was the same on gcc on Fedora 37 and whatever > syzkaller was running. > > > This size report (SIZE_MAX) > > should be impossible to reach. But also, the size is just wrong -- > > i_inline is 128 bytes, not SIZE_MAX. So, the detection is working > > (132 > 128), but the report is broken, and I can't see how... > > Yeh, and led me down a blind alley for a while thinking something had > really managed to screwup the strlen somehow. This looks like a GCC bug (going at least back to GCC 10.2)[1], but some extra care around the macro appears to make it go away, so the reporting variable doesn't get confused/re-evaluated: diff --git a/include/linux/fortify-string.h b/include/linux/fortify-string.h index 09a032f6ce6b..9e2d96993c30 100644 --- a/include/linux/fortify-string.h +++ b/include/linux/fortify-string.h @@ -550,13 +550,18 @@ __FORTIFY_INLINE bool fortify_memcpy_chk(__kernel_size_t size, #define __fortify_memcpy_chk(p, q, size, p_size, q_size, \ p_size_field, q_size_field, op) ({ \ - size_t __fortify_size = (size_t)(size); \ - WARN_ONCE(fortify_memcpy_chk(__fortify_size, p_size, q_size, \ - p_size_field, q_size_field, #op), \ + const size_t __fortify_size = (size_t)(size); \ + const size_t __p_size = (p_size); \ + const size_t __q_size = (q_size); \ + const size_t __p_size_field = (p_size_field); \ + const size_t __q_size_field = (q_size_field); \ + WARN_ONCE(fortify_memcpy_chk(__fortify_size, __p_size, \ + __q_size, __p_size_field, \ + __q_size_field, #op), \ #op ": detected field-spanning write (size %zu) of single %s (size %zu)\n", \ __fortify_size, \ "field \"" #p "\" at " __FILE__ ":" __stringify(__LINE__), \ - p_size_field); \ + __p_size_field); \ __underlying_##op(p, q, __fortify_size); \ }) [1] https://syzkaller.appspot.com/bug?id=23d613df5259b977dac1696bec77f61a85890e3d
* Kees Cook (keescook@chromium.org) wrote: > On Mon, Oct 24, 2022 at 07:49:17PM +0100, Dr. David Alan Gilbert wrote: > > * Kees Cook (keescook@chromium.org) wrote: > > > On Sat, Oct 22, 2022 at 09:39:14PM +0100, linux@treblig.org wrote: > > > > From: "Dr. David Alan Gilbert" <linux@treblig.org> > > > > > > > > JFS has in jfs_incore.h: > > > > > > > > /* _inline may overflow into _inline_ea when needed */ > > > > /* _inline_ea may overlay the last part of > > > > * file._xtroot if maxentry = XTROOTINITSLOT > > > > */ > > > > union { > > > > struct { > > > > /* 128: inline symlink */ > > > > unchar _inline[128]; > > > > /* 128: inline extended attr */ > > > > unchar _inline_ea[128]; > > > > }; > > > > unchar _inline_all[256]; > > > > > > > > and currently the symlink code copies into _inline; > > > > if this is larger than 128 bytes it triggers a fortify warning of the > > > > form: > > > > > > > > memcpy: detected field-spanning write (size 132) of single field > > > > "ip->i_link" at fs/jfs/namei.c:950 (size 18446744073709551615) > > > > > > Which compiler are you using for this build? > > > > I think that report was the same on gcc on Fedora 37 and whatever > > syzkaller was running. > > > > > This size report (SIZE_MAX) > > > should be impossible to reach. But also, the size is just wrong -- > > > i_inline is 128 bytes, not SIZE_MAX. So, the detection is working > > > (132 > 128), but the report is broken, and I can't see how... > > > > Yeh, and led me down a blind alley for a while thinking something had > > really managed to screwup the strlen somehow. > > This looks like a GCC bug (going at least back to GCC 10.2)[1], but some > extra care around the macro appears to make it go away, so the reporting > variable doesn't get confused/re-evaluated: Thanks for chasing that; are you also going to file a gcc bug? Dave > diff --git a/include/linux/fortify-string.h b/include/linux/fortify-string.h > index 09a032f6ce6b..9e2d96993c30 100644 > --- a/include/linux/fortify-string.h > +++ b/include/linux/fortify-string.h > @@ -550,13 +550,18 @@ __FORTIFY_INLINE bool fortify_memcpy_chk(__kernel_size_t size, > > #define __fortify_memcpy_chk(p, q, size, p_size, q_size, \ > p_size_field, q_size_field, op) ({ \ > - size_t __fortify_size = (size_t)(size); \ > - WARN_ONCE(fortify_memcpy_chk(__fortify_size, p_size, q_size, \ > - p_size_field, q_size_field, #op), \ > + const size_t __fortify_size = (size_t)(size); \ > + const size_t __p_size = (p_size); \ > + const size_t __q_size = (q_size); \ > + const size_t __p_size_field = (p_size_field); \ > + const size_t __q_size_field = (q_size_field); \ > + WARN_ONCE(fortify_memcpy_chk(__fortify_size, __p_size, \ > + __q_size, __p_size_field, \ > + __q_size_field, #op), \ > #op ": detected field-spanning write (size %zu) of single %s (size %zu)\n", \ > __fortify_size, \ > "field \"" #p "\" at " __FILE__ ":" __stringify(__LINE__), \ > - p_size_field); \ > + __p_size_field); \ > __underlying_##op(p, q, __fortify_size); \ > }) > > > > [1] https://syzkaller.appspot.com/bug?id=23d613df5259b977dac1696bec77f61a85890e3d > > -- > Kees Cook
On Sat, Oct 29, 2022 at 01:48:05PM +0100, Dr. David Alan Gilbert wrote: > * Kees Cook (keescook@chromium.org) wrote: > > This looks like a GCC bug (going at least back to GCC 10.2)[1], but some > > extra care around the macro appears to make it go away, so the reporting > > variable doesn't get confused/re-evaluated: > > Thanks for chasing that; are you also going to file a gcc bug? No, I haven't had the time to minimize a PoC, so I'm not sure it would make a very good bug report.
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index 9db4f5789c0ec..4fbbf88435e69 100644 --- a/fs/jfs/namei.c +++ b/fs/jfs/namei.c @@ -946,7 +946,7 @@ static int jfs_symlink(struct user_namespace *mnt_userns, struct inode *dip, if (ssize <= IDATASIZE) { ip->i_op = &jfs_fast_symlink_inode_operations; - ip->i_link = JFS_IP(ip)->i_inline; + ip->i_link = JFS_IP(ip)->i_inline_all; memcpy(ip->i_link, name, ssize); ip->i_size = ssize - 1;