[CRIU] [PATCH] security: set suid flag on crtools and check real uid on dump/restore
Ruslan Kuprieiev
kupruser at gmail.com
Wed Oct 2 06:00:48 PDT 2013
Hi!
Lets set suid flag on crtools, so non-root users could dump/restore
their own tasks and start service for their own tasks. On start criu
will get it's real uid and will allow user to dump/restore only tasks
that he own.
Signed-off-by: Ruslan Kuprieiev <kupruser at gmail.com>
-------------- next part --------------
---
diff --git a/Makefile b/Makefile
index 0834277..8c75e92 100644
--- a/Makefile
+++ b/Makefile
@@ -166,6 +166,7 @@ PROGRAM-BUILTINS += $(ARCH_DIR)/vdso-pie.o
$(PROGRAM): $(SYSCALL-LIB) $(ARCH-LIB) $(PROGRAM-BUILTINS)
$(E) " LINK " $@
$(Q) $(CC) $(CFLAGS) $^ $(LIBS) $(LDFLAGS) -o $@
+ $(Q) chmod u+s $@
zdtm: all
$(Q) $(MAKE) -C test/zdtm all
diff --git a/cr-restore.c b/cr-restore.c
index 3debcbe..8c7389c 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -1957,6 +1957,9 @@ static int prepare_creds(int pid, struct task_restore_core_args *args)
return -1;
}
+ if (!may_restore_uid(ce->uid))
+ return -1;
+
args->creds = *ce;
args->creds.cap_inh = args->cap_inh;
memcpy(args->cap_inh, ce->cap_inh, sizeof(args->cap_inh));
diff --git a/cr-service.c b/cr-service.c
index d1286c3..38543e7 100644
--- a/cr-service.c
+++ b/cr-service.c
@@ -87,7 +87,8 @@ static int setup_dump_from_req(int sk, CriuDumpReq *req)
return -1;
}
- restrict_uid(ids.uid);
+ if (restrict_uid(ids.uid) < 0)
+ return -1;
if (fstat(sk, &st)) {
pr_perror("Can't get socket stat");
diff --git a/crtools.c b/crtools.c
index ebab052..83948e9 100644
--- a/crtools.c
+++ b/crtools.c
@@ -72,6 +72,7 @@ int main(int argc, char *argv[])
BUILD_BUG_ON(PAGE_SIZE != PAGE_IMAGE_SIZE);
cr_pb_init();
+ security_init();
if (argc < 2)
goto usage;
diff --git a/include/crtools.h b/include/crtools.h
index 8f84f94..b197a40 100644
--- a/include/crtools.h
+++ b/include/crtools.h
@@ -208,7 +208,9 @@ static inline bool pid_rst_prio(unsigned pid_a, unsigned pid_b)
return pid_a < pid_b;
}
-void restrict_uid(unsigned int uid);
+void security_init(void);
+int restrict_uid(unsigned int uid);
bool may_dump_uid(unsigned int uid);
+bool may_restore_uid(unsigned int uid);
#endif /* __CR_CRTOOLS_H__ */
diff --git a/security.c b/security.c
index caf9dda..40e4b59 100644
--- a/security.c
+++ b/security.c
@@ -2,7 +2,8 @@
#include "crtools.h"
#include "log.h"
-static unsigned int dumper_uid = 0;
+static unsigned int cr_uid; /* "Effective" uid, which is used in C/R */
+static unsigned int ruid; /* Real uid of the user, which runs criu */
/*
* Setup what user is requesting for dump (via rpc or using
@@ -11,19 +12,56 @@ static unsigned int dumper_uid = 0;
* access to. (Or implement some trickier security policy).
*/
-void restrict_uid(unsigned int uid)
+void security_init()
{
- pr_info("Restrict C/R with %u uid\n", uid);
- dumper_uid = uid;
+ ruid = getuid();
+ cr_uid = ruid;
}
-bool may_dump_uid(unsigned int uid)
+int restrict_uid(unsigned int uid)
+{
+ if (ruid == 0) {
+ pr_info("Restrict C/R with %u uid\n", uid);
+ cr_uid = uid;
+ return 0;
+ }
+ if (cr_uid == uid) {
+ pr_info("C/R is already restricted with %u uid\n", uid);
+ return 0;
+ }
+
+ pr_perror("User(%u uid) has no right to restrict C/R with %u uid\n",
+ ruid, uid);
+ return -1;
+}
+
+
+static bool check_uid(unsigned int uid)
{
- if (dumper_uid == 0)
+ if (cr_uid == 0)
return true;
- if (dumper_uid == uid)
+ if (cr_uid == uid)
return true;
- pr_err("UID (%u) != dumper's UID(%u)\n", uid, dumper_uid);
return false;
}
+
+bool may_dump_uid(unsigned int uid)
+{
+ if (!check_uid(uid)) {
+ pr_err("UID (%u) != dumper's UID(%u)\n", uid, cr_uid);
+ return false;
+ }
+
+ return true;
+}
+
+bool may_restore_uid(unsigned int uid)
+{
+ if (!check_uid(uid)) {
+ pr_err("UID (%u) != restorer's UID(%u)\n", uid, cr_uid);
+ return false;
+ }
+
+ return true;
+}
More information about the CRIU
mailing list