bug-findutils
[Top][All Lists]
Advanced

[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 */
   }
}




reply via email to

[Prev in Thread] Current Thread [Next in Thread]