123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- /*
- * This little program checks whether your operating system allows a process
- * to attach to another process whose uid is only identical because it
- * revoked its privileges.
- *
- * If it detects that your operating system may be unsafe, then it's probably
- * better to avoid usage of privilege separation if untrusted users have
- * shell access.
- *
- * Compile and run with :
- *
- * make ptracetest
- * ./ptracetest
- *
- * (C)opyleft 2003-2009 Jedi/Sector One <j at pureftpd dot org>.
- */
- #include <config.h>
- #include "ftpd.h"
- #ifdef HAVE_SYS_WAIT_H
- # include <sys/wait.h>
- #endif
- #define TEST_GID 65534
- #define TEST_UID 65534
- #define ZIPPER "|/-\\ "
- #if !defined(HAVE_PTRACE) || !defined(HAVE_SYS_PTRACE_H) || !(defined(PT_ATTACH) || defined(PTRACE_ATTACH))
- int main(void)
- {
- fputs("Sorry, this test can't be compiled in this platform\n", stderr);
- return 255;
- }
- #else
- # include <sys/ptrace.h>
- int main(void)
- {
- pid_t pid;
- int rtn = 1;
- if (geteuid() != (uid_t) 0) {
- fputs("Sorry, you need to run this program as root\n", stderr);
- return 254;
- }
- if (setgid((gid_t) TEST_GID) || setegid((gid_t) TEST_GID) ||
- setuid((uid_t) TEST_UID) || seteuid((uid_t) TEST_UID)) {
- perror("Error while switching gid/uid");
- return 254;
- }
- if ((pid = fork()) == (pid_t) -1) {
- perror("Unable to fork");
- return 254;
- }
- if (pid == (pid_t) 0) {
- size_t t = (size_t) 0U;
- fputs("Checking for traceability after uid change ", stdout);
- fflush(stdout);
- do {
- putchar(ZIPPER[t]);
- putchar('\b');
- fflush(stdout);
- (void) sleep(1U);
- t++;
- } while (t < sizeof ZIPPER - (size_t) 1U);
- putchar('\n');
- _exit(0);
- } else {
- int status;
- long ret;
- # ifdef PT_ATTACH
- ret = ptrace(PT_ATTACH, pid, NULL, NULL);
- # else
- ret = ptrace(PTRACE_ATTACH, pid, NULL, NULL);
- # endif
- while (wait(&status) != pid);
- if (ret < 0L) {
- puts("\n"
- "*** YOUR OPERATING SYSTEM LOOKS SAFE ***\n"
- "\n"
- "You can probably enable privilege separation, even if\n"
- "untrusted users also have shell access.");
- rtn = 0;
- } else {
- puts("\n"
- "*** YOUR OPERATING SYSTEM MAY BE _UNSAFE_ ***\n"
- "\n"
- "Enabling privilege separation is ok as long as untrusted\n"
- "users don't have shell access.");
- }
- }
- return rtn;
- }
- #endif
|