|
@@ -24,32 +24,56 @@
|
|
|
*/
|
|
|
|
|
|
#include <shim_internal.h>
|
|
|
+#include <shim_checkpoint.h>
|
|
|
#include <shim_table.h>
|
|
|
#include <shim_utils.h>
|
|
|
#include <shim_vma.h>
|
|
|
|
|
|
#include <asm/resource.h>
|
|
|
|
|
|
-unsigned int max_fds = DEFAULT_MAX_FDS;
|
|
|
|
|
|
-int shim_do_getrlimit (int resource, struct __kernel_rlimit * rlim)
|
|
|
-{
|
|
|
- switch (resource) {
|
|
|
- case RLIMIT_NOFILE:
|
|
|
- rlim->rlim_cur = max_fds;
|
|
|
- rlim->rlim_max = MAX_MAX_FDS;
|
|
|
- return 0;
|
|
|
+/*
|
|
|
+ * TODO: implement actual limitation on each resource.
|
|
|
+ *
|
|
|
+ * The current behavor(i.e. sys_stack_size, brk_max_size) may be subject
|
|
|
+ * to be fixed.
|
|
|
+ */
|
|
|
|
|
|
- case RLIMIT_RSS:
|
|
|
- rlim->rlim_cur = RLIM_INFINITY;
|
|
|
- rlim->rlim_max = RLIM_INFINITY;
|
|
|
- return 0;
|
|
|
+#define _STK_LIM (8*1024*1024)
|
|
|
+#define MAX_THREADS (0x3fffffff / 2)
|
|
|
+#define DEFAULT_MAX_FDS (1024)
|
|
|
+#define MAX_MAX_FDS (65536) /* 4096: Linux initial value */
|
|
|
+#define MLOCK_LIMIT (64*1024)
|
|
|
+#define MQ_BYTES_MAX 819200
|
|
|
+
|
|
|
+struct __kernel_rlimit __rlim[RLIM_NLIMITS] __attribute_migratable = {
|
|
|
+ [RLIMIT_CPU] = { RLIM_INFINITY, RLIM_INFINITY },
|
|
|
+ [RLIMIT_FSIZE] = { RLIM_INFINITY, RLIM_INFINITY },
|
|
|
+ /* For now __rlim[RLIMIT_DATA] isn't used. See the implementation */
|
|
|
+ [RLIMIT_DATA] = { RLIM_INFINITY, RLIM_INFINITY },
|
|
|
+ /* For now __rlim[RLIMIT_STACK] isn't used. See the implementation */
|
|
|
+ [RLIMIT_STACK] = { _STK_LIM, RLIM_INFINITY },
|
|
|
+ [RLIMIT_CORE] = { 0, RLIM_INFINITY },
|
|
|
+ [RLIMIT_RSS] = { RLIM_INFINITY, RLIM_INFINITY },
|
|
|
+ [RLIMIT_NPROC] = { MAX_THREADS, MAX_THREADS },
|
|
|
+ [RLIMIT_NOFILE] = { DEFAULT_MAX_FDS, MAX_MAX_FDS },
|
|
|
+ [RLIMIT_MEMLOCK] = { MLOCK_LIMIT, MLOCK_LIMIT },
|
|
|
+ [RLIMIT_AS] = { RLIM_INFINITY, RLIM_INFINITY },
|
|
|
+ [RLIMIT_LOCKS] = { RLIM_INFINITY, RLIM_INFINITY },
|
|
|
+ /* [RLIMIT_SIGPENDING] = [RLIMIT_NPROC] for initial value */
|
|
|
+ [RLIMIT_SIGPENDING] = { MAX_THREADS, MAX_THREADS },
|
|
|
+ [RLIMIT_MSGQUEUE] = { MQ_BYTES_MAX, MQ_BYTES_MAX },
|
|
|
+ [RLIMIT_NICE] = { 0, 0 },
|
|
|
+ [RLIMIT_RTPRIO] = { 0, 0 },
|
|
|
+ [RLIMIT_RTTIME] = { RLIM_INFINITY, RLIM_INFINITY },
|
|
|
+};
|
|
|
|
|
|
- case RLIMIT_AS:
|
|
|
- rlim->rlim_cur = RLIM_INFINITY;
|
|
|
- rlim->rlim_max = RLIM_INFINITY;
|
|
|
- return 0;
|
|
|
+int shim_do_getrlimit (int resource, struct __kernel_rlimit * rlim)
|
|
|
+{
|
|
|
+ if (resource < 0 || RLIM_NLIMITS <= resource)
|
|
|
+ return -EINVAL;
|
|
|
|
|
|
+ switch (resource) {
|
|
|
case RLIMIT_STACK:
|
|
|
rlim->rlim_cur = sys_stack_size;
|
|
|
rlim->rlim_max = sys_stack_size;
|
|
@@ -57,28 +81,33 @@ int shim_do_getrlimit (int resource, struct __kernel_rlimit * rlim)
|
|
|
|
|
|
case RLIMIT_DATA:
|
|
|
rlim->rlim_cur = brk_max_size;
|
|
|
- rlim->rlim_max = RLIM_INFINITY;
|
|
|
+ rlim->rlim_max = __rlim[resource].rlim_max;
|
|
|
return 0;
|
|
|
|
|
|
default:
|
|
|
- return -ENOSYS;
|
|
|
+ *rlim = __rlim[resource];
|
|
|
+ return 0;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
int shim_do_setrlimit (int resource, struct __kernel_rlimit * rlim)
|
|
|
{
|
|
|
+ if (resource < 0 || RLIM_NLIMITS <= resource)
|
|
|
+ return -EINVAL;
|
|
|
+ if (!rlim || test_user_memory(rlim, sizeof(*rlim), false))
|
|
|
+ return -EFAULT;
|
|
|
+ if (rlim->rlim_cur > rlim->rlim_max)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ if (rlim->rlim_cur > __rlim->rlim_max)
|
|
|
+ return -EINVAL;
|
|
|
switch (resource) {
|
|
|
- case RLIMIT_NOFILE:
|
|
|
- if (rlim->rlim_cur > MAX_MAX_FDS)
|
|
|
- return -EINVAL;
|
|
|
- max_fds = rlim->rlim_cur;
|
|
|
- return 0;
|
|
|
-
|
|
|
case RLIMIT_STACK:
|
|
|
sys_stack_size = rlim->rlim_cur;
|
|
|
return 0;
|
|
|
|
|
|
default:
|
|
|
- return -ENOSYS;
|
|
|
+ __rlim[resource].rlim_cur = rlim->rlim_cur;
|
|
|
+ return 0;
|
|
|
}
|
|
|
}
|