[PATCH] fs/readdir: Give kernel warning if an application uses the 32-bit getdents syscall

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Linux SoC]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux