ptracetest.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. /*
  2. * This little program checks whether your operating system allows a process
  3. * to attach to another process whose uid is only identical because it
  4. * revoked its privileges.
  5. *
  6. * If it detects that your operating system may be unsafe, then it's probably
  7. * better to avoid usage of privilege separation if untrusted users have
  8. * shell access.
  9. *
  10. * Compile and run with :
  11. *
  12. * make ptracetest
  13. * ./ptracetest
  14. *
  15. * (C)opyleft 2003-2009 Jedi/Sector One <j at pureftpd dot org>.
  16. */
  17. #include <config.h>
  18. #include "ftpd.h"
  19. #ifdef HAVE_SYS_WAIT_H
  20. # include <sys/wait.h>
  21. #endif
  22. #define TEST_GID 65534
  23. #define TEST_UID 65534
  24. #define ZIPPER "|/-\\ "
  25. #if !defined(HAVE_PTRACE) || !defined(HAVE_SYS_PTRACE_H) || !(defined(PT_ATTACH) || defined(PTRACE_ATTACH))
  26. int main(void)
  27. {
  28. fputs("Sorry, this test can't be compiled in this platform\n", stderr);
  29. return 255;
  30. }
  31. #else
  32. # include <sys/ptrace.h>
  33. int main(void)
  34. {
  35. pid_t pid;
  36. int rtn = 1;
  37. if (geteuid() != (uid_t) 0) {
  38. fputs("Sorry, you need to run this program as root\n", stderr);
  39. return 254;
  40. }
  41. if (setgid((gid_t) TEST_GID) || setegid((gid_t) TEST_GID) ||
  42. setuid((uid_t) TEST_UID) || seteuid((uid_t) TEST_UID)) {
  43. perror("Error while switching gid/uid");
  44. return 254;
  45. }
  46. if ((pid = fork()) == (pid_t) -1) {
  47. perror("Unable to fork");
  48. return 254;
  49. }
  50. if (pid == (pid_t) 0) {
  51. size_t t = (size_t) 0U;
  52. fputs("Checking for traceability after uid change ", stdout);
  53. fflush(stdout);
  54. do {
  55. putchar(ZIPPER[t]);
  56. putchar('\b');
  57. fflush(stdout);
  58. (void) sleep(1U);
  59. t++;
  60. } while (t < sizeof ZIPPER - (size_t) 1U);
  61. putchar('\n');
  62. _exit(0);
  63. } else {
  64. int status;
  65. long ret;
  66. # ifdef PT_ATTACH
  67. ret = ptrace(PT_ATTACH, pid, NULL, NULL);
  68. # else
  69. ret = ptrace(PTRACE_ATTACH, pid, NULL, NULL);
  70. # endif
  71. while (wait(&status) != pid);
  72. if (ret < 0L) {
  73. puts("\n"
  74. "*** YOUR OPERATING SYSTEM LOOKS SAFE ***\n"
  75. "\n"
  76. "You can probably enable privilege separation, even if\n"
  77. "untrusted users also have shell access.");
  78. rtn = 0;
  79. } else {
  80. puts("\n"
  81. "*** YOUR OPERATING SYSTEM MAY BE _UNSAFE_ ***\n"
  82. "\n"
  83. "Enabling privilege separation is ok as long as untrusted\n"
  84. "users don't have shell access.");
  85. }
  86. }
  87. return rtn;
  88. }
  89. #endif