[PATCH] fs: Abort if a module symbol is too long

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

 



If a user tries to mount, using mount(2), a file system with an invalid
size, as in the following example, WARN_ONCE() is called:

	#define MAX	4096*10
	char buffer[MAX];
	memset(&buffer, 0xff, 4096*100);
	syscall(SYS_mount, "/tmp/foo", "/tmp/bar", &buffer, 0x0, NULL);

This simple example can call WARN_ONCE() that dumps the whole CPU register
set to the log buffer, which is undesired, since it dumps internal CPU
states.

	precision 56029 too large
	WARNING: CPU: 1 PID: 17377 at lib/vsprintf.c:2293 set_precision+0xa0/0xc0
	Modules linked in: binfmt_misc ghash_generic gf128mul ecb xts ctr evdev cbc vmx_crypto virtio_balloon ip_tables x_tables autofs4 hid_generic usbhid hid ext4 crc16 mbcache jbd2 fscrypto crc32c_generic ohci_pci ehci_pci ohci_hcd ehci_hcd usbcore ibmvscsi scsi_transport_srp
	CPU: 1 PID: 17377 Comm: trinity-c10 Not tainted 5.0.0-rc1-00003-g9655f21d217a #960
	NIP:  c0000000009cd820 LR: c0000000009cd81c CTR: c0000000009d1740
	REGS: c00000041d7cf7a0 TRAP: 0700   Not tainted  (5.0.0-rc1-00003-g9655f21d217a)
	MSR:  8000000002029033 <SF,VEC,EE,ME,IR,DR,RI,LE>  CR: 28024422  XER: 20000000
	CFAR: c000000000106cc4 IRQMASK: 0
	GPR00: c0000000009cd81c c00000041d7cfa30 c000000000e7d100 0000000000000019
	GPR04: 0000000000000000 0000000000000009 000000006772616c 0000000000000019
	GPR08: c000000000eb6dc0 0000000000000000 0000000000000000 c00000041d7cf75f
	GPR12: 0000000000004400 c00000003ffcf480 0000000010034c30 0000000010034c20
	GPR16: 0000000000000000 0000000000000000 0000000010034c40 0000000010034808
	GPR20: 0000000010985da4 0000000000000433 0000000000000003 c000000000b68d76
	GPR24: c00000041d7cfc88 0000000000000025 0000000000000020 0000000000000038
	GPR28: c00000041d7cfbd0 c00000041d7cfc08 c000000000b68d76 c00000041d7cfad0
	NIP [c0000000009cd820] set_precision+0xa0/0xc0
	LR [c0000000009cd81c] set_precision+0x9c/0xc0
	Call Trace:
	[c00000041d7cfa30] [c0000000009cd81c] set_precision+0x9c/0xc0 (unreliable)
	[c00000041d7cfab0] [c0000000009d1614] vsnprintf+0x194/0x4e0
	[c00000041d7cfb30] [c000000000140b2c] __request_module+0xdc/0x570
	[c00000041d7cfc50] [c0000000003fd0f8] get_fs_type+0xe8/0x190
	[c00000041d7cfcd0] [c0000000004033bc] do_mount+0x2ac/0x1040
	[c00000041d7cfdb0] [c000000000404668] ksys_mount+0x158/0x180
	[c00000041d7cfe00] [c0000000004046b0] sys_mount+0x20/0x30
	[c00000041d7cfe20] [c00000000000bde4] system_call+0x5c/0x70
	Instruction dump:
	39400000 4bffffe0 7c0802a6 39200001 f8810068 3d42fff7 3c62ffd4 386368d8
	992a5bad f8010090 4b739445 60000000 <0fe00000> e8010090 e9410068 7c0803a6
	---[ end trace 9964ee192f850a9d ]---

This path simply does not request the module if the file system name (thus
module name) is bigger than MODULE_NAME_LEN.

Signed-off-by: Breno Leitao <leitao@xxxxxxxxxx>
---
 fs/filesystems.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/fs/filesystems.c b/fs/filesystems.c
index b03f57b1105b..375abb39d073 100644
--- a/fs/filesystems.c
+++ b/fs/filesystems.c
@@ -264,6 +264,9 @@ struct file_system_type *get_fs_type(const char *name)
 	const char *dot = strchr(name, '.');
 	int len = dot ? dot - name : strlen(name);
 
+	if (len > MODULE_NAME_LEN)
+		return NULL;
+
 	fs = __get_fs_type(name, len);
 	if (!fs && (request_module("fs-%.*s", len, name) == 0)) {
 		fs = __get_fs_type(name, len);
-- 
2.19.0




[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux