Bugtraq mailing list archives

Re: Fix for ssh-1.2.27 symlink/bind problem


From: markus.friedl () INFORMATIK UNI-ERLANGEN DE (Markus Friedl)
Date: Tue, 26 Oct 1999 21:55:21 +0200


On Mon, Oct 25, 1999 at 07:05:01PM -0400, Wietse Venema wrote:
please note, that ssh dropped support for uid-swapping beginning
with version 1.2.13:
in order to avoid leakage of the private hostkey (e.g. in core-dumps)

I was talking about seteuid(), which leaves real uid == 0, so that
the process remains protected against groping by unprivileged users.

I thought i was talking about seteuid(), too, but I may be wrong:

ssh-1.2.12 uses seteuid() for swapping of uids (saved and real uid,
maybe swapping is the wrong term, code from ssh-1.2.12 at end of message).

Since Solaris 2.3 allowed you to attach (e.g. with gdb) to a
programm running with euid==youruid, Tatu dropped the uid-swapping
code and made ssh fork into two processes:

  * The main process runs as root and reads the secret host key,
    it keeps root privileges until authentication is done.
  * A helper process runs as the user, reads the user's files and
    creates files. The main process controls this helper process
    by a binary protocol. This protocol provides no messages for the
    creation of unix domain sockets, thus the agent stealing bugs.

What was that with core dumps again? Any program that has access
to secrets such as host keys should disable core dumps; not doing
so would be negligent.

It appears from the mailinglist that not all systems supported
RLIMIT_CORE back in December 1995.

-markus

---
uid-swapping code from ssh-1.2.12:

/* Saved effective uid. */
static uid_t saved_euid = 0;

/* Temporarily changes to the given uid.  If the effective user id is not
   root, this does nothing.  This call cannot be nested. */

void temporarily_use_uid(uid_t uid)
{
#ifdef SAVED_IDS_WORK_WITH_SETEUID

  /* Save the current euid. */
  saved_euid = geteuid();

  /* Set the effective uid to the given (unprivileged) uid. */
  if (seteuid(uid) == -1)
    debug("seteuid %d: %.100s", (int)uid, strerror(errno));

#else /* SAVED_IDS_WORK_WITH_SETUID */

  /* Propagate the privileged uid to all of our uids. */
  if (setuid(geteuid()) < 0)
    debug("setuid %d: %.100s", (int)geteuid(), strerror(errno));

  /* Set the effective uid to the given (unprivileged) uid. */
  if (seteuid(uid) == -1)
    debug("seteuid %d: %.100s", (int)uid, strerror(errno));

#endif /* SAVED_IDS_WORK_WITH_SETEUID */

}

/* Restores to the original uid. */

void restore_uid()
{
#ifdef SAVED_IDS_WORK_WITH_SETEUID

  /* Set the effective uid back to the saved uid. */
  if (seteuid(saved_euid) < 0)
    debug("seteuid %d: %.100s", (int)saved_euid, strerror(errno));

#else /* SAVED_IDS_WORK_WITH_SETEUID */

  /* We are unable to restore the real uid to its unprivileged value. */
  /* Propagate the real uid (usually more privileged) to effective uid
     as well. */
  setuid(getuid());

#endif /* SAVED_IDS_WORK_WITH_SETEUID */
}

/* Permanently sets all uids to the given uid.  This cannot be called while
   temporarily_use_uid is effective. */

void permanently_set_uid(uid_t uid)
{
  if (setuid(uid) < 0)
    debug("setuid %d: %.100s", (int)uid, strerror(errno));
}



Current thread: