# It is expected that running a systemtap script will fail for normal users > /usr/bin/stap -e 'probe begin { printf("hello\n"); exit() }' Copy failed ("/tmp/stap7JpfJ9/stap_0a799d701652d96117065a219429e3fa_284.ko" to "/home/scox/.systemtap/cache/0a/stap_0a799d701652d96117065a219429e3fa_284.ko"): Permission denied ERROR: You are trying to run stap as a normal user. # However recent versions of stap incorrectly succeed for normal users > stap -V SystemTap translator/driver (version 0.7.1/0.135 git branch master, commit e071e49b) > id uid=2558(scox) gid=2563(scox) groups=2563(scox) # stap complains about caching but otherwise the script seems to work okay # stap -e 'probe process("/bin/ls").end {printf("in probe process")}' Copy failed ("/tmp/stapd07mpW/stap_cdf5233cb3f66091de60800627346256_233.ko" to "/home/scox/.systemtap/cache/cd/stap_cdf5233cb3f66091de60800627346256_233.ko"): Permission denied in probe processin probe process^C> > /usr/local/bin/stap -e 'probe begin { printf("hello\n"); exit() }' Copy failed ("/tmp/stapXuiEoI/stap_a525970ce776d4cd67c058513e04a605_303.ko" to "/home/scox/.systemtap/cache/a5/stap_a525970ce776d4cd67c058513e04a605_303.ko"): Permission denied hello
Assuming I ran "git bisect" correctly, the following commits are when this behaviour started: 6fa7bd6e70f8f6d783395399c92a9a13d24ce997 337cd273963410c9a1fa46b10287e72c146df054 (There are 2 commits since the tree doesn't compile after the first commit.) Here are the log entries from those commits: Author: Frank Ch. Eigler <fche@elastic.org> Date: Fri Sep 5 13:02:37 2008 -0400 remove capability logic It was only barely beneficial anyway, since some crucial capabilities were never permanently dropped. Author: Frank Ch. Eigler <fche@elastic.org> Date: Fri Sep 5 13:02:56 2008 -0400 remove capabilities logic, cont'd Now to figure out why removing the capability logic allows anyone to run systemtap...
Originally, staprun.c:main() called cap.c:init_cap(), which did the following: void init_cap(void) { uid_t uid = getuid(); gid_t gid = getgid(); ... if (setresuid(uid, uid, uid) < 0) ferror("setresuid"); if (setresgid(gid, gid, gid) < 0) ferror("setresgid"); } Which basically set the effective and saved user/group ids to the real user/group id. Then, staprun.c:main() called staprun_funcs.c:check_permissions() int check_permissions(void) { /* If we're root, we can do anything. */ if (geteuid() == 0) return 1; ... } Without the code in init_cap(), the euid of staprun is always 0, since staprun is setuid 0. Changing that 'geteuid()' call to 'getuid()' seems to fix the problem. Fixed in commit 0387bde.
Thanks for finding and fixing this brown-paper-bag bug of mine.