ovl: avoid deadlock on directory ioctl
authorMiklos Szeredi <mszeredi@redhat.com>
Tue, 5 Jan 2021 00:36:11 +0000 (08:36 +0800)
committerMiklos Szeredi <mszeredi@redhat.com>
Thu, 28 Jan 2021 09:22:48 +0000 (10:22 +0100)
commitb854cc659dcb80f172cb35dbedc15d39d49c383f
treea6e341ada6aa4808a949c043cad3e7d90cd168b8
parentf2b00be488730522d0fb7a8a5de663febdcefe0a
ovl: avoid deadlock on directory ioctl

The function ovl_dir_real_file() currently uses the inode lock to serialize
writes to the od->upperfile field.

However, this function will get called by ovl_ioctl_set_flags(), which
utilizes the inode lock too.  In this case ovl_dir_real_file() will try to
claim a lock that is owned by a function in its call stack, which won't get
released before ovl_dir_real_file() returns.

Fix by replacing the open coded compare and exchange by an explicit atomic
op.

Fixes: 61536bed2149 ("ovl: support [S|G]ETFLAGS and FS[S|G]ETXATTR ioctls for directories")
Cc: stable@vger.kernel.org # v5.10
Reported-by: Icenowy Zheng <icenowy@aosc.io>
Tested-by: Icenowy Zheng <icenowy@aosc.io>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
fs/overlayfs/readdir.c