1# -*- Autoconf -*-
2
3# SYNOPSIS
4#
5#   AX_CHECK_UTS_NAMESPACE
6#
7# DESCRIPTION
8#
9#   This macro checks whether the local system supports Linux UTS namespaces.
10#   Also requires user namespaces to be available, so that non-root users
11#   can enter the namespace.
12#   If so, it calls AC_DEFINE(HAVE_UTS_NAMESPACE).
13#
14# Copyright (C) The c-ares team
15# SPDX-License-Identifier: MIT
16
17AC_DEFUN([AX_CHECK_UTS_NAMESPACE],[dnl
18 AC_CACHE_CHECK([whether UTS namespaces are supported],
19  ax_cv_uts_namespace,[
20  AC_LANG_PUSH([C])
21  AC_RUN_IFELSE([AC_LANG_SOURCE([[
22#define _GNU_SOURCE
23#include <sched.h>
24#include <signal.h>
25#include <stdio.h>
26#include <string.h>
27#include <fcntl.h>
28#include <unistd.h>
29#include <sys/types.h>
30#include <sys/wait.h>
31
32int utsfn(void *d) {
33  char buffer[1024];
34  const char *name = "autoconftest";
35  int rc = sethostname(name, strlen(name));
36  if (rc != 0) return 1;
37  gethostname(buffer, 1024);
38  return (strcmp(buffer, name) != 0);
39}
40
41char st2[1024*1024];
42int fn(void *d) {
43  pid_t child;
44  int rc, status;
45  usleep(100000);  /* synchronize by sleep */
46  if (getuid() != 0) return 1;
47  child = clone(utsfn, st2 + 1024*1024, CLONE_NEWUTS|SIGCHLD, 0);
48  if (child < 0) return 1;
49  rc = waitpid(child, &status, 0);
50  if (rc <= 0) return 1;
51  if (!WIFEXITED(status)) return 1;
52  return WEXITSTATUS(status);
53}
54char st[1024*1024];
55int main() {
56  char buffer[1024];
57  int rc, status, fd;
58  pid_t child = clone(fn, st + 1024*1024, CLONE_NEWUSER|SIGCHLD, 0);
59  if (child < 0) return 1;
60
61  snprintf(buffer, sizeof(buffer), "/proc/%d/uid_map", child);
62  fd = open(buffer, O_CREAT|O_WRONLY|O_TRUNC, 0755);
63  snprintf(buffer, sizeof(buffer), "0 %d 1\n", getuid());
64  write(fd, buffer, strlen(buffer));
65  close(fd);
66
67  rc = waitpid(child, &status, 0);
68  if (rc <= 0) return 1;
69  if (!WIFEXITED(status)) return 1;
70  return WEXITSTATUS(status);
71}
72]])
73  ],[ax_cv_uts_namespace=yes],[ax_cv_uts_namespace=no],[ax_cv_uts_namespace=no])
74 AC_LANG_POP([C])
75 ])
76 if test "$ax_cv_uts_namespace" = yes; then
77   AC_DEFINE([HAVE_UTS_NAMESPACE],[1],[Whether UTS namespaces are available])
78 fi
79]) # AX_CHECK_UTS_NAMESPACE
80