This patch allows to detect which programs still use the 32-bit directory system calls and which should be converted to use large filessystem support (LFS). Link: https://sourceware.org/bugzilla/show_bug.cgi?id=23960 Signed-off-by: Helge Deller <deller@xxxxxx> --- arch/Kconfig | 10 ++++++++++ fs/readdir.c | 18 ++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/arch/Kconfig b/arch/Kconfig index 12e3ddabac9d..24ebaa3911eb 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -1153,6 +1153,16 @@ config COMPAT_32BIT_TIME This is relevant on all 32-bit architectures, and 64-bit architectures as part of compat syscall handling. +config COMPAT_WARN_32BIT_FILESYSTEM_ACCESS + bool "Warn on usage of 32-bit filesystem system calls" + default !64BIT || COMPAT + help + Issue a warning in kernel syslog if a 32-bit userspace application + calls the 32-bit getdents() syscall. Enabling this option helps to + find programs which will silently break on larger filesystems. + Disable this option only if you know your machine will never access + filesystems above 4GB of size (embedded devices). + config ARCH_NO_PREEMPT bool diff --git a/fs/readdir.c b/fs/readdir.c index 9c53edb60c03..93c80726f82c 100644 --- a/fs/readdir.c +++ b/fs/readdir.c @@ -116,6 +116,19 @@ static int verify_dirent_name(const char *name, int len) return 0; } +static void warn_32bit_access(void) +{ +#ifdef CONFIG_COMPAT_WARN_32BIT_FILESYSTEM_ACCESS + if (sizeof(compat_ulong_t) >= sizeof(loff_t)) + return; + + printk_ratelimited(KERN_WARNING "%s(%d): Recompile this 32-bit " + "application with '-D_FILE_OFFSET_BITS=64 " + "-D_LARGEFILE_SOURCE' or '-D_GNU_SOURCE'\n", + current->comm, task_pid_nr(current)); +#endif +} + /* * Traditional linux readdir() handling.. * @@ -195,6 +208,7 @@ SYSCALL_DEFINE3(old_readdir, unsigned int, fd, error = buf.result; fdput_pos(f); + warn_32bit_access(); return error; } @@ -294,6 +308,8 @@ SYSCALL_DEFINE3(getdents, unsigned int, fd, error = -EFAULT; else error = count - buf.count; + } else { + warn_32bit_access(); } fdput_pos(f); return error; @@ -545,6 +561,8 @@ COMPAT_SYSCALL_DEFINE3(getdents, unsigned int, fd, error = -EFAULT; else error = count - buf.count; + } else { + warn_32bit_access(); } fdput_pos(f); return error; -- 2.38.1