Re: setuid/setgid binaries contained in the Debian repository.
Hi,
On Mon, Aug 11, 2003 at 05:32:23PM -0400, Matt Zimmerman wrote:
> On Mon, Aug 11, 2003 at 10:30:24PM +0200, Emile van Bergen wrote:
>
> > On Mon, Aug 11, 2003 at 04:14:36PM -0400, Matt Zimmerman wrote:
> > > allocated for every game. And what have we gained? The ability to share a
> > > file with other users.
> >
> > No, a sandbox for every game. Every sandbox requires a uid. This is a
> > problem why?
>
> Complexity.
Let me then ask this first. Do you want the game to run with the full
privileges of the user invoking it? If no, then you need a sandbox per
game in some form or another.
Using a different uid for a process is the simplest and strongest form
of sandbox imaginable.
> > All other solutions require traversing the kernel. Now we traverse a
> > userspace wrapper. Is there any fundamental difference?
>
> How does your proposed solution avoid the kernel?
It avoids having to put the one-way trapdoor feature in the kernel.
[SNIP]
> I was talking about the current state of affairs in Debian, not about a
> hypothetical solution. What I described is what we do _today_ in Debian
> (the problem).
Yes, and it seems you prefer to keep talking about the problem than
talking about solutions. I haven't heard any viable alternative from
you so far.
> > > I personally don't care one whit about impersonating high scores.
> > > I do care about the security of my system.
> >
> > I do too. I don't trust game code. I don't want it to access my
> > $HOME at all. Have it use /var/games/<game>/$USER. My solution
> > allows that.
>
> Moving data to /var/games is possible without setuid operation, as
> well, if it is desirable.
Sure, but moving is not an end in itself, but a means to and end, the
end being the ability to remove the need for access to the user's ~.
> > > And $LOGNAME. And then make sure that none of the programs that
> > > you're wrapping will break, because they use getpwuid() or
> > > getlogin() or cuserid() or any other method which uses the uid.
> >
> > Fine, they see the game user. This is bad why?
>
> Because then the game doesn't work correctly.
Then you patch it. It only has to happen at one point; instead of
'getuid()' you need to use another bit of information ($UID or
something); the rest goes on as normal.
Really, this is less complex than any client server solution, a
mandatory library, or taking advantage of some hot shot kernel feature.
> > > nethack, for example, uses the process uid in order to name its
> > > save files, and changing this would necessitate migration of
> > > existing games. Of course, that needs to be done very carefully
> > > in order to avoid making it possible to exploit root from the
> > > games uid through filesystem-based attacks.
> >
> > There is no games uid, there is only a 'nethack' uid and gid. This
> > uid and gid cannot attack anything. The consequence is that ~/.game
> > must be moved to /var/games/<game>/<user>. This is a trivial change.
>
> I think you misunderstood my scenario. The migration of the game
> files would typically be done by the maintainer scripts, with root
> privileges. It was an example of additional risks which are
> introduced by adding complexity. In this case, a migration is
> required, and secure migration in that situation is not necessarily
> trivial or obvious to the package maintainer.
*Any* solution to the age-old setgid games problem will require some
migration. We'll have to live with either the age-old problem or a
migration. I don't care which will happen, but don't complain that a
solution needs a migration. It's not a problem with *this* particular
solution.
> (nethack, the example game, already stores its saved games under
> /var/lib/games/nethack)
That's excellent; then only the trivial getuid() -> atoi(getenv("UID"))
patch remains.
- pwent = getpwuid(getuid());
+ envuid = getenv("UID");
+ pwent = getpwuid((envuid && getgid() == getegid()) ? atoi(envuid) : getuid());
if (!pwent) { perror("getpwuid"); _exit(1); }
username = pwent->pw_name;
fullname = pwent->pw_gecos;
if (fullname) { s = strchr(fullname, ','); if (s) *s = 0; }
else fullname = username;
...
Note that this also ignores UID if the game is installed setgid, to
prevent impersonating other players. (Only a user that has been given
login gid 'games' can cheat this way, but that's a feature, not a bug
;-).
Cheers,
Emile.
--
E-Advies - Emile van Bergen emile@e-advies.nl
tel. +31 (0)70 3906153 http://www.e-advies.nl
Reply to: