ax_check_user_namespace.m4 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. # -*- Autoconf -*-
  2. # SYNOPSIS
  3. #
  4. # AX_CHECK_USER_NAMESPACE
  5. #
  6. # DESCRIPTION
  7. #
  8. # This macro checks whether the local system supports Linux user namespaces.
  9. # If so, it calls AC_DEFINE(HAVE_USER_NAMESPACE).
  10. AC_DEFUN([AX_CHECK_USER_NAMESPACE],[dnl
  11. AC_CACHE_CHECK([whether user namespaces are supported],
  12. ax_cv_user_namespace,[
  13. AC_LANG_PUSH([C])
  14. AC_RUN_IFELSE([AC_LANG_SOURCE([[
  15. #define _GNU_SOURCE
  16. #include <fcntl.h>
  17. #include <sched.h>
  18. #include <signal.h>
  19. #include <stdio.h>
  20. #include <string.h>
  21. #include <sys/types.h>
  22. #include <sys/wait.h>
  23. int userfn(void *d) {
  24. usleep(100000); /* synchronize by sleep */
  25. return (getuid() != 0);
  26. }
  27. char userst[1024*1024];
  28. int main() {
  29. char buffer[1024];
  30. int rc, status, fd;
  31. pid_t child = clone(userfn, userst + 1024*1024, CLONE_NEWUSER|SIGCHLD, 0);
  32. if (child < 0) return 1;
  33. sprintf(buffer, "/proc/%d/uid_map", child);
  34. fd = open(buffer, O_CREAT|O_WRONLY|O_TRUNC, 0755);
  35. sprintf(buffer, "0 %d 1\n", getuid());
  36. write(fd, buffer, strlen(buffer));
  37. close(fd);
  38. rc = waitpid(child, &status, 0);
  39. if (rc <= 0) return 1;
  40. if (!WIFEXITED(status)) return 1;
  41. return WEXITSTATUS(status);
  42. }
  43. ]])],[ax_cv_user_namespace=yes],[ax_cv_user_namespace=no],[ax_cv_user_namespace=no])
  44. AC_LANG_POP([C])
  45. ])
  46. if test "$ax_cv_user_namespace" = yes; then
  47. AC_DEFINE([HAVE_USER_NAMESPACE],[1],[Whether user namespaces are available])
  48. fi
  49. ]) # AX_CHECK_USER_NAMESPACE