[CRIU] [crtools-bot] proc_parse: Routine for reading creds from /proc/pid/status

Cyrill Gorcunov gorcunov at openvz.org
Mon Jan 30 04:00:18 EST 2012


The commit is pushed to "master" and will appear on git://github.com/cyrillos/crtools.git
------>
commit f382d2a376b87b714fdfba3a6c390cf3df8fcc97
Author: Pavel Emelyanov <xemul at openvz.org>
Date:   Fri Jan 27 21:37:13 2012 +0400

    proc_parse: Routine for reading creds from /proc/pid/status
    
    All the IDs and caps are in there. Just read them for future use.
    
    Signed-off-by: Pavel Emelyanov <xemul at parallels.com>
    Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
 include/proc_parse.h |   13 +++++++
 proc_parse.c         |   96 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 109 insertions(+), 0 deletions(-)

diff --git a/include/proc_parse.h b/include/proc_parse.h
index 9e26fdd..145cea1 100644
--- a/include/proc_parse.h
+++ b/include/proc_parse.h
@@ -59,7 +59,20 @@ struct proc_pid_stat {
 	int			exit_code;
 };
 
+#define PROC_CAP_SIZE	2
+
+struct proc_status_creds {
+	unsigned int uids[4];
+	unsigned int gids[4];
+
+	unsigned int cap_inh[PROC_CAP_SIZE];
+	unsigned int cap_prm[PROC_CAP_SIZE];
+	unsigned int cap_eff[PROC_CAP_SIZE];
+	unsigned int cap_bnd[PROC_CAP_SIZE];
+};
+
 extern int parse_pid_stat(pid_t pid, int pid_dir, struct proc_pid_stat *s);
 extern int parse_maps(pid_t pid, int pid_dir, struct list_head *vma_area_list, bool use_map_files);
+extern int parse_pid_status(int pid_dir, struct proc_status_creds *);
 
 #endif /* PROC_PARSE_H__ */
diff --git a/proc_parse.c b/proc_parse.c
index 66dcaa4..ebe1c90 100644
--- a/proc_parse.c
+++ b/proc_parse.c
@@ -6,6 +6,7 @@
 #include <dirent.h>
 #include <errno.h>
 #include <sys/stat.h>
+#include <string.h>
 
 #include "types.h"
 #include "list.h"
@@ -258,3 +259,98 @@ int parse_pid_stat(pid_t pid, int pid_dir, struct proc_pid_stat *s)
 
 	return 0;
 }
+
+static int ids_parse(char *str, unsigned int *arr)
+{
+	char *end;
+
+	arr[0] = strtol(str, &end, 10);
+	arr[1] = strtol(end + 1, &end, 10);
+	arr[2] = strtol(end + 1, &end, 10);
+	arr[3] = strtol(end + 1, &end, 10);
+	if (*end != '\n')
+		return -1;
+	else
+		return 0;
+}
+
+static int cap_parse(char *str, unsigned int *res)
+{
+	int i, ret;
+
+	for (i = 0; i < PROC_CAP_SIZE; i++) {
+		ret = sscanf(str, "%08x", &res[PROC_CAP_SIZE - 1 - i]);
+		if (ret != 1)
+			return -1;
+		str += 8;
+	}
+
+	return 0;
+}
+
+int parse_pid_status(int pid_dir, struct proc_status_creds *cr)
+{
+	int done = 0;
+	FILE *f;
+	char str[64];
+
+	f = fopen_proc(pid_dir, "status");
+	if (f == NULL) {
+		pr_perror("Can't open proc status\n");
+		return -1;
+	}
+
+	while (done < 6 && fgets(str, sizeof(str), f)) {
+		if (!strncmp(str, "Uid:", 4)) {
+			if (ids_parse(str + 5, cr->uids))
+				goto err_parse;
+
+			done++;
+		}
+
+		if (!strncmp(str, "Gid:", 4)) {
+			if (ids_parse(str + 5, cr->gids))
+				goto err_parse;
+
+			done++;
+		}
+
+		if (!strncmp(str, "CapInh:", 7)) {
+			if (cap_parse(str + 8, cr->cap_inh))
+				goto err_parse;
+
+			done++;
+		}
+
+		if (!strncmp(str, "CapEff:", 7)) {
+			if (cap_parse(str + 8, cr->cap_eff))
+				goto err_parse;
+
+			done++;
+		}
+
+		if (!strncmp(str, "CapPrm:", 7)) {
+			if (cap_parse(str + 8, cr->cap_prm))
+				goto err_parse;
+
+			done++;
+		}
+
+		if (!strncmp(str, "CapBnd:", 7)) {
+			if (cap_parse(str + 8, cr->cap_bnd))
+				goto err_parse;
+
+			done++;
+		}
+	}
+
+	if (done != 6) {
+err_parse:
+		pr_err("Error parsing proc status file\n");
+		fclose(f);
+		return -1;
+	}
+
+	fclose(f);
+	return 0;
+}


More information about the CRIU mailing list