[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH glibc v1] Hurd limits: implement RLIMIT_AS against Mach RPCs
From: |
dnietoc |
Subject: |
[PATCH glibc v1] Hurd limits: implement RLIMIT_AS against Mach RPCs |
Date: |
Mon, 16 Jun 2025 23:58:07 +0100 |
From: Diego Nieto Cid <dnietoc@gmail.com>
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.
---
config.h.in | 6 ++++
hurd/hurdrlimit.c | 5 +++
sysdeps/mach/configure | 60 +++++++++++++++++++++++++++++++++++
sysdeps/mach/configure.ac | 4 +++
sysdeps/mach/hurd/setrlimit.c | 57 ++++++++++++++++++++++++++++++++-
5 files changed, 131 insertions(+), 1 deletion(-)
mode change 100644 => 100755 sysdeps/mach/configure
diff --git a/config.h.in b/config.h.in
index 29126ea933..3dbb3fd6af 100644
--- a/config.h.in
+++ b/config.h.in
@@ -164,6 +164,12 @@
/* Mach specific: define if the `thread_get_name' RPC is available. */
#undef HAVE_MACH_THREAD_GET_NAME
+/* Mach specific: define if the `vm_get_size_limit' RPC is available. */
+#undef HAVE_MACH_VM_GET_SIZE_LIMIT
+
+/* Mach specific: define if the `vm_set_size_limit' RPC is available. */
+#undef HAVE_MACH_VM_SET_SIZE_LIMIT
+
/* Mach/i386 specific: define if the `i386_io_perm_*' RPCs are available. */
#undef HAVE_I386_IO_PERM_MODIFY
diff --git a/hurd/hurdrlimit.c b/hurd/hurdrlimit.c
index 6cb5045bfe..6b0d8a26a3 100644
--- a/hurd/hurdrlimit.c
+++ b/hurd/hurdrlimit.c
@@ -39,6 +39,11 @@ init_rlimit (void)
for (i = 0; i < RLIM_NLIMITS; ++i)
{
+#ifdef HAVE_MACH_VM_GET_SIZE_LIMIT
+ if (i == RLIMIT_AS)
+ __vm_get_size_limit (__mach_task_self (),
+ &_hurd_rlimits[i].rlim_cur, &_hurd_rlimits[i].rlim_max);
+#endif
if (_hurd_rlimits[i].rlim_max == 0)
_hurd_rlimits[i].rlim_max = RLIM_INFINITY;
if (_hurd_rlimits[i].rlim_cur == 0)
diff --git a/sysdeps/mach/configure b/sysdeps/mach/configure
old mode 100644
new mode 100755
index 311b2dd30b..0161937ab4
--- 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..ce01efbac8 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;
+ mach_port_t host = MACH_PORT_NULL;
if (rlimits == NULL || (unsigned int) resource >= RLIMIT_NLIMITS)
return __hurd_fail (EINVAL);
@@ -41,13 +43,66 @@ __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)
+ {
+ /* XXX initialize err to 0 for skipping error handling in
+ * non-privileged host port branch.
+ */
+ err = 0;
+
+ /* Check whether the privileged host control port is required */
+ if (_hurd_rlimits[resource].rlim_max < lim.rlim_max)
+ err = __get_privileged_ports (&host, NULL);
+ else
+ host = __mach_host_self ();
+
+ /* If we were interrupted, leave the error unchanged so cleanup code
can retry */
+ if (err == EINTR)
+ goto fail;
+
+ /* Handle any error getting the privileged ports by mapping them to
EPERM */
+ if (err)
+ {
+ err = EPERM;
+ goto fail;
+ }
+ }
+
+ err = __vm_set_size_limit (host, __mach_task_self (),
+ lim.rlim_cur, lim.rlim_max);
+
+ if (err != MIG_BAD_ID)
+ {
+ if (err)
+ goto fail;
+ }
+ else /* XXX MIG_BAD_ID returned as kernel support is missing, clear
error */
+ err = 0;
+ }
+#endif
+
_hurd_rlimits[resource] = lim;
+
+fail:
__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 err != 0 ? __hurd_fail (err) : 0;
}
libc_hidden_def (__setrlimit)
--
2.47.1
- [PATCH] Virtual Memory Limits, dnietoc, 2025/06/16
- [PATCH glibc v1] Hurd limits: implement RLIMIT_AS against Mach RPCs,
dnietoc <=
- [PATCH hurd v2] libpager: raise RLIMIT_AS if permissions allow us, dnietoc, 2025/06/16
- [PATCH gnumach v4] Implement per task virtual memory limit, dnietoc, 2025/06/16
- Re: [PATCH gnumach v4] Implement per task virtual memory limit, Samuel Thibault, 2025/06/22
- Re: [PATCH gnumach v4] Implement per task virtual memory limit, Diego Nieto Cid, 2025/06/24
- Re: [PATCH gnumach v4] Implement per task virtual memory limit, Samuel Thibault, 2025/06/24
- Re: [PATCH gnumach v4] Implement per task virtual memory limit, Diego Nieto Cid, 2025/06/24
- Re: [PATCH gnumach v4] Implement per task virtual memory limit, Samuel Thibault, 2025/06/24
- Re: [PATCH gnumach v4] Implement per task virtual memory limit, Diego Nieto Cid, 2025/06/24