Discussion:
strace -p <pid> EPERM after root process changed uid/gid to non-root user
Ole Bjorn Hessen
2012-09-28 16:11:12 UTC
Permalink
Hi,

I have a program that starts as root and changes uid/gid to a non-root
user on linux. I'd like to run strace -p on that process as non-root
but I do only get ptrace(PTRACE_ATTACH, ...): Operation not
permitted. I can send kill to that program though as that non-root user.

Anybody care to explain what magic is neccessary for a root program to
reduce priv level so that an unpriv process can strace -p that program:

Attach is a small program that changes uid from root to "news".
Try to strace that program in another window:

## in window 1

echo '
#include <sys/types.h>
#include <unistd.h>

#define UID 9
int main(char **argv, int argc) {
setresgid(UID, UID, UID);
gid_t list[2];
list[0] = UID;
list[1] = 0;
setgroups(1, list);
setresuid(UID, UID, UID);
while (1) {
sleep(1);
write(1, "hello\n", 6);
}
return 1;
}
' > /tmp/ffo.c


gcc -o /tmp/ffo /tmp/ffo.c
super sh
/tmp/ffo

## in window 2
su news
strace -p $(ps -ef | grep ffo | grep -v grep | awk '{print $2}')
attach: ptrace(PTRACE_ATTACH, ...): Operation not permitted

## kill is ok though
kill $(ps -ef | grep ffo | grep -v grep | awk '{print $2}')


--

Kind regards,

Ole Bjorn Hessen.
Telenor
----------

--
To unsubscribe from this list: send the line "unsubscribe linux-c-programming" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Ole Bjorn Hessen
2012-10-08 10:43:02 UTC
Permalink
Hi,

I got an email from Celelibi pointing me in the right direction
(thanks!).

It seems like that it is neccessary to use prctl(PR_SET_DUMPABLE, 1) to
let strace -p to work. The dumpable flag is cleared in some setuid
situations.

Linux requires that real uid of strace process matches all of real uid,
effective uid and saved uid and the real gid must match the real gid,
effective gid and saved gid. And the dumpable flag must be set.


--

#include <sys/types.h>
#include <unistd.h>
#include <sys/prctl.h>

#define UID 9
#define GID 13
int main(int argc, char **argv) {
setresgid(GID, GID, GID);
setresuid(UID, UID, UID);
prctl(PR_SET_DUMPABLE, 1);
while (1) {
sleep(1);
write(1, "hello\n", 6);
}
return 1;
}


Kind regards
Ole Bjorn Hessen.
Telenor
--
To unsubscribe from this list: send the line "unsubscribe linux-c-programming" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Loading...