[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: findutils-4.3.2: core dump when run as root on Solaris 10 SPARC
From: |
James Youngman |
Subject: |
Re: findutils-4.3.2: core dump when run as root on Solaris 10 SPARC |
Date: |
Thu, 1 Mar 2007 10:54:19 +0000 |
On 3/1/07, Nelson H. F. Beebe <address@hidden> wrote:
The findutils-4.3.2 locate utility dumps core when run as root on
Solaris 10 SPARC:
I can't yet explain the core dump inside error(). As far as I can
see, we are not calling it incorrectly. Addressing the initial
problem though, please try this version of drop_privs() instead.
static int
drop_privs(void)
{
const char * what = "failed";
const uid_t orig_euid = geteuid();
const uid_t uid = getuid();
const gid_t gid = getgid();
/* Use of setgroups() is restrcted to root only. */
if (0 == orig_euid)
{
/* UID != 0, but EUID == 0. We're running setuid-root. */
gid_t groups[1];
groups[1] = getgid();
if (0 != setgroups(1, groups))
{
what = _("failed to drop group privileges");
goto fail;
}
}
/* Drop any setuid privileges */
if (uid != orig_euid)
{
if (0 == uid)
{
/* We're really root anyway, but are setuid to something else. Leave
it. */
}
else
{
errno = 0;
if (0 != setuid(getuid()))
{
what = _("failed to drop setuid privileges");
goto fail;
}
/* Defend against the case where the attacker runs us with the
* capability to call setuid() turned off, which on some systems
* will cause the above attempt to drop privileges fail (leaving us
* privileged).
*/
else
{
/* Check that we can no longer switch bask to root */
if (0 == setuid(0))
{
what = _("Failed to fully drop privileges");
/* The errno value here is not interesting (since
* the system call we are complaining about
* succeeded when we wanted it to fail). Arrange
* for the call to error() not to print the errno
* value by setting errno=0.
*/
errno = 0;
goto fail;
}
}
}
}
/* Drop any setgid privileges */
errno = 0;
if (0 != setgid(gid))
{
what = _("failed to drop setgid privileges");
goto fail;
}
/* success. */
return 0;
fail:
error(1, errno, "%s", what);
abort();
kill(0, SIGKILL);
_exit(1);
/*NOTREACHED*/
/* ... we hope. */
for (;;)
{
/* deliberate infinite loop */
}
}