[PATCH v2] dcache: fix dpath buffer corruption for too small buffers

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

 



During dentry path lookups we can end up corrupting memory if the
destination path buffer is too small. This is because prepend_path()
and prepend() adjust the passed buffer length unconditionally, allowing
for the buffer length to go negative. Then a later prepend_name() call
will receive a negative length and convert this to unsigned before
comparing it against the source string length leading to a possible
memory corruption preceeding the destination buffer.

v2:
- Fix this by doing the same as prepend() and subtract the qstr length
  unconditionally from *buflen. All the callers know already how to
  properly treat a negative *buflen (Al Viro).

This fixes the following core dumping for me:

evolution[16162]: segfault at 0 ip 00007faadd0e7609 sp 00007ffffd63e780 error 4 in libevolution-mail.so.0.0.0[7faadd05a000+c7000]
BUG: unable to handle kernel paging request at ffffc900000f5000
IP: [<ffffffff812e04fa>] memmove+0x4a/0x1a0
PGD 41d80e067 PUD 41d80f067 PMD 41d820067 PTE 0
Oops: 0002 [#1] PREEMPT SMP
Modules linked in: nbd vfat fat nls_utf8 fuse rfcomm bnep bluetooth rfkill snd_hda_codec_hdmi snd_hda_codec_realtek kvm_intel kvm crc32c_intel snd_hda_intel snd_hda_codec snd_hwdep snd_pcm_oss snd_mixer_oss ftdi_sio usbserial snd_pcm cdc_acm snd_seq_dummy snd_page_alloc snd_seq_oss microcode serio_raw i915 snd_seq_midi snd_rawmidi snd_seq_midi_event snd_seq snd_seq_device snd_timer snd cfbfillrect soundcore cfbimgblt i2c_algo_bit cfbcopyarea drm_kms_helper lpc_ich drm mfd_core usb_storage usbhid
CPU: 1 PID: 16162 Comm: evolution Tainted: G        W    3.13.0-imre+ #327
Hardware name: Dell Inc. XPS 8300  /0Y2MRG, BIOS A03 02/15/2011
task: ffff8804157a8000 ti: ffff8803e0afa000 task.ti: ffff8803e0afa000
RIP: 0010:[<ffffffff812e04fa>]  [<ffffffff812e04fa>] memmove+0x4a/0x1a0
RSP: 0000:ffff8803e0afba70  EFLAGS: 00010283
RAX: ffffc900000f5000 RBX: 00000000ffffffdd RCX: ffffc900000f5000
RDX: ffffffffffffffe3 RSI: ffffc900000f4ffd RDI: ffffc900000f5000
RBP: ffff8803e0afbc30 R08: 312e302e6f732e30 R09: 2e332d6b74677469
R10: 6b62657762696c2f R11: 62696c2f7273752f R12: 0000000000000023
R13: ffff880415cb7790 R14: ffffc900000f5023 R15: ffffc900000e7370
FS:  00007faafb750a40(0000) GS:ffff88042fa40000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: ffffc900000f5000 CR3: 0000000043388000 CR4: 00000000000407e0
Stack:
 ffffffff811e4a3d ffffffff811e4757 ffff8804157a8000 0000000000007558
 000004e5000004e5 ffff880400014000 ffff880100007558 ffff8801668bfb00
 ffffffff81c226a0 ffff8803e0afbce0 ffffc900000e8558 ffffc900000e1000
Call Trace:
 [<ffffffff811e4a3d>] ? elf_core_dump+0xb3d/0x1400
 [<ffffffff811e4757>] ? elf_core_dump+0x857/0x1400
 [<ffffffff811e9b9a>] do_coredump+0xbda/0xf90
 [<ffffffff8109890d>] ? trace_hardirqs_off+0xd/0x10
 [<ffffffff81061ec6>] get_signal_to_deliver+0x5c6/0x6b0
 [<ffffffff81002378>] do_signal+0x48/0x560
 [<ffffffff811d359f>] ? fsnotify+0x8f/0x340
 [<ffffffff816ac7d1>] ? retint_signal+0x11/0x90
 [<ffffffff810028c5>] do_notify_resume+0x35/0x80
 [<ffffffff816ac806>] retint_signal+0x46/0x90
Code: 00 00 48 81 fa a8 02 00 00 72 05 40 38 fe 74 41 48 83 ea 20 48 83 ea 20 4c 8b 1e 4c 8b 56 08 4c 8b 4e 10 4c 8b 46 18 48 8d 76 20 <4c> 89 1f 4c 89 57 08 4c 89 4f 10 4c 89 47 18 48 8d 7f 20 73 d4
RIP  [<ffffffff812e04fa>] memmove+0x4a/0x1a0
 RSP <ffff8803e0afba70>
CR2: ffffc900000f5000

Signed-off-by: Imre Deak <imre.deak@xxxxxxxxx>
---
 fs/dcache.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/dcache.c b/fs/dcache.c
index 265e0ce..ca02c13 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -2833,9 +2833,9 @@ static int prepend_name(char **buffer, int *buflen, struct qstr *name)
 	u32 dlen = ACCESS_ONCE(name->len);
 	char *p;
 
-	if (*buflen < dlen + 1)
-		return -ENAMETOOLONG;
 	*buflen -= dlen + 1;
+	if (*buflen < 0)
+		return -ENAMETOOLONG;
 	p = *buffer -= dlen + 1;
 	*p++ = '/';
 	while (dlen--) {
-- 
1.8.4

--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[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