From f382d2a376b87b714fdfba3a6c390cf3df8fcc97 Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Fri, 27 Jan 2012 21:37:13 +0400 Subject: [PATCH] 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 Signed-off-by: Cyrill Gorcunov --- include/proc_parse.h | 13 ++++++ proc_parse.c | 96 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+) diff --git a/include/proc_parse.h b/include/proc_parse.h index 9e26fddf9..145cea140 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 66dcaa429..ebe1c908c 100644 --- a/proc_parse.c +++ b/proc_parse.c @@ -6,6 +6,7 @@ #include #include #include +#include #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; +}