[CRIU] [PATCH 1/3] kerndat: add has_loginuid to kerndat_s
Dmitry Safonov
dsafonov at odin.com
Wed Dec 23 05:47:36 PST 2015
This value will differ on C/R:
- on checkpoint it means that it's possible to dump logiuid values;
- on restore it means that it's possible to unset loginuid and write
saved value to unsetted loginuid.
Signed-off-by: Dmitry Safonov <dsafonov at odin.com>
---
cr-restore.c | 19 -------------------
include/kerndat.h | 2 ++
include/proc_parse.h | 1 +
kerndat.c | 37 +++++++++++++++++++++++++++++++++++++
proc_parse.c | 19 +++++++++++++++++++
5 files changed, 59 insertions(+), 19 deletions(-)
diff --git a/cr-restore.c b/cr-restore.c
index 9fc1e3d..52d70a9 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -860,25 +860,6 @@ static int prepare_oom_score_adj(int value)
return ret;
}
-static int prepare_loginuid(unsigned int value)
-{
- int fd, ret = 0;
- char buf[11]; /* 4294967295 is maximum for u32 */
-
- fd = open_proc_rw(PROC_SELF, "loginuid");
- if (fd < 0)
- return -1;
-
- snprintf(buf, 11, "%u", value);
-
- if (write(fd, buf, 11) < 0) {
- pr_perror("Write %s to /proc/self/loginuid failed", buf);
- ret = -1;
- }
- close(fd);
- return ret;
-}
-
static int prepare_proc_misc(pid_t pid, TaskCoreEntry *tc)
{
int ret;
diff --git a/include/kerndat.h b/include/kerndat.h
index e76b0d2..5cc1003 100644
--- a/include/kerndat.h
+++ b/include/kerndat.h
@@ -14,6 +14,7 @@ extern int kerndat_init(void);
extern int kerndat_init_rst(void);
extern int kerndat_get_dirty_track(void);
extern int kerndat_fdinfo_has_lock(void);
+extern int kerndat_loginuid(bool only_dump);
struct kerndat_s {
dev_t shmem_dev;
@@ -25,6 +26,7 @@ struct kerndat_s {
bool has_fdinfo_lock;
unsigned long task_size;
bool ipv6;
+ bool has_loginuid;
};
extern struct kerndat_s kdat;
diff --git a/include/proc_parse.h b/include/proc_parse.h
index b0bdac5..d65a4a8 100644
--- a/include/proc_parse.h
+++ b/include/proc_parse.h
@@ -122,6 +122,7 @@ extern struct mount_info *parse_mountinfo(pid_t pid, struct ns_id *nsid, bool fo
extern int parse_pid_stat(pid_t pid, struct proc_pid_stat *s);
extern unsigned int parse_pid_loginuid(pid_t pid, int *err);
extern int parse_pid_oom_score_adj(pid_t pid, int *err);
+extern int prepare_loginuid(unsigned int value);
extern int parse_smaps(pid_t pid, struct vm_area_list *vma_area_list);
extern int parse_self_maps_lite(struct vm_area_list *vms);
extern int parse_pid_status(pid_t pid, struct proc_status_creds *);
diff --git a/kerndat.c b/kerndat.c
index 5b9df83..d4d2abd 100644
--- a/kerndat.c
+++ b/kerndat.c
@@ -19,6 +19,7 @@
#include "cr_options.h"
#include "util.h"
#include "lsm.h"
+#include "proc_parse.h"
struct kerndat_s kdat = {
/*
@@ -348,6 +349,38 @@ static int get_ipv6()
return 0;
}
+int kerndat_loginuid(bool only_dump)
+{
+ unsigned int saved_loginuid;
+ int ret;
+
+ kdat.has_loginuid = false;
+
+ /* No such file, or perm fault: CONFIG_AUDITSYSCALL disabled */
+ saved_loginuid = parse_pid_loginuid(getpid(), &ret);
+ if (ret < 0)
+ return 0;
+
+ if (only_dump) {
+ kdat.has_loginuid = true;
+ return 0;
+ }
+
+ /*
+ * From kernel v3.13-rc2 it's possible to unset loginuid value,
+ * on that rely dump/restore code.
+ * See also: marc.info/?l=git-commits-head&m=138509506407067
+ */
+ if (prepare_loginuid(INVALID_UID) < 0)
+ return 0;
+ /* Cleaning value back as it was */
+ if (prepare_loginuid(saved_loginuid) < 0)
+ return 0;
+
+ kdat.has_loginuid = true;
+ return 0;
+}
+
int kerndat_init(void)
{
int ret;
@@ -365,6 +398,8 @@ int kerndat_init(void)
ret = get_task_size();
if (!ret)
ret = get_ipv6();
+ if (!ret)
+ ret = kerndat_loginuid(true);
kerndat_lsm();
@@ -390,6 +425,8 @@ int kerndat_init_rst(void)
ret = get_task_size();
if (!ret)
ret = get_ipv6();
+ if (!ret)
+ ret = kerndat_loginuid(false);
kerndat_lsm();
diff --git a/proc_parse.c b/proc_parse.c
index 2eef21a..fa3f0d3 100644
--- a/proc_parse.c
+++ b/proc_parse.c
@@ -724,6 +724,25 @@ err:
return -1;
}
+int prepare_loginuid(unsigned int value)
+{
+ int fd, ret = 0;
+ char buf[11]; /* 4294967295 is maximum for u32 */
+
+ fd = open_proc_rw(PROC_SELF, "loginuid");
+ if (fd < 0)
+ return -1;
+
+ snprintf(buf, 11, "%u", value);
+
+ if (write(fd, buf, 11) < 0) {
+ pr_perror("Write %s to /proc/self/loginuid failed", buf);
+ ret = -1;
+ }
+ close(fd);
+ return ret;
+}
+
unsigned int parse_pid_loginuid(pid_t pid, int *err)
{
int fd;
--
2.6.4
More information about the CRIU
mailing list