summaryrefslogtreecommitdiffstats
path: root/src/daemon/cgrulesengd.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/daemon/cgrulesengd.c')
-rw-r--r--src/daemon/cgrulesengd.c107
1 files changed, 47 insertions, 60 deletions
diff --git a/src/daemon/cgrulesengd.c b/src/daemon/cgrulesengd.c
index 4e00e18..74d12e1 100644
--- a/src/daemon/cgrulesengd.c
+++ b/src/daemon/cgrulesengd.c
@@ -132,15 +132,7 @@ void flog(int level, const char *format, ...)
}
}
-/**
- * Process an event from the kernel, and determine the correct UID/GID/PID to
- * pass to libcgroup. Then, libcgroup will decide the cgroup to move the PID
- * to, if any.
- * @param ev The event to process
- * @param type The type of event to process (part of ev)
- * @return 0 on success, > 0 on failure
- */
-int cgre_process_event(const struct proc_event *ev, const int type)
+static int cgre_get_euid_egid_from_status(pid_t pid, uid_t *euid, gid_t *egid)
{
/* Handle for the /proc/PID/status file */
FILE *f;
@@ -149,19 +141,13 @@ int cgre_process_event(const struct proc_event *ev, const int type)
char path[FILENAME_MAX];
/* Temporary buffer */
- char *buf = NULL;
+ char buf[4092];
/* UID data */
- uid_t ruid, euid, suid, fsuid, log_uid = 0;
+ uid_t ruid, suid, fsuid;
/* GID data */
- gid_t rgid, egid, sgid, fsgid, log_gid = 0;
-
- /* PID, just for logging */
- pid_t log_pid = 0;
-
- /* Return codes */
- int ret = 0;
+ gid_t rgid, sgid, fsgid;
/*
* First, we need to open the /proc/PID/status file so that we can
@@ -169,76 +155,79 @@ int cgre_process_event(const struct proc_event *ev, const int type)
* on. This process is probably not us, so we can't just call
* geteuid() or getegid().
*/
- sprintf(path, "/proc/%d/status", ev->event_data.id.process_pid);
+ sprintf(path, "/proc/%d/status", pid);
f = fopen(path, "r");
if (!f) {
flog(LOG_WARNING, "Failed to open %s", path);
- goto finished;
+ return 1;
}
- /* Now, we need to find either the eUID or the eGID of the process. */
- buf = calloc(4096, sizeof(char));
- if (!buf) {
- flog(LOG_WARNING, "Failed to process event, out of"
- "memory? Error: %s",
- strerror(errno));
- ret = errno;
- fclose(f);
- goto finished;
+ /* Have the eUID, need to find the eGID. */
+ memset(buf, '\0', sizeof(buf));
+ while (fgets(buf, sizeof(buf), f)) {
+ if (!strncmp(buf, "Uid:", 4)) {
+ sscanf((buf + 5), "%d%d%d%d", &ruid, euid,
+ &suid, &fsuid);
+ break;
+ } else if (!strncmp(buf, "Gid:", 4)) {
+ sscanf((buf + 5), "%d%d%d%d", &rgid, egid,
+ &sgid, &fsgid);
+ break;
+ }
+ memset(buf, '\0', sizeof(buf));
}
+ fclose(f);
+ return 0;
+}
+
+/**
+ * Process an event from the kernel, and determine the correct UID/GID/PID to
+ * pass to libcgroup. Then, libcgroup will decide the cgroup to move the PID
+ * to, if any.
+ * @param ev The event to process
+ * @param type The type of event to process (part of ev)
+ * @return 0 on success, > 0 on failure
+ */
+int cgre_process_event(const struct proc_event *ev, const int type)
+{
+ pid_t pid = 0, log_pid = 0;
+ uid_t euid, log_uid = 0;
+ gid_t egid, log_gid = 0;
+
+ int ret = 0;
+
switch (type) {
case PROC_EVENT_UID:
- /* Have the eUID, need to find the eGID. */
- while (fgets(buf, 4096, f)) {
- if (!strncmp(buf, "Gid:", 4)) {
- sscanf((buf + 5), "%d%d%d%d", &rgid, &egid,
- &sgid, &fsgid);
- break;
- }
- memset(buf, '\0', 4096);
- }
- break;
case PROC_EVENT_GID:
- /* Have the eGID, need to find the eUID. */
- while (fgets(buf, 4096, f)) {
- if (!strncmp(buf, "Uid:", 4)) {
- sscanf((buf + 5), "%d%d%d%d", &ruid, &euid,
- &suid, &fsuid);
- break;
- }
- memset(buf, '\0', 4096);
- }
+ pid = ev->event_data.id.process_pid;
break;
default:
- flog(LOG_WARNING, "For some reason, we're processing a"
- " non-UID/GID event. Something is wrong!");
break;
}
- free(buf);
- fclose(f);
+ if (cgre_get_euid_egid_from_status(pid, &euid, &egid))
+ /* cgre_get_euid_egid_from_status() returns 1 if it fails to
+ * open /proc/<pid>/status file and that is not a problem. */
+ return 0;
/*
* Now that we have the UID, the GID, and the PID, we can make a call
* to libcgroup to change the cgroup for this PID.
*/
+ log_pid = pid;
switch (type) {
case PROC_EVENT_UID:
log_uid = ev->event_data.id.e.euid;
log_gid = egid;
- log_pid = ev->event_data.id.process_pid;
ret = cgroup_change_cgroup_uid_gid_flags(
ev->event_data.id.e.euid,
- egid, ev->event_data.id.process_pid,
- CGFLAG_USECACHE);
+ egid, pid, CGFLAG_USECACHE);
break;
case PROC_EVENT_GID:
log_uid = euid;
log_gid = ev->event_data.id.e.egid;
- log_pid = ev->event_data.id.process_pid;
ret = cgroup_change_cgroup_uid_gid_flags(euid,
ev->event_data.id.e.egid,
- ev->event_data.id.process_pid,
- CGFLAG_USECACHE);
+ pid, CGFLAG_USECACHE);
break;
default:
break;
@@ -256,8 +245,6 @@ int cgre_process_event(const struct proc_event *ev, const int type)
flog(LOG_INFO, "Cgroup change for PID: %d, UID: %d, GID: %d OK",
log_pid, log_uid, log_gid);
}
-
-finished:
return ret;
}