[12350] in bugtraq
Re: Fix for ssh-1.2.27 symlink/bind problem
daemon@ATHENA.MIT.EDU (Markus Friedl)
Wed Oct 27 13:42:01 1999
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Message-Id: <19991026215521.A30564@folly.informatik.uni-erlangen.de>
Date: Tue, 26 Oct 1999 21:55:21 +0200
Reply-To: Markus Friedl <markus.friedl@INFORMATIK.UNI-ERLANGEN.DE>
From: Markus Friedl <markus.friedl@INFORMATIK.UNI-ERLANGEN.DE>
X-To: Wietse Venema <wietse@porcupine.org>
To: BUGTRAQ@SECURITYFOCUS.COM
In-Reply-To: <19991025230501.34B8E45A7B@spike.porcupine.org>
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));
}