Bug 142586

Summary: Potential kernel DOS
Product: Red Hat Enterprise Linux 3 Reporter: Josh Bressers <bressers>
Component: kernelAssignee: Dave Anderson <anderson>
Status: CLOSED ERRATA QA Contact: Brian Brock <bbrock>
Severity: low Docs Contact:
Priority: medium    
Version: 3.0CC: davem, lwoodman, mjc, petrides, redhat-bugzilla, riel
Target Milestone: ---Keywords: Security
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard: impact=low,source=lkml,public=20041125
Fixed In Version: RHSA-2005-663 Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2005-09-28 14:38:04 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 156320    
Attachments:
Description Flags
test module that makes a reserved page available for user mmap'ing
none
user program to mmap a reserved page from testmod module none

Description Josh Bressers 2004-12-10 19:35:07 UTC
This message
http://marc.theaimsgroup.com/?l=linux-kernel&m=109776571411003

refers to a memory leak in the 2.4 kernel.  As far as I can tell we're
vulnerable to this issue, but the fix mentioned in the message looks
pretty hackish.

Could one of you guys who understands the kernel take a look at this
and see if this is a real issue, and if it actually affects us.

Comment 1 Josh Bressers 2004-12-10 19:38:38 UTC
The message seems to suggest that one needs a raw socket to trigger
this issue.  If that's the case, the severity of this issue is
seriously mitigated.

Comment 2 Ernie Petrides 2004-12-10 22:05:21 UTC
The subject line of the LKML link above is:

  Memory leak in 2.4.27 kernel, using mmap raw packet sockets

The discussion is about whether get_user_pages() should modify
page reference counts when the PG_reserved bit is set.


Comment 4 Dave Anderson 2004-12-16 15:41:11 UTC
> I discovered a memory leak in the mmap raw packet socket
> implementation, specifically when the client application core dumps
> (elf format). More specifically, the entire ring buffer memory leaks
> under such circumstances. I have reproduced the problem with our
> custom app, which links with Phil Wood's mmap version of libpcap
> (http://plublic.lanl.gov/cpw) as well as with tcpdump binding
> against the same library. I have asserted the problem presence in
> kernels 2.4.26 and 2.4.27. It has been resolved in kernel 2.6.8.

Although the reporter has reproduced it, his description makes little
sense to me.  While it appears in an application where a driver calls
mem_map_reserve() and is able to force a core dump before the driver
does a subsequent mem_map_unreserve(), then it would appear that the
page->count would be out of sync. 

But I have no way of knowing whether this is realistically
reproducible using our kernel?




Comment 5 Ernie Petrides 2005-05-23 20:52:51 UTC
Dave, I've just looked into this a bit more.  I *do* think the RHEL3
kernel is vulnerable.  There are plenty of mem_map_reserve() calls
from various drivers, and at least one in drivers/media/video/meye.c
is used on a region that is mmap'ed into user space.  I think that if
the application dumps core when the mapping is in effect, the page
reference count will get out of sync as described in LKML posting at
the URL in the initial comment of this bug report.


Comment 6 Dave Anderson 2005-05-23 21:07:07 UTC
Right -- I agreed that it *could* happen.
But can you whip up a reproducer?

Comment 7 Ernie Petrides 2005-05-24 19:35:03 UTC
Dave, I don't have time to develop a reproducer.  Could you please
either do this or figure out a way to utilize one of our existing
drivers that implements mmap'ing of a memory that has had an
mem_map_reserve() invoked for its page(s)?  Thanks.  -ernie


Comment 8 Dave Anderson 2005-05-24 19:53:00 UTC
> ...figure out a way to utilize one of our existing
> drivers that implements mmap'ing of a memory that has had an
> mem_map_reserve() invoked for its page(s)? 

Well, looking at the list of RHEL3 drivers that call mem_map_reserve(),
I would say no, I couldn't figure out a way to do that.
  
I suppose we could create a debug module that does an mem_map_reserve()
on a page in a calling process's data section, and then force it to dump
core.  Or for that matter, it wouldn't even need a module -- I coud just
set the PG_reserved bit on some process's data page with crash, and then
force the process to dump core.  Would that suffice?




Comment 9 Ernie Petrides 2005-05-24 20:47:16 UTC
Yes, that's a perfectly valid test scenario.  (I guess you'd have
to verify the page ref count with "crash" before and after the
core dump.)


Comment 10 Mark J. Cox 2005-05-26 15:22:33 UTC
Does comment 8 or 9 imply that this is not possible to trigger by an
unprivileged user, and therefore not a security issues.  Or just that it is hard
but not impossible to create a reproducer that could work.

Comment 11 Dave Anderson 2005-05-26 15:53:37 UTC
Comment #8 implies my complete unfamiliarity with interfacing with
drivers in order to get them to call mem_map_reserve().

These are the current mem_map_reserve() callers in the RHEL3 kernel: 

Functions calling this function: mem_map_reserve

  File                              Function             Line
