Bug 589478 - rpc.rquotad calls quotactl with garbage arguments
Summary: rpc.rquotad calls quotactl with garbage arguments
Alias: None
Product: Red Hat Enterprise Linux 6
Classification: Red Hat
Component: quota
Version: 6.0
Hardware: x86_64
OS: Linux
Target Milestone: rc
: ---
Assignee: Petr Pisar
QA Contact: Martin Cermak
URL: https://sourceforge.net/tracker/?func...
Whiteboard: setroubleshoot_trace_hash:750852c8561...
Depends On: 528581
TreeView+ depends on / blocked
Reported: 2010-05-06 09:25 UTC by Petr Pisar
Modified: 2010-11-10 21:28 UTC (History)
9 users (show)

Fixed In Version: quota-3.17-10.el6
Doc Type: Bug Fix
Doc Text:
Clone Of: 528581
Last Closed: 2010-11-10 21:28:13 UTC
Target Upstream Version:

Attachments (Terms of Use)

Description Petr Pisar 2010-05-06 09:25:18 UTC
+++ This bug was initially created as a clone of Bug #528581 +++


Your system may be seriously compromised! /usr/sbin/rpc.rquotad attempted to
mmap low kernel memory.

Detailed Description:

[SELinux is in permissive mode. This access was not denied.]

SELinux has denied the rpc.rquotad the ability to mmap low area of the kernel
address space. The ability to mmap a low area of the address space, as
configured by /proc/sys/kernel/mmap_min_addr. Preventing such mappings helps
protect against exploiting null deref bugs in the kernel. All applications that
need this access should have already had policy written for them. If a
compromised application tries modify the kernel this AVC would be generated.
This is a serious issue. Your system may very well be compromised.

Allowing Access:

Contact your security administrator and report this issue.

Additional Information:

Source Context                system_u:system_r:rpcd_t:s0
Target Context                system_u:system_r:rpcd_t:s0
Target Objects                None [ memprotect ]
Source                        rpc.rquotad
Source Path                   /usr/sbin/rpc.rquotad
Port                          <Unknown>
Host                          (removed)
Source RPM Packages           quota-3.17-7.fc12
Target RPM Packages           
Policy RPM                    selinux-policy-3.6.32-24.fc12
Selinux Enabled               True
Policy Type                   targeted
MLS Enabled                   True
Enforcing Mode                Permissive
Plugin Name                   mmap_zero
Host Name                     (removed)
Platform                      Linux (removed) #1 SMP Tue Sep
                              29 16:16:22 EDT 2009 x86_64 x86_64
Alert Count                   2
First Seen                    Tue 06 Oct 2009 02:49:39 PM EDT
Last Seen                     Mon 12 Oct 2009 07:43:32 PM EDT
Local ID                      63898359-96cb-46fc-a706-a30e6ba3e31a
Line Numbers                  

Raw Audit Messages            

node=(removed) type=AVC msg=audit(1255391012.132:9): avc:  denied  { mmap_zero } for  pid=1588 comm="rpc.rquotad" scontext=system_u:system_r:rpcd_t:s0 tcontext=system_u:system_r:rpcd_t:s0 tclass=memprotect

node=(removed) type=SYSCALL msg=audit(1255391012.132:9): arch=c000003e syscall=179 success=no exit=-14 a0=580500 a1=0 a2=0 a3=0 items=0 ppid=1587 pid=1588 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=4294967295 comm="rpc.rquotad" exe="/usr/sbin/rpc.rquotad" subj=system_u:system_r:rpcd_t:s0 key=(null)

Hash String generated from  selinux-policy-3.6.32-24.fc12,mmap_zero,rpc.rquotad,rpcd_t,rpcd_t,memprotect,mmap_zero
audit2allow suggests:

#============= rpcd_t ==============
allow rpcd_t self:memprotect mmap_zero;

--- Additional comment from eparis@redhat.com on 2009-10-13 12:36:35 EDT ---

reassigning to quota package, that syscall call looks like garbage....  apparently rpc.rquotad called

quotactl(0x580500, 0, 0, 0)

which doesn't seem to be a valid command....

