linux-unionfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] ovl: Check for NULL OVL_E() results
@ 2024-11-17  4:46 Kees Cook
  2024-11-18 18:20 ` Amir Goldstein
  2024-11-25 12:53 ` kernel test robot
  0 siblings, 2 replies; 4+ messages in thread
From: Kees Cook @ 2024-11-17  4:46 UTC (permalink / raw)
  To: Miklos Szeredi
  Cc: Kees Cook, Amir Goldstein, linux-unionfs, linux-kernel,
	linux-hardening

GCC notices that it is possible for OVL_E() to return NULL (which
implies that d_inode(dentry) may be NULL). This would result in out
of bounds reads via container_of(), seen with GCC 15's -Warray-bounds
-fdiagnostics-details. For example:

In file included from ./arch/x86/include/generated/asm/rwonce.h:1,
                 from ../include/linux/compiler.h:339,
                 from ../include/linux/export.h:5,
                 from ../include/linux/linkage.h:7,
                 from ../include/linux/fs.h:5,
                 from ../fs/overlayfs/util.c:7:
In function 'ovl_upperdentry_dereference',
    inlined from 'ovl_dentry_upper' at ../fs/overlayfs/util.c:305:9,
    inlined from 'ovl_path_type' at ../fs/overlayfs/util.c:216:6:
../include/asm-generic/rwonce.h:44:26: error: array subscript 0 is outside array bounds of 'struct inode[7486503276667837]' [-Werror=array-bounds=]
   44 | #define __READ_ONCE(x)  (*(const volatile __unqual_scalar_typeof(x) *)&(x))                       |                         ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                 ../include/asm-generic/rwonce.h:50:9: note: in expansion of macro '__READ_ONCE'
   50 |         __READ_ONCE(x);                                                 \
      |         ^~~~~~~~~~~
../fs/overlayfs/ovl_entry.h:195:16: note: in expansion of macro 'READ_ONCE'                           195 |         return READ_ONCE(oi->__upperdentry);
      |                ^~~~~~~~~
  'ovl_path_type': event 1
  185 |         return inode ? OVL_I(inode)->oe : NULL;
  'ovl_path_type': event 2

Explicitly check the result of OVL_E() and return accordingly.

Signed-off-by: Kees Cook <kees@kernel.org>
---
Cc: Miklos Szeredi <miklos@szeredi.hu>
Cc: Amir Goldstein <amir73il@gmail.com>
Cc: linux-unionfs@vger.kernel.org
---
 fs/overlayfs/util.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c
index 3bb107471fb4..32ec5eec32fa 100644
--- a/fs/overlayfs/util.c
+++ b/fs/overlayfs/util.c
@@ -213,6 +213,9 @@ enum ovl_path_type ovl_path_type(struct dentry *dentry)
 	struct ovl_entry *oe = OVL_E(dentry);
 	enum ovl_path_type type = 0;
 