0 ia64/kernel/perfmon.c             pfm_rvmalloc          742
mem_map_reserve(virt_to_page(__va(page)));
1 addon/cmpci_564/cmpci.c           prog_dmabuf           994
mem_map_reserve(pstart);
2 char/drm-4.0/memory.c             drm_alloc_pages       252
mem_map_reserve(virt_to_page(addr));
3 char/drm-4.0/memory.c             drm_alloc_pages       254
mem_map_reserve(MAP_NR(addr));
4 char/drm-hp_ia64/drm_memory.h     DRM                   254
mem_map_reserve(virt_to_page(addr));
5 char/drm/drm_memory.h             DRM                   254
mem_map_reserve(virt_to_page(addr));
6 ftape/lowlevel/ftape-buffer.c     dmaalloc               54 mem_map_reserve(page);
7 media/video/bttv-driver.c         rvmalloc              185 mem_map_reserve(page);
8 media/video/cpia.c                rvmalloc              213
mem_map_reserve(vmalloc_to_page((void *)adr));
9 media/video/meye.c                rvmalloc              142
mem_map_reserve(vmalloc_to_page((void *)adr));
a media/video/planb.c               grabbuf_alloc         181
mem_map_reserve(virt_to_page(pb->rawbuf[i]));
b media/video/zr36067.c             v4l_fbuffer_alloc     307
mem_map_reserve(MAP_NR(mem + off));
c media/video/zr36067.c             jpg_fbuffer_alloc     449
mem_map_reserve(MAP_NR(mem + off));
d media/video/zr36067.c             jpg_fbuffer_alloc     467
mem_map_reserve(MAP_NR(mem));
e media/video/zr36120_mem.c         bmalloc                54
mem_map_reserve(virt_to_page(phys_to_virt(adr)));
f drivers/sound/ali5455.c           alloc_dmabuf          942 mem_map_reserve(page);
g drivers/sound/au1000.c            prog_dmabuf           637 mem_map_reserve(page);
h sound/audigy/audio.c              emu10k1_audio_mmap   1188
mem_map_reserve(MAP_NR(pgaddr));
i drivers/sound/cmpci.c             prog_dmabuf          1259
mem_map_reserve(pstart);
j sound/cs4281/cs4281_wrapper.h     cs4x_mem_map_reserve   51 #define
cs4x_mem_map_reserve(page) mem_map_reserve(page)
k drivers/sound/cs46xx_wrapper-24.h cs4x_mem_map_reserve   34 #define
cs4x_mem_map_reserve(page) mem_map_reserve(page)
l drivers/sound/dmabuf.c            sound_alloc_dmap      119 mem_map_reserve(page);
m drivers/sound/es1370.c            prog_dmabuf           587 mem_map_reserve(page);
n drivers/sound/es1371.c            prog_dmabuf           922 mem_map_reserve(page);
o drivers/sound/esssolo1.c          prog_dmabuf           452 mem_map_reserve(page);

Functions calling this function: mem_map_reserve

  File                              Function             Line
0 drivers/sound/forte.c             forte_channel_prep    698 mem_map_reserve
(page++);
1 drivers/sound/ite8172.c           prog_dmabuf           700 mem_map_reserve(page);
2 drivers/sound/maestro.c           ac97_read_mixer      2943 mem_map_reserve(page);
3 drivers/sound/maestro3.c          allocate_dmabuf      1930 mem_map_reserve(page);
4 drivers/sound/sonicvibes.c        prog_dmabuf           763 mem_map_reserve(page);
5 drivers/sound/sscape.c            sscape_alloc_dma      857 mem_map_reserve(page);
6 drivers/sound/trident.c           alloc_dmabuf         1228 mem_map_reserve(page);
7 drivers/usb/audio.c               dmabuf_init           558
mem_map_reserve(virt_to_page(p));
8 drivers/usb/ov511.c               rvmalloc              378
mem_map_reserve(vmalloc_to_page((void *)adr));
9 drivers/usb/pwc-if.c              rvmalloc              211
mem_map_reserve(vmalloc_to_page((void *)adr));
a drivers/usb/se401.c               rvmalloc              104
mem_map_reserve(vmalloc_to_page((void *)adr));
b drivers/usb/stv680.c              rvmalloc              142
mem_map_reserve(vmalloc_to_page((void *)adr));
c drivers/usb/usbvideo.c            usbvideo_rvmalloc      88
mem_map_reserve(vmalloc_to_page((void *)adr));

My point is just that I don't know how, or if it's even possible, to load the
modules and get them to do the mem_map_reserve() operation if the hardware
isn't present, or even if it were how it could be done from a user application.

The reporter's description of how he did made no sense to me, required
some special library, etc.  And if it were possible using existing RHEL3
drivers, I don't know off-hand whether it would require root privileges.

I don't do much with drivers, so again, my comment reflects that inadequacy...



Comment 12 Ernie Petrides 2005-05-26 22:51:50 UTC
Comment #9 addresses how to design a test case (which would require
root privileges to load a test module).  However, I believe that we
have existing drivers that could exhibit the vulnerability through
usage by an unprivileged user (assuming that the driver and any
related hardware is in use on a customer's system).


Comment 14 Dave Anderson 2005-06-13 18:52:44 UTC
Created attachment 115367 [details]
test module that makes a reserved page available for user mmap'ing

Comment 15 Dave Anderson 2005-06-13 18:54:16 UTC
Created attachment 115368 [details]
user program to mmap a reserved page from testmod module

Comment 16 Dave Anderson 2005-06-13 19:31:57 UTC
Proposed patch posted to rhkernel-list:

 http://post-office.corp.redhat.com/archives/rhkernel-list/2005-June/msg00423.html

Comment 17 Ernie Petrides 2005-06-15 01:08:09 UTC
A fix for this problem has just been committed to the RHEL3 U6
patch pool this evening (in kernel version 2.4.21-32.8.EL).


Comment 22 Red Hat Bugzilla 2005-09-28 14:38:04 UTC
An advisory has been issued which should help the problem
described in this bug report. This report is therefore being
closed with a resolution of ERRATA. For more information
on the solution and/or where to find the updated files,
please follow the link below. You may reopen this bug report
if the solution does not work for you.

http://rhn.redhat.com/errata/RHSA-2005-663.html