Serious Attack Vector On Pkcheck Ignored By Red Hat

Home » CentOS » Serious Attack Vector On Pkcheck Ignored By Red Hat
CentOS 34 Comments

Based on an article that was mentioned on this list

I found two attacker controlled memory leaks in the option parsing of pkcheck.c. These memory leaks allow a local attacker the ability to
“spray the heap”, i.e. initialize large parts of the heap before launching his attack.

The original attack uses a setuid binary, because the author “is giving himself a break”.

However, the fact that the binary in the example is setuid is orthogonal to the fact that heap spraying is a very serious attack vector.

Bug reports are filed but closed WONTFIX. I think this is a mistake so I
would hope people could weigh in on this.

34 thoughts on - Serious Attack Vector On Pkcheck Ignored By Red Hat

  • pkcheck might not be directly vulnerable. However, pkexec is. Closing these bugs because pkcheck might not be directly vulnerable also stops pkexec from being fixed. And pkexec clearly is vulnerable.

    Regards, Leonard.

  • If that’s so, why are you supplying patches to pkcheck rather than fixing pkexec?

    If your bug report, you said, “The author clearly states that in his example exploit he gives himself a break, … choosing a more easily exploitable binary so he does not have to add a privilege escalation.”
    But that’s not true. The author used pkexec *because* it’s SUID root.
    Lots of programs can be made to crash due to memory errors. Those are bugs, but it’s only exploitable if you can cause a program that has rights other than your own to execute code on your behalf. If you cause a program with your own rights to execute code, you’re just executing code via a complicated path. It’s not a security flaw because you have the rights to execute the same code directly, rather than through a memory handling flaw.

  • The patch has a fix for three memory leaks. One memory leak that allows heap spraying in pkexec.c that according to the aforementioned article is *directly* exploitable and has been fixed upstream. (Check references I provided.)

    Two similar memory leaks exist in pkcheck.c, for which I also provided patches. Even though these might not be so easily exploitable the memory leaks in themselves allow a local attacker to “spray the heap”, which makes it easier for him to leverage an attack. You do not want to allow an attacker to have such potent tools readily available.

    Memory leaks are always bad, but these are seriously bad because they are attacker controlled.

    Regards, Leonard.

  • It took me a while to find the patch that you mentioned, which is probably why your bugs are being disregarded. Entirely too much of your existing bug reports is spent discussing a non-issue.

    If you want this issue to be taken seriously, I have a couple of pointers: First, drop the bug reports that have been closed. Those tickets are now convoluted and clouded by misguided discussion of a bug in pkcheck.c, which isn’t expoitable. Continued arguing in those bug reports will be counter-productive.

    Open a new bug report and focus on this patch, exclusively:

    The upstream developer has disallowed multiple –user specifications in order to close a memory leak. That memory leak can be used to cause the heap and the stack to run in to each other, and that flaw has previously been combined with bugs in glibc to produce an exploit. The glibc bug is now fixed, but there is still a risk that collision could be exploitable in combination with other, as yet undiscovered bugs. If Red Hat is concerned with changing the behavior of pkexec in scripts, then they can still fix the memory leak without otherwise changing the behavior of the program by adding:

    if (opt_user != NULL)

    ..instead of the upstream solution of failing on multiple –user specifications. This will correct the leak and won’t break any scripts that call –user multiple times.

    That’s it. Keep your bug report simple. Focus on the program that presents a security vulnerability due to being SUID root. Offer a solution that doesn’t break any existing user applications. Since the problem has been fixed upstream already, you don’t need any bug reports with, just with Red Hat for the polkit-112 package.

  • It is beyond my control where patches are listed in the Red Hat bugzilla pages. I don’t think the Red Hat employee involved should have a hard time finding it in my report.

    Yes. This seems to be a better solution than the one I came up with initially and which you mention below, because multiple invocations of
    –user are meaningless in this context.

    Yes. I understand perfectly well how this works, which is why I am so concerned. And that is exactly why I also want to fix those memory leaks in pkcheck.c. There might not be a known exploit for pkcheck.c but the vector (“heap spraying” because of a memory leak) is the same. That
    “heap spraying” will make it easier for an attacker to leverage any attack including a privilege escalation so it is worrisome even if the binary itself is not setuid.

    That is the initial fix I proposed, but I changed it to use the upstream fix of not allowing multiple invocations of –user. Multiple invocations of –user are pointless in this context, so I believe the upstream fix is just fine. And probably *more* acceptable for “midstream”, i.e. Red Hat. But either will do.

    I applied a similar fix to pkcheck.c, because the memory leaks are identical to the one in pkexec.c, so even though not quite as exploitable that (very powerful) vector is in that binary too.

    The argument that the binary must be setuid to make this worrisome is bogus. The vector might enable a privilege escalation because (at least on a 32-bit system) a shell user is able to initialize the entire heap with data of his liking making it way easier to mount any attack.

    Scripts shouldn’t call –user multiple times. When using the fix with g_free() only the last specification will be used.

    I think proposing a fix different from the one applied upstream (as in might also be considered “convoluting the issue”.

    The fixes I provided for upstream are for pkcheck.c only (because pkexec.c has been fixed there). Again, even though not directly
    (knowingly) exploitable allowing a shell user to heap spray *any* binary is bad. Just the fact that I have to argue that fact so extensively is troubling. Any memory leak should be fixed. A memory leak that allows a
    (local) user to entirely control the contents of the heap should be fixed immediately.

    I have no indications the fixes I supplied for pkcheck.c will not be applied upstream.

    Regards, Leonard.

  • I apologize if my intent was unclear. I was providing you with the text that you should use in your bug report. I am not explaining the problem to you, I am showing you a clear way to explain the problem in the bug report. You should use the appropriate parts of the text I provided, and basically nothing else.

    No. Stop. Drop the issue of pkcheck.c entirely. No one will listen to you as long as you continue to refer to that file. Completely stop talking about it.

    pkcheck.c executes entirely in the security context of the user’s own session. It does not have any security rights that the user does not have. The user may be able to cause it to crash or execute code, but it cannot execute any code that the user wouldn’t have been able to call on their own, directly. It is not a security flaw, because it *doesn’t change the user’s security context.* Your bugs will continue to be closed with WONTFIX until you understand that.

    I am honestly trying to help you. I would like to see the issue with pkexec.c fixed. But you have to listen to this point: causing a program to crash isn’t a security flaw unless that program operates in a different security context than your own. Crashing your own programs, within your own security context, isn’t a security flaw. It’s just a bug. Stop chasing the bug, and focus on the potential security flaw in psexec.c

  • Ok. No offense was taken :-) . But, seeing that the upstream and midstream developer are the same I think he understands the issue quite well himself. (That is, apart from the fact that the binary needs not to be setuid for this to be worrisome ;) .

    Oops, too late. I did mention it as an FYI in the new reports. But the subject is about pkexec.c only.

    I’ll try this one more time. “Heap spraying” in itself is a very powerful attack vector. It will simplify any attack on any binary that is affected. Read the article and weep. (The ridiculous value of that kernel parameter is making matters even worse, but I understand I’ll have to take up that issue elsewhere.)

    We do not need the privilege escalation in the binary. The vector will make any attack way easier, including a potential privilege escalation. So by continuing to have these memory leaks in the binary you are making it easier for a malevolent local user to mount an attack that might cause the “desired” privilege escalation.

    But I agree that to get the more serious issue fixed I should stop talking about pkcheck.c in those bug reports ;) .

    Thanks for your input.

    Regards, Leonard.

  • I’m really struggling to explain this more simply and clearly. Privilege escalation means that the attacker gains a privilege they do not start with. Right? Escalation means that you end with more than you started with.

    If a local user runs pkcheck in a manner that triggers the flaw, they might be able to cause it to execute some code. In the blog you cited, they were able to call chroot() and then system(/bin/sh). But your hypothetical malicious local user doesn’t have root privs, so they can’t call chroot(). And if they force pkcheck to call system(/bin/sh), all they’ve done is launched a shell that runs under their own uid. They don’t have to attack pkcheck to do that, they can just run /bin/sh directly.

    Escalation *requires* attacking a program in a security context other than your own. If you have a SUID binary, you can initiate the execution of code which operates in the security context of the user to which it is SUID. If you can cause it to execute arbitrary code, then you’ve escalated your privileges by gaining a new security context. You might also escalate privileges by attacking a daemon that runs in a different security context. If you can cause it to execute arbitrary code, you have your security rights plus whatever rights the daemon has. That’s an escalation. Executing new code in your own security context is not an escalation. You haven’t gained anything new. You’ve just taken a complex path to execute code that you were already allowed to execute. Does that make sense?

  • Not necessarily. Suppose the adversary is aware of a root exploit/privilege escalation in a random library. Then the heap spraying allows this attacker to easily trigger this exploit because he is able to initialize the entire contents of the heap to his liking and thus call whatever function he likes, including the one that will cause the root exploit.

    So even though the heap spraying is not an attack in itself it is a serious “crow bar” i.e. attack vector.

    If you read the article carefully the author makes no claims that the setuid on the binary is a necessity. He clearly states he is “giving himself a break” by using a setuid binary.

    Regards, Leonard.

  • if the adversary is aware of this exploit and has a login (required to invoke pkexec in the first place), they can simply execute a C program to invoke it, they don’t need to mess about with what you’re describing.

  • There are two serious problems with this argument:

    1. Give me a scenario where this attacker can execute *only* pkcheck in order to exploit this hypothetical library’s flaw, but where the attacker cannot simply provide their own binary to do the same exploit. Short of something insane like exposing pkcheck via CGI over HTTP, I don’t see how a flaw in pkcheck gives you something here that you don’t already have.

    A vulnerable library is a vulnerable library. Fix the library, don’t invent reasons to fix all the other programs on the system because the library is vulnerable.

    2. There’s no such thing as SUID libraries. So, how is this hypothetical library of yours going to gain privileges that the executable linked to it does not have? Point me at a CVE where a vulnerable library was used for privilege escalation.

    You can point at vulnerable libraries giving data exfiltration and such all day long, but privilege escalation??

  • Hello Warren,

    On many systems local users cannot execute their own uploaded binaries
    (noexec mounts). This would also be true for an adversary entering a system with a remote “unprivileged” exploit. In that situation pcheck gives them a “crow bar” they did not have before.

    I would say the modus operandi should be to eliminate all known attack vectors, including such a powerful one as the described “heap spraying”.

    I never argued there are.

    Maybe the example using a library is wrong. But there are other ways to gain a privilege escalation, kernel bugs for example. Those could be triggered just as well.

    Regards, Leonard.

    mount -t life -o ro /dev/dna /genetic/research

  • There is no such thing as a root exploit in a library. A “root exploit”
    is one that ends with the attacker executing code as root. That can only be done by attacking an existing process running as root, or by attacking a SUID binary.

    There are certainly flaws in libraries that lead to code execution, but the exploit will be described in terms of the entire system that enables privilege escalation, which means the attack will be in the context of a daemon, or a SUID binary.

    No, he doesn’t. He gave himself a break by attacking a 32-bit binary instead of the 64 bit one, because causing the heap and the stack to collide in a 64 bit address space is a *lot* more work.

    pkcheck doesn’t escalate privileges. If they are able to launch a remote exploit which calls pkcheck, they can launch a remote exploit that just calls a shell directly instead. Attacking pkcheck doesn’t give them anything extra.

    Does it not tell you anything that *everyone* is telling you that there is no security exploit in the ability to cause pkcheck to execute code?
    It’s a bug, but it’s not a security flaw.

  • So you’ve now sprayed the heap on this system, but you can’t upload anything else to it because noexec, so…now what? What has our nefarious attacker gained?

    That sounds like an esthetic argument, not a logical argument. “Heap spraying” sounds scary, so let’s fix it!

    What I want to know is, what can you *do* with a sprayed heap caused by an unprivileged executable?

    Realize that as soon as a second executable starts, it doesn’t see the sprayed heap. The kernel zeroes all reassigned memory pages. Your attack must therefore work within the pkcheck process, while that sprayed heap is still active.

    I threw that idea out in an effort to follow the Principle of Charity. ( I wasn’t required to provide the idea in the first place; the burden of proof was on you, and remains there, even though you’ve rejected my attempt to provide you with such an idea.

    Now you’re just moving the goalposts. The nature of the vulnerability does not change just because we call it a “kernel” instead of a “library”. A vulnerable kernel is a vulnerable kernel, and does not require that we fix all the other problems on the system in order to fix the kernel.

    I’m with Gordon: someone certainly should fix this problem for its own sake, but don’t try to strong-arm Red Hat into doing it for you because Security.

    Way too many bad things are done Because Security.

  • Leonard,

    I’m sure, the only way you can make your point so that others will listen to you is by providing an example of bad thing done through the flaw you have discovered. Which may be:

    1. overwriting portions of memory or filesystem belonging to another user which do not have write permission for this user

    2. elevate privileges with the help of the flaw you discovered on sane patched system, in other words not exploiting some other known vulnerabilities which on well maintained system do not exists

    This is basically the shortest and simplest way to say what others repeated several times.

    I hope, this helps.


    Valeri Galtsev Sr System Administrator Department of Astronomy and Astrophysics Kavli Institute for Cosmological Physics University of Chicago Phone: 773-702-4247

  • My larger concern is that there *does* seem to be a security issue with pkexec that has at least two very simple fixes, and that issue isn’t being addressed because of the noise involved in arguing about pkcheck.
    There’s no security problem in pkcheck, and all of the time spent insisting that there is serves to further delay fixing pkexec.

  • you realize noone on this email list has anything to do with the source code for this pkcheck thing? CentOS uses the code exactly as is that Red Hat releases. You’re tilting at windmills in the wrong country here.

  • Yes, I do. And I tried to help OP file a bug report with Red Hat so that pkexec could be fixed. His original bugs wasted a lot of time arguing about pkcheck, and were closed WONTFIX. He has since filed new bug reports which are currently ASSIGNED. I’m hopeful that those will be fixed, because there does appear to be a security flaw in a SUID
    binary installed by default on CentOS 6 and 7.

  • Hello Warren,

    So the heap is set with data provided by the (local) attacker who could initialize it to his liking using either of the two memory leaks in the options parsing.

    The heap, that is entirely under the control of the attacker, now contains a call to a library with parameters such that it invokes a zero day kernel escalation privilege exploit. And now the exploit will run because pkcheck allowed the attacker to initialize its entire heap via the command line.

    Had the two memory leaks in the pkcheck options parsing been fixed the attacker should have looked for another path to leverage his zero day.

    So the mere fact that an untrusted user is able to massage the heap of a binary (pkcheck in this case) to run whatever code he wants is a serious attack vector and thus those two memory leaks should be fixed. Because they allow bad people to leverage attacks with much more ease.

    Regards, Leonard.

    mount -t life -o ro /dev/dna /genetic/research

  • What people are trying to point out to you is:

    1. The ‘user’ that the ‘atacker’ can run things as is themselves .. AND

    2. They already have shell access on the machine in question and they can already run anything in that shell that they can run via what you are pointing out.

    3. If they have access to a zeroday issue that give them root .. they can just use that via their shell that they already have (that you gave them, which they are using) to get root .. they therefore don’t need to use this issue at all.


    All of that said, all memory leaks (and any other bugs) should be fixed.

    It is just NOT a major security issue.

  • Hello Johnny,

    No, assuming noexec /home mounts all they can run is system binaries.

    No, assuming noexec /home mounts all they have to leverage a zero day are system binaries. pkcheck to the rescue.

    Regards, Leonard.

  • Johnny Hughes wrote:
    anything else to it because noexec, so…now what? What has our nefarious attacker gained?
    initialize it to his liking using either of the two memory leaks in the options parsing. contains a call to a library with parameters such that it invokes a zero day kernel escalation privilege exploit. And now the exploit will run because pkcheck allowed the attacker to initialize its entire heap via the command line.

    I’ve skipped most of this thread, but went through this post, and excuse me if this sounds like a stupid question… but when the attacker runs their job, isn’t it *THEIR* heap, one allocated for this PID, and not any other, such as the heap allocated for PID 1?


  • Once upon a time, Leonard den Ottolander said:

    noexec is not that big of a protection. On a normal CentOS system, you almost certainly have python installed (as well as likely other scripting languages such as perl), and they can be used to do just about anything compiled code can do.

    Plus there’s /tmp, /var/tmp, and other directories (depending on software installed) that are writable by users, so unless you mount something noexec on all of them, you haven’t gained much.

    noexec is largely a legacy option at this point.

  • Indeed, perl and often python are installed on most of servers I run. Not considering myself security expert, I would like to ask: could you point to some elevation of privileges exploit written in perl or python? All I’ve seen were c/c++, but again I’m just a humble sysadmin.

    And yes, ALL user writable places (including often overlooked /dev/shm)
    are mounted with nosuid, nosgid, nodev, noexec options on servers where users are allowed to have shell. Or you should be able to do something like jail on FreeBSD which you dedicate to user shell login, and restrict it the way you need – don’t know off hand how you do it on Linux box, experts will definitely name several ways.


    Valeri Galtsev Sr System Administrator Department of Astronomy and Astrophysics Kavli Institute for Cosmological Physics University of Chicago Phone: 773-702-4247

  • Exactly. Since python is required by yum (and gettext, and systemd-sysv), it’s nearly impossible to have a CentOS system without python.

    Python, of course, includes the “ctypes” module, which allows you to load a shared object and call a C function with whatever arguments you choose.

    You *absolutely* do not need a heap spraying attack in order to make arbitrary library or kernel calls.

    Leonard, man… you’ve got let this go. Users with shell access already have fairly broad permission to execute arbitrary code on the system they log in to. The memory leak in pkcheck is *not* a security issue.
    It’s just a bug. *Everyone* is trying to tell you this, including the maintainers of CentOS, and (in your original bug report) the maintainers of RHEL. The security bug you’ve used as a foundation for all of this was built on a SUID binary, which pkcheck is not. What’s it going to take for you to accept this? Do you honestly think that you are better qualified than all of the maintainers and developers that are telling you that this isn’t a security bug?

    I really want to encourage you to stay involved as a community member.
    Free Software is a participation culture, and every contributor has the potential to make the entire system better, but participation is a two-way conversation. You’ve got to learn to listen, as well.

  • How sure are you? On the system I’m looking at right now, any user can write to:



    Notably, the “screen” and “samba” locations only appear when the respective packages are installed, so the places users can write may vary from system to system.

  • Once upon a time, Gordon Messmer said:

    Here’s the other thing about it: you are saying it might could be exploited in your setup (where other things maybe could not). That’s potentially a problem, but it is not a problem in most anybody else’s setup (most definitely not the default setup, or alternate setups from the Red Hat documentation). Red Hat generally only devotes resources to security issues in the default or documented setups; there have been CVEs where they just say “this is outside any supported setup”.

  • Once upon a time, Valeri Galtsev said:

    That wasn’t the point; the point was that users can only run system binaries so they can only do what is “permitted”. I don’t know about python, but perl can make arbitrary kernel system calls (even if they aren’t actually supported by perl), so having perl installed allows users to do anything a compiled program can do. Trying to control what users can do by mounting “noexec” is not particularly limiting, at least to somebody determined.

    So it may be harder/more cumbersome/etc., but I believe that you could write exploits in perl or python; it just isn’t commonly done in examples because of the extra work (it’s also probably harder to read).

  • Thanks for answering. Well, I have seen attempts on my systems, more than once, and they were unsuccessful, as all user writable on these two machines was mounted noexec (and also nosuid, nosgid, nodev). Of course, systems didn’t have unpatched known exploits, here we are on the same page: you have to keep your system updated. So they shouldn’t be successful even if they were executed. Still, noexec is like yet one more line of defense. Pretty much like we lock front doors of our buildings, even though we do lock doors of our apartments. Or the same as having firewall, even though you don’t have anything listening to some ports which is not supposed to. I kind of was repeated too many times by many people in my life that there is no overdoing when the security is concerned.


    Valeri Galtsev Sr System Administrator Department of Astronomy and Astrophysics Kavli Institute for Cosmological Physics University of Chicago Phone: 773-702-4247

  • I just run a bunch of find commands before rolling out system to find what I might not like, e.g. finding all world writable files…:

    find / -perm -2 ! -type l -ls

    Oh, yes, I must confess, I do not tighten up latest Linuxes, my machines that do need this level of attitude to users are FreeBSD since long ago. The last Linuxes that needed that were CentOS 5, so logically, you are right again. And on CentOS 5, as far as the following list is concerned (I
    am just marking those that did not exists there on my boxes):

    /dev/mqueue – NOT on CentOS 5
    /dev/shm – there and was mounted with noexec (and others)
    /run/user/ – NOT on CentOS 5
    /run/screen/S- – NOT on CentOS 5
    /var/spool/samba – NOT on CentOS 5 that needs extra security – in our shop;

    but there is /var/spool/mail (needs to be writable for locks if it is mbox format, not maildir)

    /home/ – mounted with noexec and friends
    /tmp – mounted with noexec and friends
    /var/tmp – mounted with noexec and friends

    And you are right again, there is a lot of hassle (and using separate partitions to have them noexec). I guess, I was not too lazy with respect to security back then (and now too, hopefully ;-)


    Valeri Galtsev Sr System Administrator Department of Astronomy and Astrophysics Kavli Institute for Cosmological Physics University of Chicago Phone: 773-702-4247

  • To be pedantic: screen definitely creates a user-writable directory on CentOS 5, in a different location, and samba will include that directory if installed. It can be really hard to make sure everything required is mounted noexec when some of these directories are automatically created by SUID or SGID binaries, in response to user actions.

  • shop;
    CentOS 5, in a different location, and samba will include that directory if installed. It can be really hard to make sure everything required is mounted noexec when some of these directories are automatically created by SUID or SGID binaries, in response to user actions.

    Sure, I agree. Screen itself is SGID group screen and no SUID. One needs to watch for places with group screen write permission, that they do not live anywhere that is not noexec mounted. And we never had SAMBA whenever we went to that length in restricting users… All in all virtualization made our lives easier (I’m using FreeBSD jails to compartmentalize immiscible things these days, I bet Linux has its lightweight equivalent, and likely more than one).


    Valeri Galtsev Sr System Administrator Department of Astronomy and Astrophysics Kavli Institute for Cosmological Physics University of Chicago Phone: 773-702-4247