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