Right shift that by SUBCMDSHIFT you get 0x5805 for the command, which certainly doesn't look like a valid quota command to me.  The selinux complaint is because the kernel (based on this erroneous command) attempted to either read or write to the address at special or addr, both of which are NULL.

the real bug here is that the syscall is being made with garbage.  garbage in garbage out...

--- Additional comment from ppisar@redhat.com on 2010-05-03 12:35:09 EDT ---

Problem located:


void init_kernel_interface(void)
    struct stat st; 
    struct sigaction sig, oldsig;

    /* This signal handling is needed because old kernels send us SIGSEGV as they try to resolve the device */
    sig.sa_handler = SIG_IGN;
    sig.sa_sigaction = NULL;
    if (sigemptyset(&sig.sa_mask) < 0)
        die(2, _("Cannot create set for sigaction(): %s\n"), strerror(errno));
    sig.sa_flags = 0;
    if (sigaction(SIGSEGV, &sig, &oldsig) < 0)
        die(2, _("Cannot set signal handler: %s\n"), strerror(errno));

    kernel_formats = 0;
    if (!stat("/proc/fs/xfs/stat", &st))
        kernel_formats |= (1 << QF_XFS);
→       if (!quotactl(QCMD(Q_XGETQSTAT, 0), NULL, 0, NULL) || (errno != EINVAL && errno != ENOSYS))
            kernel_formats |= (1 << QF_XFS);

--- Additional comment from ppisar@redhat.com on 2010-05-04 03:43:11 EDT ---

Regarding comment #1: The quotactl(0x580500, 0, 0, 0) is a valid kernel command (linux-2.6.32/fs/quota/quota.c:319).

The only real problem is NULL argv[3]. quota-tools use this dummy value to detect XFS support on running kernel. However due to ambivalent zeroth page semantics on x86 kernel sometimes returns EFAULT (if the page is unmapped), sometimes 0 if the page is mapped. Therefore mmap_minaddr check has been introduced into later kernels and into SELinux policies.

I propose to use auxiliary struct fs_quota_stat as last quotactl(2) argument to make sure (1) kernel does not overwrite occasionally mapped memory region (as happened in duplicate bug #532342) and (2) too keep in-line with modern approach zeroth page is reserved as promoted by SELinux.

I will discuss this issue with upstream.

--- Additional comment from ppisar@redhat.com on 2010-05-04 07:36:15 EDT ---

The EFAULT itself is produced earlier in quotactl(2). Kernel tries to copy second argument (name of mounted block device) into kernel space by getname() that produces EFAULT if user space source address (the second quotctl(2) argument) is NULL (if zeroth page unmapped).

We can supply "" instead of NULL. That causes ENOENT and does not trigger page fault.

The only remaining problem is I can not reproduce SELinux deny on unfixed code.

--- Additional comment from ppisar@redhat.com on 2010-05-05 08:33:27 EDT ---

Created an attachment (id=411576)
Prevent NULL region corruption

This is backported patch from upstream CVS tree too prevent write to NULL.

Remaining issues (read from NULL by kernel, zeroth page presence) are in discussion with upstream maintainer.

Comment 2 RHEL Program Management 2010-05-06 10:45:24 UTC
This request was evaluated by Red Hat Product Management for inclusion in a Red
Hat Enterprise Linux major release.  Product Management has requested further
review of this request by Red Hat Engineering, for potential inclusion in a Red
Hat Enterprise Linux Major release.  This request is not yet committed for

Comment 6 Petr Pisar 2010-05-12 13:54:37 UTC
Regarding alloca(3): On Fefora12, it's implemented as simple subtraction from stack pointer register without any checks. Even arithmetic underflow while sub is not checked. No page mapping is proceeded. Thus it can not be considered as source of (3) problem.

In addition, the alloca(3) call presents only in F-12. It's missing in RHEL-6.

Comment 16 Martin Cermak 2010-09-09 11:38:03 UTC

Comment 17 releng-rhel@redhat.com 2010-11-10 21:28:13 UTC
Red Hat Enterprise Linux 6.0 is now available and should resolve
the problem described in this bug report. This report is therefore being closed
with a resolution of CURRENTRELEASE. You may reopen this bug report if the
solution does not work for you.

Note You need to log in before you can comment on or make changes to this bug.