summaryrefslogtreecommitdiff
path: root/sysdeps/mach
diff options
context:
space:
mode:
authorDiego Nieto Cid <dnietoc@gmail.com>2025-08-15 02:57:30 +0100
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2025-09-22 00:52:37 +0200
commit802b0eba519b1333c639fd0e1b55222099df9263 (patch)
tree54edcd609848cf84ddb4672d669b9a76ad3693cb /sysdeps/mach
parentc9cc047e9f222b20fa3704d67d46b39e3456119b (diff)
hurd: implement RLIMIT_AS against Mach RPCs
Check for VM limit RPCs * config.h.in: add #undef for HAVE_MACH_VM_GET_SIZE_LIMIT and HAVE_MACH_VM_SET_SIZE_LIMIT. * sysdeps/mach/configure.ac: use mach_RPC_CHECK to check for vm_set_size_limit and vm_get_size_limit RPCs in gnumach.defs. * sysdeps/mach/configure: regenerate file. Use vm_get_size_limit to initialize RLIMIT_AS * hurd/hurdrlimit.c(init_rlimit): use vm_get_size_limit to initialize RLIMIT_AS entry of the _hurd_rlimits array. Notify the kernel of the new VM size limits * sysdeps/mach/hurd/setrlimit.c: use the vm_set_size_limit RPC, if available, to notify the kernel of the new limits. Retry RPC calls if they were interrupted by a signal. Message-ID: <03fb90a795b354a366ee73f56f73e6ad22a86cda.1755220108.git.dnietoc@gmail.com>
Diffstat (limited to 'sysdeps/mach')
-rwxr-xr-x[-rw-r--r--]sysdeps/mach/configure60
-rw-r--r--sysdeps/mach/configure.ac4
-rw-r--r--sysdeps/mach/hurd/setrlimit.c48
3 files changed, 111 insertions, 1 deletions
diff --git a/sysdeps/mach/configure b/sysdeps/mach/configure
index 311b2dd30b..0161937ab4 100644..100755
--- a/sysdeps/mach/configure
+++ b/sysdeps/mach/configure
@@ -581,6 +581,66 @@ if test $libc_cv_mach_rpc_thread_get_name = yes; then
fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for vm_set_size_limit in gnumach.defs" >&5
+printf %s "checking for vm_set_size_limit in gnumach.defs... " >&6; }
+if test ${libc_cv_mach_rpc_vm_set_size_limit+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <mach/gnumach.defs>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP_TRADITIONAL "vm_set_size_limit" >/dev/null 2>&1
+then :
+ libc_cv_mach_rpc_vm_set_size_limit=yes
+else case e in #(
+ e) libc_cv_mach_rpc_vm_set_size_limit=no ;;
+esac
+fi
+rm -rf conftest*
+ ;;
+esac
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_mach_rpc_vm_set_size_limit" >&5
+printf "%s\n" "$libc_cv_mach_rpc_vm_set_size_limit" >&6; }
+if test $libc_cv_mach_rpc_vm_set_size_limit = yes; then
+ printf "%s\n" "#define HAVE_MACH_VM_SET_SIZE_LIMIT 1" >>confdefs.h
+
+fi
+
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for vm_get_size_limit in gnumach.defs" >&5
+printf %s "checking for vm_get_size_limit in gnumach.defs... " >&6; }
+if test ${libc_cv_mach_rpc_vm_get_size_limit+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <mach/gnumach.defs>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP_TRADITIONAL "vm_get_size_limit" >/dev/null 2>&1
+then :
+ libc_cv_mach_rpc_vm_get_size_limit=yes
+else case e in #(
+ e) libc_cv_mach_rpc_vm_get_size_limit=no ;;
+esac
+fi
+rm -rf conftest*
+ ;;
+esac
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_mach_rpc_vm_get_size_limit" >&5
+printf "%s\n" "$libc_cv_mach_rpc_vm_get_size_limit" >&6; }
+if test $libc_cv_mach_rpc_vm_get_size_limit = yes; then
+ printf "%s\n" "#define HAVE_MACH_VM_GET_SIZE_LIMIT 1" >>confdefs.h
+
+fi
+
ac_fn_c_check_header_preproc "$LINENO" "mach/machine/ndr_def.h" "ac_cv_header_mach_machine_ndr_def_h"
if test "x$ac_cv_header_mach_machine_ndr_def_h" = xyes
diff --git a/sysdeps/mach/configure.ac b/sysdeps/mach/configure.ac
index 3a6f2443e2..237b8be937 100644
--- a/sysdeps/mach/configure.ac
+++ b/sysdeps/mach/configure.ac
@@ -100,6 +100,10 @@ mach_RPC_CHECK(gnumach.defs, thread_set_name,
HAVE_MACH_THREAD_SET_NAME)
mach_RPC_CHECK(gnumach.defs, thread_get_name,
HAVE_MACH_THREAD_GET_NAME)
+mach_RPC_CHECK(gnumach.defs, vm_set_size_limit,
+ HAVE_MACH_VM_SET_SIZE_LIMIT)
+mach_RPC_CHECK(gnumach.defs, vm_get_size_limit,
+ HAVE_MACH_VM_GET_SIZE_LIMIT)
AC_CHECK_HEADER(mach/machine/ndr_def.h, [dnl
DEFINES="$DEFINES -DNDR_DEF_HEADER='<mach/machine/ndr_def.h>'"], [dnl
diff --git a/sysdeps/mach/hurd/setrlimit.c b/sysdeps/mach/hurd/setrlimit.c
index cbc172ee75..738a8a60b0 100644
--- a/sysdeps/mach/hurd/setrlimit.c
+++ b/sysdeps/mach/hurd/setrlimit.c
@@ -28,6 +28,8 @@ int
__setrlimit (enum __rlimit_resource resource, const struct rlimit *rlimits)
{
struct rlimit lim;
+ error_t err = 0;
+ mach_port_t host = MACH_PORT_NULL;
if (rlimits == NULL || (unsigned int) resource >= RLIMIT_NLIMITS)
return __hurd_fail (EINVAL);
@@ -41,13 +43,57 @@ __setrlimit (enum __rlimit_resource resource, const struct rlimit *rlimits)
if (lim.rlim_cur > lim.rlim_max)
lim.rlim_cur = lim.rlim_max;
+retry:
HURD_CRITICAL_BEGIN;
__mutex_lock (&_hurd_rlimit_lock);
+
+#ifdef HAVE_MACH_VM_SET_SIZE_LIMIT
+ if (resource == RLIMIT_AS)
+ {
+ if (host == MACH_PORT_NULL)
+ {
+ /* Check whether the privileged host control port is required */
+ if (_hurd_rlimits[resource].rlim_max < lim.rlim_max)
+ {
+ err = __get_privileged_ports (&host, NULL);
+ if (err)
+ goto fail;
+ }
+ else
+ host = __mach_host_self ();
+ }
+
+ err = __vm_set_size_limit (host, __mach_task_self (),
+ lim.rlim_cur, lim.rlim_max);
+
+ if (err == MIG_BAD_ID)
+ /* MIG_BAD_ID returned as kernel support is missing, clear error */
+ err = 0;
+ else if (err)
+ {
+ if (err == KERN_NO_ACCESS)
+ err = EPERM;
+ goto fail;
+ }
+ }
+#endif
+
_hurd_rlimits[resource] = lim;
+
+#ifdef HAVE_MACH_VM_SET_SIZE_LIMIT
+fail:
+#endif
__mutex_unlock (&_hurd_rlimit_lock);
HURD_CRITICAL_END;
- return 0;
+ if (err == EINTR)
+ /* Got a signal while inside an RPC of the critical section, retry */
+ goto retry;
+
+ if (host != MACH_PORT_NULL && host != __mach_host_self ())
+ __mach_port_deallocate (__mach_task_self (), host);
+
+ return __hurd_fail (err);
}
libc_hidden_def (__setrlimit)