+	if (WARN_ON_ONCE(oe == NULL))
+		return 0;
+
 	if (ovl_dentry_upper(dentry)) {
 		type = __OVL_PATH_UPPER;
 
@@ -1312,6 +1315,9 @@ bool ovl_is_metacopy_dentry(struct dentry *dentry)
 {
 	struct ovl_entry *oe = OVL_E(dentry);
 
+	if (WARN_ON_ONCE(oe == NULL))
+		return false;
+
 	if (!d_is_reg(dentry))
 		return false;
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] ovl: Check for NULL OVL_E() results
  2024-11-17  4:46 [PATCH] ovl: Check for NULL OVL_E() results Kees Cook
@ 2024-11-18 18:20 ` Amir Goldstein
  2025-04-21 23:00   ` Kees Cook
  2024-11-25 12:53 ` kernel test robot
  1 sibling, 1 reply; 4+ messages in thread
From: Amir Goldstein @ 2024-11-18 18:20 UTC (permalink / raw)
  To: Kees Cook; +Cc: Miklos Szeredi, linux-unionfs, linux-kernel, linux-hardening

On Sun, Nov 17, 2024 at 5:46 AM Kees Cook <kees@kernel.org> wrote:
>
> GCC notices that it is possible for OVL_E() to return NULL (which
> implies that d_inode(dentry) may be NULL).

I cannot follow this logic.

Yes, OVL_E() can be NULL, but
it does not imply that inode is NULL, so if you think that
code should to be fortified, what's wrong with:

 struct dentry *ovl_dentry_upper(struct dentry *dentry)
 {
-       return ovl_upperdentry_dereference(OVL_I(d_inode(dentry)));
+       struct inode *inode = d_inode(dentry);
+
+       return inode ? ovl_upperdentry_dereference(OVL_I(inode)) : NULL;
 }

TBH, I don't know where the line should be drawn for fortifying against
future bugs, but if the goal of this patch is to silene a compiler warning
then please specify this in the commit message, because I don't think
there is any evidence of an actual bug, is there?

Thanks,
Amir.

> This would result in out
> of bounds reads via container_of(), seen with GCC 15's -Warray-bounds
> -fdiagnostics-details. For example:
>
> In file included from ./arch/x86/include/generated/asm/rwonce.h:1,
>                  from ../include/linux/compiler.h:339,
>                  from ../include/linux/export.h:5,
>                  from ../include/linux/linkage.h:7,
>                  from ../include/linux/fs.h:5,
>                  from ../fs/overlayfs/util.c:7:
> In function 'ovl_upperdentry_dereference',
>     inlined from 'ovl_dentry_upper' at ../fs/overlayfs/util.c:305:9,
>     inlined from 'ovl_path_type' at ../fs/overlayfs/util.c:216:6:
> ../include/asm-generic/rwonce.h:44:26: error: array subscript 0 is outside array bounds of 'struct inode[7486503276667837]' [-Werror=array-bounds=]
>    44 | #define __READ_ONCE(x)  (*(const volatile __unqual_scalar_typeof(x) *)&(x))                       |                         ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                 ../include/asm-generic/rwonce.h:50:9: note: in expansion of macro '__READ_ONCE'
>    50 |         __READ_ONCE(x);                                                 \
>       |         ^~~~~~~~~~~
> ../fs/overlayfs/ovl_entry.h:195:16: note: in expansion of macro 'READ_ONCE'                           195 |         return READ_ONCE(oi->__upperdentry);
>       |                ^~~~~~~~~
>   'ovl_path_type': event 1
>   185 |         return inode ? OVL_I(inode)->oe : NULL;
>   'ovl_path_type': event 2
>
> Explicitly check the result of OVL_E() and return accordingly.
>
> Signed-off-by: Kees Cook <kees@kernel.org>
> ---
> Cc: Miklos Szeredi <miklos@szeredi.hu>
> Cc: Amir Goldstein <amir73il@gmail.com>
> Cc: linux-unionfs@vger.kernel.org
> ---
>  fs/overlayfs/util.c | 6 ++++++
>  1 file changed, 6 insertions(+)
>
> diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c
> index 3bb107471fb4..32ec5eec32fa 100644
> --- a/fs/overlayfs/util.c
> +++ b/fs/overlayfs/util.c
> @@ -213,6 +213,9 @@ enum ovl_path_type ovl_path_type(struct dentry *dentry)
>         struct ovl_entry *oe = OVL_E(dentry);
>         enum ovl_path_type type = 0;
>
> +       if (WARN_ON_ONCE(oe == NULL))
> +               return 0;
> +
>         if (ovl_dentry_upper(dentry)) {
>                 type = __OVL_PATH_UPPER;
>
> @@ -1312,6 +1315,9 @@ bool ovl_is_metacopy_dentry(struct dentry *dentry)
>  {
>         struct ovl_entry *oe = OVL_E(dentry);
>
> +       if (WARN_ON_ONCE(oe == NULL))
> +               return false;
> +
>         if (!d_is_reg(dentry))
>                 return false;
>
> --
> 2.34.1
>

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] ovl: Check for NULL OVL_E() results
  2024-11-17  4:46 [PATCH] ovl: Check for NULL OVL_E() results Kees Cook
  2024-11-18 18:20 ` Amir Goldstein
@ 2024-11-25 12:53 ` kernel test robot
  1 sibling, 0 replies; 4+ messages in thread
From: kernel test robot @ 2024-11-25 12:53 UTC (permalink / raw)
  To: Kees Cook
  Cc: oe-lkp, lkp, linux-unionfs, ltp, Miklos Szeredi, Kees Cook,
	Amir Goldstein, linux-kernel, linux-hardening, oliver.sang



Hello,

kernel test robot noticed "WARNING:at_fs/overlayfs/util.c:#ovl_path_type[overlay]" on:

commit: d6b14141241121ff7761dc8dfb33d27284fc5331 ("[PATCH] ovl: Check for NULL OVL_E() results")
url: https://github.com/intel-lab-lkp/linux/commits/Kees-Cook/ovl-Check-for-NULL-OVL_E-results/20241121-100558
base: https://git.kernel.org/cgit/linux/kernel/git/vfs/vfs.git vfs.all
patch link: https://lore.kernel.org/all/20241117044612.work.304-kees@kernel.org/
patch subject: [PATCH] ovl: Check for NULL OVL_E() results

in testcase: ltp
version: ltp-x86_64-14c1f76-1_20241111
with following parameters:

	disk: 1HDD
	fs: ext4
	test: syscalls-07



config: x86_64-rhel-9.4-ltp
compiler: gcc-12
test machine: 4 threads 1 sockets Intel(R) Core(TM) i3-3220 CPU @ 3.30GHz (Ivy Bridge) with 8G memory

(please refer to attached dmesg/kmsg for entire log/backtrace)



If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <oliver.sang@intel.com>
| Closes: https://lore.kernel.org/oe-lkp/202411251652.ecbb3c7e-lkp@intel.com


The kernel config and materials to reproduce are available at:
https://download.01.org/0day-ci/archive/20241125/202411251652.ecbb3c7e-lkp@intel.com


kern  :warn  : [  407.439702] ------------[ cut here ]------------
user  :notice: [  407.448057] fanotify06.c:134: TPASS: group 0 got event: mask 2 pid=5267 fd=13
kern  :warn  : [  407.448607] WARNING: CPU: 0 PID: 5267 at fs/overlayfs/util.c:211 ovl_path_type+0xdb/0x220 [overlay]

kern  :warn  : [  407.461773] Modules linked in:
user  :notice: [  407.473065] fanotify06.c:134: TPASS: group 1 got event: mask 2 pid=5267 fd=13
kern  :warn  : [  407.473711]  overlay

kern  :warn  : [  407.485300]  brd exfat vfat fat xfs
user  :notice: [  407.489747] fanotify06.c:134: TPASS: group 2 got event: mask 2 pid=5267 fd=13
kern  :warn  : [  407.490395]  ext2 ext4 mbcache jbd2 netconsole btrfs blake2b_generic xor zstd_compress

kern  :warn  : [  407.502433]  raid6_pq libcrc32c snd_hda_codec_realtek snd_hda_codec_generic snd_hda_scodec_component
user  :notice: [  407.512136] fanotify06.c:217: TPASS: group 3 got no event
kern  :warn  : [  407.513249]  intel_rapl_msr intel_rapl_common sd_mod x86_pkg_temp_thermal

kern  :warn  : [  407.529180]  intel_powerclamp sg coretemp snd_hda_intel
user  :notice: [  407.537741] fanotify06.c:217: TPASS: group 4 got no event
kern  :warn  : [  407.538876]  kvm_intel ipmi_devintf ipmi_msghandler

kern  :warn  : [  407.550897]  i915 snd_intel_dspcfg snd_intel_sdw_acpi kvm
user  :notice: [  407.557559] fanotify06.c:217: TPASS: group 5 got no event
kern  :warn  : [  407.558678]  cec snd_hda_codec snd_hda_core

kern  :warn  : [  407.570873]  intel_gtt snd_hwdep crct10dif_pclmul crc32_pclmul drm_buddy
user  :notice: [  407.576845] fanotify06.c:217: TPASS: group 6 got no event
kern  :warn  : [  407.577961]  crc32c_intel ahci ghash_clmulni_intel

user  :notice: [  407.586986] fanotify06.c:217: TPASS: group 7 got no event
kern  :warn  : [  407.591490]  snd_pcm

kern  :warn  : [  407.599214]  drm_display_helper ttm rapl libahci snd_timer intel_cstate
user  :notice: [  407.606451] fanotify06.c:217: TPASS: group 8 got no event
kern  :warn  : [  407.608219]  wmi_bmof

kern  :warn  : [  407.617727]  mei_me intel_uncore drm_kms_helper snd pcspkr
user  :notice: [  407.625498] fanotify06.c:158: TINFO: Test #1: Fanotify merge overlayfs mount mark
kern  :warn  : [  407.626824]  i2c_i801 lpc_ich i2c_smbus

kern  :warn  : [  407.635208]  libata mei soundcore video wmi binfmt_misc loop fuse drm dm_mod ip_tables
kern  :warn  : [  407.659894] CPU: 0 UID: 0 PID: 5267 Comm: fanotify06 Tainted: G S                 6.12.0-rc5-00193-gd6b141412411 #1
kern  :warn  : [  407.671076] Tainted: [S]=CPU_OUT_OF_SPEC
kern  :warn  : [  407.675743] Hardware name: Hewlett-Packard HP Pro 3340 MT/17A1, BIOS 8.07 01/24/2013
kern  :warn  : [  407.684219] RIP: 0010:ovl_path_type+0xdb/0x220 [overlay]
kern  :warn  : [  407.690304] Code: 01 00 00 41 8b 04 24 4d 85 f6 0f 84 b7 00 00 00 41 bc 01 00 00 00 85 c0 75 25 5b 44 89 e0 5d 41 5c 41 5d 41 5e c3 cc cc cc cc <0f> 0b 45 31 e4 5b 5d 44 89 e0 41 5c 41 5d 41 5e c3 cc cc cc cc 4c
kern  :warn  : [  407.709811] RSP: 0018:ffffc900021ff870 EFLAGS: 00010246
kern  :warn  : [  407.715790] RAX: dffffc0000000000 RBX: ffff8881e6ea33a0 RCX: ffffffffc2f437e4
kern  :warn  : [  407.723669] RDX: 1ffff1103cdd46c2 RSI: ffffc900021ff8f0 RDI: ffff8881e6ea3610
kern  :warn  : [  407.731551] RBP: ffff888001a9e800 R08: 0000000000000000 R09: ffffed1000353d0f
kern  :warn  : [  407.739432] R10: ffff888001a9e87f R11: ffff88811835de00 R12: 0000000000000000
kern  :warn  : [  407.747312] R13: ffff888001a9e830 R14: ffffc900021ff8f0 R15: 000000000011801e
kern  :warn  : [  407.755192] FS:  00007fc80cb3a740(0000) GS:ffff888174c00000(0000) knlGS:0000000000000000
kern  :warn  : [  407.764026] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
kern  :warn  : [  407.770512] CR2: 00007f3378006280 CR3: 000000013af18005 CR4: 00000000001726f0
kern  :warn  : [  407.778391] Call Trace:
kern  :warn  : [  407.781606]  <TASK>
kern  :warn  : [  407.784463]  ? __warn+0xcd/0x260
kern  :warn  : [  407.788451]  ? ovl_path_type+0xdb/0x220 [overlay]
kern  :warn  : [  407.793929]  ? report_bug+0x25d/0x2c0
kern  :warn  : [  407.798337]  ? handle_bug+0x53/0xa0
kern  :warn  : [  407.802582]  ? exc_invalid_op+0x13/0x40
kern  :warn  : [  407.807159]  ? asm_exc_invalid_op+0x16/0x20
kern  :warn  : [  407.812092]  ? ovl_already_copied_up+0x94/0x110 [overlay]
kern  :warn  : [  407.818264]  ? ovl_path_type+0xdb/0x220 [overlay]
kern  :warn  : [  407.823744]  ovl_path_realdata+0x16/0x200 [overlay]
kern  :warn  : [  407.829384]  ovl_open+0x179/0x220 [overlay]
kern  :warn  : [  407.834335]  ? __pfx_ovl_open+0x10/0x10 [overlay]
kern  :warn  : [  407.839807]  ? revert_creds+0x7a/0xb0
kern  :warn  : [  407.844218]  ? ovl_permission+0x143/0x1f0 [overlay]
kern  :warn  : [  407.849862]  do_dentry_open+0x453/0x10d0
kern  :warn  : [  407.854532]  ? __pfx_ovl_open+0x10/0x10 [overlay]
kern  :warn  : [  407.860011]  vfs_open+0x75/0x340
kern  :warn  : [  407.863987]  do_open+0x41c/0xd40
kern  :warn  : [  407.867963]  path_openat+0x23b/0x630
kern  :warn  : [  407.872289]  ? __pfx_path_openat+0x10/0x10
kern  :warn  : [  407.877141]  ? __pfx_ksys_write+0x10/0x10
kern  :warn  : [  407.881898]  ? kill_pid_info_type+0xa6/0xc0
kern  :warn  : [  407.886824]  do_filp_open+0x1b0/0x3e0
kern  :warn  : [  407.891240]  ? syscall_exit_to_user_mode+0xc/0x1e0
kern  :warn  : [  407.896780]  ? __pfx_do_filp_open+0x10/0x10
kern  :warn  : [  407.901705]  ? kfree+0xef/0x400
kern  :warn  : [  407.905595]  ? _raw_spin_lock+0x81/0xe0
kern  :warn  : [  407.910185]  ? strncpy_from_user+0x28/0x1f0
kern  :warn  : [  407.915111]  ? alloc_fd+0x269/0x440
kern  :warn  : [  407.919350]  do_sys_openat2+0x11e/0x160
kern  :warn  : [  407.923934]  ? __kasan_slab_alloc+0x2f/0x70
kern  :warn  : [  407.928867]  ? __pfx_do_sys_openat2+0x10/0x10
kern  :warn  : [  407.933975]  ? syscall_exit_to_user_mode+0xc/0x1e0
kern  :warn  : [  407.939513]  ? syscall_exit_to_user_mode+0xc/0x1e0
kern  :warn  : [  407.945048]  __x64_sys_openat+0x135/0x1d0
kern  :warn  : [  407.949806]  ? __pfx___x64_sys_openat+0x10/0x10
kern  :warn  : [  407.955082]  ? syscall_exit_to_user_mode+0x1c1/0x1e0
kern  :warn  : [  407.960795]  ? do_syscall_64+0x85/0x150
kern  :warn  : [  407.965377]  do_syscall_64+0x79/0x150
kern  :warn  : [  407.969790]  ? kmem_cache_free+0x265/0x4d0
kern  :warn  : [  407.974635]  ? switch_fpu_return+0xe8/0x1f0
kern  :warn  : [  407.979567]  ? __task_pid_nr_ns+0x21e/0x2a0
kern  :warn  : [  407.984497]  ? syscall_exit_to_user_mode+0xc/0x1e0
kern  :warn  : [  407.990035]  ? do_syscall_64+0x85/0x150
kern  :warn  : [  407.994617]  ? do_syscall_64+0x85/0x150
kern  :warn  : [  407.999198]  ? do_syscall_64+0x85/0x150
kern  :warn  : [  408.003785]  ? exc_page_fault+0x57/0xc0
kern  :warn  : [  408.008361]  entry_SYSCALL_64_after_hwframe+0x76/0x7e
kern  :warn  : [  408.014144] RIP: 0033:0x7fc80cc34f81
kern  :warn  : [  408.018477] Code: 75 57 89 f0 25 00 00 41 00 3d 00 00 41 00 74 49 80 3d 6a 26 0e 00 00 74 6d 89 da 48 89 ee bf 9c ff ff ff b8 01 01 00 00 0f 05 <48> 3d 00 f0 ff ff 0f 87 93 00 00 00 48 8b 54 24 28 64 48 2b 14 25
kern  :warn  : [  408.037988] RSP: 002b:00007ffdfed4d7b0 EFLAGS: 00000202 ORIG_RAX: 0000000000000101
kern  :warn  : [  408.046305] RAX: ffffffffffffffda RBX: 0000000000000041 RCX: 00007fc80cc34f81
kern  :warn  : [  408.054181] RDX: 0000000000000041 RSI: 000055e24d04dd40 RDI: 00000000ffffff9c
kern  :warn  : [  408.062062] RBP: 000055e24d04dd40 R08: 00000000000001a4 R09: 0000000000000000
kern  :warn  : [  408.069934] R10: 00000000000001b6 R11: 0000000000000202 R12: 00000000000000a6
kern  :warn  : [  408.077813] R13: 00000000000001a4 R14: 0000000000000000 R15: 0000000000000000
kern  :warn  : [  408.085692]  </TASK>

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] ovl: Check for NULL OVL_E() results
  2024-11-18 18:20 ` Amir Goldstein
@ 2025-04-21 23:00   ` Kees Cook
  0 siblings, 0 replies; 4+ messages in thread
From: Kees Cook @ 2025-04-21 23:00 UTC (permalink / raw)
  To: Amir Goldstein
  Cc: Miklos Szeredi, linux-unionfs, linux-kernel, linux-hardening

On Mon, Nov 18, 2024 at 07:20:52PM +0100, Amir Goldstein wrote:
> On Sun, Nov 17, 2024 at 5:46 AM Kees Cook <kees@kernel.org> wrote:
> >
> > GCC notices that it is possible for OVL_E() to return NULL (which
> > implies that d_inode(dentry) may be NULL).
> 
> I cannot follow this logic.
> 
> Yes, OVL_E() can be NULL, but
> it does not imply that inode is NULL, so if you think that
> code should to be fortified, what's wrong with:
> 
>  struct dentry *ovl_dentry_upper(struct dentry *dentry)
>  {
> -       return ovl_upperdentry_dereference(OVL_I(d_inode(dentry)));
> +       struct inode *inode = d_inode(dentry);
> +
> +       return inode ? ovl_upperdentry_dereference(OVL_I(inode)) : NULL;
>  }
> 
> TBH, I don't know where the line should be drawn for fortifying against
> future bugs, but if the goal of this patch is to silene a compiler warning
> then please specify this in the commit message, because I don't think
> there is any evidence of an actual bug, is there?

Sorry for the delay on this! I'm finally coming back around to these
fixes. :)

Yes, your suggestion works very nicely! That entirely solves the GCC
warning.

And correct, this was to deal with an over-eager compiler warning --
there was no bug here that I'm aware of.

I will send an updated patch with your suggestion.

-Kees

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2025-04-21 23:00 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-11-17  4:46 [PATCH] ovl: Check for NULL OVL_E() results Kees Cook
2024-11-18 18:20 ` Amir Goldstein
2025-04-21 23:00   ` Kees Cook
2024-11-25 12:53 ` kernel test robot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).