unable to attach to setuid program that as reverted it privilege

Michael Potter
2008-01-22T20:00:09Z

Gdb Crew,

I get this error when attaching to a setuid program that has
_given_up_ its root privilege setuid(getuid()):

---------------------
x~> gdb -p 19484
GNU gdb 6.5
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and
you are
welcome to change it and/or distribute copies of it under certain
conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for
details.
This GDB was configured as "i586-suse-linux".
Attaching to process 19484
ptrace: Operation not permitted. <<<<<=================

--------------------
I will speculate that the logic behind that is even tho the program
does not have root privilege now, it could have something in left over
in memory from when it did have root privilege. I think this is a
good default behavior, but I am hopeful that some clever programmer
has found a way to change their program such that gdb can attach to
it.

My program _only_ uses root privilege to be able to be able to do a
oneway switch to a non-privileged user. I believe that any hole I am
opening up is much smaller than my next alternative which is to allow
the programmers to run gdb as root so they can attach to the program.

Suggestions on alternatives such as a way to switch users without root
privileges
are welcome.

Thanks,

For those of you who may want to reproduce this feature here are some
cut and paste ready instructions:
1) mkdir -p tmp/setuidtest;cd tmp/setuidtest
2) vim iamsetuidroot.c # paste in the following:
#include <stdio.h>
#include <stdlib.h>

int main(int arc, char *argv[])
{
if (geteuid() != 0)
{
printf("this program must be run setuid root, not %d\n",
geteuid());
exit(1);
}
if (getuid() == 0)
{
printf("this program must not be run as root\n");
exit(1);
}

setuid(getuid());

if (!setuid(0))
{
/* we want setuid to fail to be able to return to root */
printf("this program was able to revert to root\n");
exit(1);
}

printf("before the sleep %d\n", getpid());

sleep(60);

printf("after the sleep\n");

exit(0);

}

3) cc -o iamsetuidroot iamsetuidroot.c
4) sudo chown root iamsetuidroot
5) sudo chmod u+s iamsetuidroot
6) ./iamsetuidroot # observe pid in output.
7) gdb -p $thePid # in another window