Selaa lähdekoodia

[LibOS] Accept all rlimit resources for [gs]etrlimit()

Accept all rlimit resource types to satisfy applications.
There is no actual restriction on all resource types except
RLIMIT_STACK and RLIMIT_DATA.

This commit also adds error handling in [gs]etrlimit().
Isaku Yamahata 5 vuotta sitten
vanhempi
commit
d357ab9a26

+ 3 - 4
LibOS/shim/include/shim_handle.h

@@ -39,6 +39,7 @@
 #include <linux/un.h>
 
 #include <asm/fcntl.h>
+#include <asm/resource.h>
 
 /* start definition of shim handle */
 enum shim_handle_type {
@@ -383,10 +384,6 @@ struct shim_fd_handle {
     struct shim_handle * handle;
 };
 
-#define MAX_MAX_FDS         (65536)
-#define DEFAULT_MAX_FDS     (1024)
-extern unsigned int max_fds;
-
 struct shim_handle_map {
     /* the top of created file descriptors */
     FDTYPE      fd_size;
@@ -436,4 +433,6 @@ ssize_t get_file_size (struct shim_handle * file);
 int do_handle_read (struct shim_handle * hdl, void * buf, int count);
 int do_handle_write (struct shim_handle * hdl, const void * buf, int count);
 
+extern struct __kernel_rlimit __rlim[RLIM_NLIMITS];
+
 #endif /* _SHIM_HANDLE_H_ */

+ 1 - 1
LibOS/shim/src/fs/proc/thread.c

@@ -241,7 +241,7 @@ static int parse_thread_fd (const char * name, const char ** rest,
         if (*p < '0' || *p > '9')
             return -ENOENT;
         fd = fd * 10 + *p - '0';
-        if (fd >= max_fds)
+        if (fd >= __rlim[RLIMIT_NOFILE].rlim_cur)
             return -ENOENT;
     }
 

+ 54 - 25
LibOS/shim/src/sys/shim_getrlimit.c

@@ -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;
     }
 }