Re: [PATCH] policycoreutils: preserve mode bits and ownership of /tmp in seunshare

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

 



On Thu, Sep 15, 2011 at 4:07 PM, Guido Trentalancia
<guido@xxxxxxxxxxxxxxxx> wrote:
> Hello Dave.
>
> On Thu, 2011-09-15 at 13:39 -0400, dave w wrote:
>> Hi,
>>
>> This patch addresses a flaw in seunshare.c that allows unprivileged
>> users to arbitrarily modify the contents of /tmp.  This bug is further
>> described in CVE 2011-1011
>> (http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2011-1011):
>
> seunshare should not be installed by default and, even if it still
> needed to be installed by default, its setuid bit should be carefully
> re-evaluated in my opinion.
>

Perhaps, but distros that install seunshare at present will be made
safer with the addition of a patch which eliminates an attack vector
to a privilege escalation.

> In any case, good practice says nothing should ever be allowed to mount
> under /tmp with suid/exec flags (use noexec,nosuid options in fstab).
>
> That said, have you tested the patch already ? Is it effective ?
>

Yes, the patch has been effective and with it applied, unprivileged
users cannot delete files other than their own from /tmp, which is the
expected behavior in a directory with the sticky bit set owned by the
superuser.

> Thanks.
>
> Guido
>
>> The seunshare_mount function in sandbox/seunshare.c in seunshare in certain
>> Red Hat packages of policycoreutils 2.0.83 and earlier in Red Hat
>> Enterprise Linux (RHEL) 6 and earlier, and Fedora 14 and earlier, mounts a
>> new directory on top of /tmp without assigning root ownership and the
>> sticky bit to this new directory, which allows local users to replace or
>> delete arbitrary /tmp files, and consequently cause a denial of service or
>> possibly gain privileges, by running a setuid application that relies on
>> /tmp, as demonstrated by the ksu application
>>
>> This patch preserves the mode bits, and thus permissions, and
>> ownership of the destination directory of the bind mount performed by
>> seunshare.  The permission check in verify_mount() was relaxed for
>> directories who originally had the sticky bit set, as root ownership
>> is required for these to ensure that unprivileged users cannot unlink
>> arbitrary files in the newly bind mounted directory.
>>
>> Thanks,
>> David
>>
>>
>>
>>  policycoreutils/sandbox/seunshare.c |   23 ++++++++++++++++++++++-
>>  1 files changed, 22 insertions(+), 1 deletions(-)
>>
>> diff --git a/policycoreutils/sandbox/seunshare.c
>> b/policycoreutils/sandbox/seunshare.c
>> index f9bf12c..82b3cb9 100644
>> --- a/policycoreutils/sandbox/seunshare.c
>> +++ b/policycoreutils/sandbox/seunshare.c
>> @@ -149,7 +149,9 @@ static int verify_mount(const char *mntdir, struct
>> passwd *pwd) {
>>         fprintf(stderr, _("Invalid mount point %s: %s\n"), mntdir,
>> strerror(errno));
>>         return -1;
>>     }
>> -   if (sb.st_uid != pwd->pw_uid) {
>> +
>> +    /* Owners don't have to match if the sticky bit has been set. */
>> +   if (sb.st_uid != pwd->pw_uid && !(sb.st_mode && S_ISVTX)) {
>>         errno = EPERM;
>>         syslog(LOG_AUTHPRIV | LOG_ALERT, "%s attempted to mount an
>> invalid directory, %s", pwd->pw_name, mntdir);
>>         perror(_("Invalid mount point, reporting to administrator"));
>> @@ -245,8 +247,17 @@ static int verify_shell(const char *shell_name)
>>  }
>>
>>  static int seunshare_mount(const char *src, const char *dst, struct
>> passwd *pwd) {
>> +    struct stat buf;
>> +
>>     if (verbose)
>>         printf("Mount %s on %s\n", src, dst);
>> +
>> +    /* Preserve mode bits and ownership */
>> +    if (stat(dst, &buf) < 0) {
>> +        fprintf(stderr, _("Failed to stat %s: %s\n"), dst, strerror(errno));
>> +        return -1;
>> +    }
>> +
>>     if (mount(dst, dst,  NULL, MS_BIND | MS_REC, NULL) < 0) {
>>         fprintf(stderr, _("Failed to mount %s on %s: %s\n"), dst, dst,
>> strerror(errno));
>>         return -1;
>> @@ -262,6 +273,16 @@ static int seunshare_mount(const char *src, const
>> char *dst, struct passwd *pwd)
>>         return -1;
>>     }
>>
>> +    /* Restore original mode bits and ownership */
>> +    if (chmod(dst, buf.st_mode) < 0) {
>> +        fprintf(stderr, _("Failed to set permissions on %s: %s\n"),
>> dst, strerror(errno));
>> +        return -1;
>> +    }
>> +    if (chown(dst, buf.st_uid, buf.st_gid) < 0) {
>> +        fprintf(stderr, _("Failed to set ownership on %s: %s\n"),
>> dst, strerror(errno));
>> +        return -1;
>> +    }
>> +
>>     if (verify_mount(dst, pwd) < 0)
>>         return -1;
>>  }
>
>
>


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@xxxxxxxxxxxxx with
the words "unsubscribe selinux" without quotes as the message.


[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux