kernel: start adding functions and files for "level 2" functionality
authorAlan Cox <alan@linux.intel.com>
Sun, 27 Dec 2015 12:46:54 +0000 (12:46 +0000)
committerAlan Cox <alan@linux.intel.com>
Sun, 27 Dec 2015 12:46:54 +0000 (12:46 +0000)
This is the bigger stuff that won't fit well on a small 8bit box but which
isn't by any means essential.

Kernel/include/level2.h [new file with mode: 0644]
Kernel/level2.c [new file with mode: 0644]
Kernel/syscall_level2.c [new file with mode: 0644]

diff --git a/Kernel/include/level2.h b/Kernel/include/level2.h
new file mode 100644 (file)
index 0000000..7b3c493
--- /dev/null
@@ -0,0 +1,30 @@
+/* Resource limits only exist on LEVEL_2 systems */
+
+#define NRLIMIT                9
+
+#define RLIMIT_AS      0
+#define RLIMIT_CORE    1
+#define RLIMIT_CPU     2
+#define RLIMIT_DATA    3
+#define RLIMIT_FSIZE   4
+#define RLIMIT_NOFILE  5
+#define RLIMIT_NPROC   6
+#define RLIMIT_RSS     7
+#define RLIMIT_STACK   8
+
+typedef uint32_t rlimit_t
+
+#define RLIM_INFINITY 0xFFFFFFFFUL
+
+struct rlimit {
+    rlim_t rlim_cur;
+    rlim_t rlim_max;
+};
+
+
+extern int in_group(uint16_t gid);
+
+extern arg_t _setgroups(void);
+extern arg_t _getgroups(void);
+extern arg_t _getrlimit(void);
+extern arg_t _setrlimit(void);
diff --git a/Kernel/level2.c b/Kernel/level2.c
new file mode 100644 (file)
index 0000000..53bf780
--- /dev/null
@@ -0,0 +1,13 @@
+#include <kernel.h>
+#include <kdata.h>
+#include <printf.h>
+
+int in_group(uint16_t gid)
+{
+       uint16_t *g = udata.u_group;
+       uint16_t *p = g + udata.u_ngroup;
+       while(g < p)
+               if (*g++ == gid)
+                       return 1;
+       return 0;
+}
diff --git a/Kernel/syscall_level2.c b/Kernel/syscall_level2.c
new file mode 100644 (file)
index 0000000..06b3fa3
--- /dev/null
@@ -0,0 +1,113 @@
+#include <kernel.h>
+#include <version.h>
+#include <kdata.h>
+#include <printf.h>
+
+/*******************************************
+  setgroups (ngroup, groups)     Function ??
+  int ngroup;
+  const uint16_t *groups;
+ *******************************************/
+#define ngroup (int)udata.u_argn
+#define groups (uint16_t *)udata.u_argn1
+
+arg_t _setgroups(void)
+{
+       if (esuper())
+               return -1;
+       if (ngroup < 0 || ngroup > NGROUP) {
+               udata.u_error = EINVAL;
+               return -1
+       }
+       if (ngroup && uget(groups, udata.u_groups, ngroup * sizeof(uint16_t)))
+               return -1;
+       udata.u_ngroup = ngroup;
+       return 0;
+}
+
+#undef ngroup
+#undef groups
+
+/*******************************************
+  getgroups (ngroup, groups)     Function ??
+  int ngroup;
+  uint16_t *groups;
+ *******************************************/
+#define ngroup (int)udata.u_argn
+#define groups (uint16_t *)udata.u_argn1
+
+arg_t _getgroups(void)
+{
+       if (groups == 0)
+               return udata.u_ngroup;
+       if (ngroup < udata.u_ngroup) {
+               udata.u_error = EINVAL;
+               return;
+       }
+       if (uput(groups, udata.u_groups, ngroup * sizeof(uint16_t)) < 0)
+               return -1;
+       return udata.u_ngroup;
+}
+
+#undef ngroup
+#undef groups
+
+/*******************************************
+  getrlimit (res, rlimit)        Function ??
+  int res;
+  struct rlimit *rlim;
+ *******************************************/
+
+#define res (int)udata.u_argn
+#define rlim (struct rlimit *)udata.u_argn1
+
+arg_t _getrlimit(void)
+{
+       if (res < 0 || res >= NRLIMIT) {
+               udata.u_error = EINVAL;
+               return -1;
+       }
+       return uput(rlim, udata.u_rlimit + res, sizeof(struct rlimit));
+}
+
+#undef res
+#undef rlim
+
+/*******************************************
+  setrlimit (res, rlimit)        Function ??
+  int res;
+  const struct rlimit *rlim;
+ *******************************************/
+
+#define res (int)udata.u_argn
+#define rlim (struct rlimit *)udata.u_argn1
+
+arg_t _setrlimit(void)
+{
+       staticfast struct rlimit r;
+       struct rlimit *o;
+
+       if (res < 0 || res >= NRLIMIT)
+               goto bad;
+
+       if (uget(rlim, &r, sizeof(struct rlimit)))
+               return -1;
+
+       o = uata.u_rlimit + res;
+       if (r.rlim_cur > r.rlim_max)
+               goto bad;
+
+       /* Securit check */
+       if ((r.rlim_cur > o->rlim_max || r.rlim_max > o->rlim_max) && esuper())
+               return -1;
+       o->rlim_cur = r.rlim_cur;
+       o->rlim_max = r.rlim_max;
+       return 0;
+bad:   
+       udata.u_error = EINVAL;
+       return -1;
+}
+
+#undef res
+#undef rlim
+