When building a kernel that disables support for 32-bit time_t system calls, it also makes sense to disable the old xfs_bstat ioctls completely, as they truncate the timestamps to 32-bit values.
Any application using these needs to be updated to use the v5 interfaces.
Signed-off-by: Arnd Bergmann arnd@arndb.de --- fs/xfs/xfs_ioctl.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c index 7b35d62ede9f..a4a4eed8879c 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c @@ -36,6 +36,7 @@ #include "xfs_reflink.h" #include "xfs_ioctl.h"
+#include <linux/compat.h> #include <linux/mount.h> #include <linux/namei.h>
@@ -617,6 +618,23 @@ xfs_fsinumbers_fmt( return xfs_ibulk_advance(breq, sizeof(struct xfs_inogrp)); }
+/* disallow y2038-unsafe ioctls with CONFIG_COMPAT_32BIT_TIME=n */ +static bool xfs_have_compat_bstat_time32(unsigned int cmd) +{ + if (IS_ENABLED(CONFIG_COMPAT_32BIT_TIME)) + return true; + + if (IS_ENABLED(CONFIG_64BIT) && !in_compat_syscall()) + return true; + + if (cmd == XFS_IOC_FSBULKSTAT_SINGLE || + cmd == XFS_IOC_FSBULKSTAT || + cmd == XFS_IOC_SWAPEXT) + return false; + + return true; +} + STATIC int xfs_ioc_fsbulkstat( xfs_mount_t *mp, @@ -637,6 +655,9 @@ xfs_ioc_fsbulkstat( if (!capable(CAP_SYS_ADMIN)) return -EPERM;
+ if (!xfs_have_compat_bstat_time32(cmd)) + return -EINVAL; + if (XFS_FORCED_SHUTDOWN(mp)) return -EIO;
@@ -1815,6 +1836,11 @@ xfs_ioc_swapext( struct fd f, tmp; int error = 0;
+ if (xfs_have_compat_bstat_time32(XFS_IOC_SWAPEXT)) { + error = -EINVAL; + goto out; + } + /* Pull information for the target fd */ f = fdget((int)sxp->sx_fdtarget); if (!f.file) {