1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230
|
commit 802b0eba519b1333c639fd0e1b55222099df9263
Author: Diego Nieto Cid <dnietoc@gmail.com>
Date: Fri Aug 15 02:57:30 2025 +0100
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>
commit 7ebac6bf9438a4338497a2e80cdcdffdd91c2542
Author: Samuel Thibault <samuel.thibault@ens-lyon.org>
Date: Tue Sep 23 21:38:46 2025 +0200
hurd: Fix building on i686-gnu
vm_size_t and rlim_t may not be the same type.
Fixes commit 802b0eba519b1333c639fd0e1b55222099df9263
("hurd: implement RLIMIT_AS against Mach RPCs")
---
config.h.in | 6 ++++
hurd/hurdrlimit.c | 9 ++++++
sysdeps/mach/configure | 60 ++++++++++++++++++++++++++++++++++++++++++
sysdeps/mach/configure.ac | 4 ++
sysdeps/mach/hurd/setrlimit.c | 48 ++++++++++++++++++++++++++++++++-
5 files changed, 126 insertions(+), 1 deletion(-)
--- 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
--- a/hurd/hurdrlimit.c
+++ b/hurd/hurdrlimit.c
@@ -37,6 +37,15 @@ init_rlimit (void)
__mutex_init (&_hurd_rlimit_lock);
+#ifdef HAVE_MACH_VM_GET_SIZE_LIMIT
+ vm_size_t current, max;
+ if (__vm_get_size_limit (__mach_task_self (), ¤t, &max) == KERN_SUCCESS)
+ {
+ _hurd_rlimits[RLIMIT_AS].rlim_cur = current;
+ _hurd_rlimits[RLIMIT_AS].rlim_max = max;
+ }
+#endif
+
for (i = 0; i < RLIM_NLIMITS; ++i)
{
if (_hurd_rlimits[i].rlim_max == 0)
--- a/sysdeps/mach/configure
+++ b/sysdeps/mach/configure
@@ -581,6 +581,66 @@ if test $libc_cv_mach_rpc_thread_get_nam
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
--- a/sysdeps/mach/configure.ac
+++ b/sysdeps/mach/configure.ac
@@ -100,6 +100,10 @@ mach_RPC_CHECK(gnumach.defs, thread_set_
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
--- 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 reso
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)
|