Hi,

This patch adds the key "process name" to find a matching rule.

By this patch, cgroup_change_cgroup_uid_gid_flags() gets a process
name by the parameter "pid" internally and uses it to find a matching
rule.


Thanks
Ken'ichi Ohmichi
 
Signed-off-by: Ken'ichi Ohmichi <[email protected]>
---
 src/api.c |   60 +++++++++++++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 47 insertions(+), 13 deletions(-)

diff --git a/src/api.c b/src/api.c
index 3e063cb..ba39280 100644
--- a/src/api.c
+++ b/src/api.c
@@ -286,10 +286,12 @@ static char *cg_skip_unused_charactors_in_rule(char *rule)
  *     @param cache True to cache rules, else false
  *     @param muid If cache is false, the UID to match against
  *     @param mgid If cache is false, the GID to match against
+ *     @param mprocname If cache is false, the process name to match against
  *     @return 0 on success, -1 if no cache and match found, > 0 on error.
  * TODO: Make this function thread safe!
  */
-static int cgroup_parse_rules(bool cache, uid_t muid, gid_t mgid)
+static int cgroup_parse_rules(bool cache, uid_t muid, gid_t mgid,
+                               char *mprocname)
 {
        /* File descriptor for the configuration file */
        FILE *fp = NULL;
@@ -486,8 +488,20 @@ static int cgroup_parse_rules(bool cache, uid_t muid, 
gid_t mgid)
                        matched = true;
                }
 
-               if (!cache && !matched)
-                       continue;
+               if (!cache) {
+                       if (!matched)
+                               continue;
+                       if (len_procname) {
+                               /*
+                                * If there is a rule based on process name,
+                                * it should be matched with mprocname.
+                                */
+                               if (!mprocname)
+                                       continue;
+                               if (strncmp(mprocname, procname, len_procname))
+                                       continue;
+                       }
+               }
 
                /*
                 * Now, we're either caching rules or we found a match.  Either
@@ -1805,11 +1819,12 @@ static int cg_prepare_cgroup(struct cgroup *cgroup, 
pid_t pid,
  * This function may NOT be thread safe.
  *     @param uid The UID to match
  *     @param gid The GID to match
+ *     @param procname The process name to match
  *     @return Pointer to the first matching rule, or NULL if no match
  * TODO: Determine thread-safeness and fix if not safe.
  */
-static struct cgroup_rule *cgroup_find_matching_rule_uid_gid(const uid_t uid,
-                               const gid_t gid)
+static struct cgroup_rule *cgroup_find_matching_rule(const uid_t uid,
+                       const gid_t gid, const char *procname)
 {
        /* Return value */
        struct cgroup_rule *ret = rl.head;
@@ -1827,20 +1842,21 @@ static struct cgroup_rule 
*cgroup_find_matching_rule_uid_gid(const uid_t uid,
        int i = 0;
 
        pthread_rwlock_wrlock(&rl_lock);
+retry:
        while (ret) {
                /* The wildcard rule always matches. */
                if ((ret->uid == CGRULE_WILD) && (ret->gid == CGRULE_WILD)) {
-                       goto finished;
+                       goto found_uid_gid_rule;
                }
 
                /* This is the simple case of the UID matching. */
                if (ret->uid == uid) {
-                       goto finished;
+                       goto found_uid_gid_rule;
                }
 
                /* This is the simple case of the GID matching. */
                if (ret->gid == gid) {
-                       goto finished;
+                       goto found_uid_gid_rule;
                }
 
                /* If this is a group rule, the UID might be a member. */
@@ -1861,7 +1877,7 @@ static struct cgroup_rule 
*cgroup_find_matching_rule_uid_gid(const uid_t uid,
                        /* If UID is a member of group, we matched. */
                        for (i = 0; grp->gr_mem[i]; i++) {
                                if (!(strcmp(usr->pw_name, grp->gr_mem[i])))
-                                       goto finished;
+                                       goto found_uid_gid_rule;
                        }
                }
 
@@ -1872,6 +1888,16 @@ static struct cgroup_rule 
*cgroup_find_matching_rule_uid_gid(const uid_t uid,
        /* If we get here, no rules matched. */
        ret = NULL;
 
+found_uid_gid_rule:
+       if (ret && procname) {
+               if (!ret->procname)
+                       /* If no process name in a rule, that means wildcard */
+                       goto finished;
+               if (!strcmp(ret->procname, procname))
+                       goto finished;
+               ret = ret->next;
+               goto retry;
+       }
 finished:
        pthread_rwlock_unlock(&rl_lock);
        return ret;
@@ -1900,6 +1926,9 @@ int cgroup_change_cgroup_uid_gid_flags(const uid_t uid, 
const gid_t gid,
        /* Temporary pointer to a rule */
        struct cgroup_rule *tmp = NULL;
 
+       /* Buffer of process name */
+       char procname[TASK_COMM_LEN] = { '\0' };
+
        /* Return codes */
        int ret = 0;
 
@@ -1909,6 +1938,10 @@ int cgroup_change_cgroup_uid_gid_flags(const uid_t uid, 
const gid_t gid,
                ret = ECGROUPNOTINITIALIZED;
                goto finished;
        }
+       ret = cgroup_get_procdata_from_status(pid, NULL, NULL,
+                                               procname, sizeof(procname));
+       if (ret)
+               goto finished;
 
        /* 
         * If the user did not ask for cached rules, we must parse the
@@ -1917,7 +1950,7 @@ int cgroup_change_cgroup_uid_gid_flags(const uid_t uid, 
const gid_t gid,
         */
        if (!(flags & CGFLAG_USECACHE)) {
                cgroup_dbg("Not using cached rules for PID %d.\n", pid);
-               ret = cgroup_parse_rules(false, uid, gid);
+               ret = cgroup_parse_rules(false, uid, gid, procname);
 
                /* The configuration file has an error!  We must exit now. */
                if (ret != -1 && ret != 0) {
@@ -1937,7 +1970,7 @@ int cgroup_change_cgroup_uid_gid_flags(const uid_t uid, 
const gid_t gid,
                tmp = trl.head;
        } else {
                /* Find the first matching rule in the cached list. */
-               tmp = cgroup_find_matching_rule_uid_gid(uid, gid);
+               tmp = cgroup_find_matching_rule(uid, gid, procname);
                if (!tmp) {
                        cgroup_dbg("No rule found to match PID: %d, UID: %d, "
                                "GID: %d\n", pid, uid, gid);
@@ -2084,7 +2117,8 @@ int cgroup_reload_cached_rules()
        int ret = 0;
 
        cgroup_dbg("Reloading cached rules from %s.\n", CGRULES_CONF_FILE);
-       if ((ret = cgroup_parse_rules(true, CGRULE_INVALID, CGRULE_INVALID))) {
+       ret = cgroup_parse_rules(true, CGRULE_INVALID, CGRULE_INVALID, NULL);
+       if (ret) {
                cgroup_dbg("Error parsing configuration file \"%s\": %d.\n",
                        CGRULES_CONF_FILE, ret);
                ret = ECGROUPPARSEFAIL;
@@ -2109,7 +2143,7 @@ int cgroup_init_rules_cache()
        int ret = 0;
 
        /* Attempt to read the configuration file and cache the rules. */
-       ret = cgroup_parse_rules(true, CGRULE_INVALID, CGRULE_INVALID);
+       ret = cgroup_parse_rules(true, CGRULE_INVALID, CGRULE_INVALID, NULL);
        if (ret) {
                cgroup_dbg("Could not initialize rule cache, error was: %d\n",
                        ret);

------------------------------------------------------------------------------
Register Now for Creativity and Technology (CaT), June 3rd, NYC. CaT
is a gathering of tech-side developers & brand creativity professionals. Meet
the minds behind Google Creative Lab, Visual Complexity, Processing, & 
iPhoneDevCamp asthey present alongside digital heavyweights like Barbarian
Group, R/GA, & Big Spaceship. http://www.creativitycat.com 
_______________________________________________
Libcg-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/libcg-devel

Reply via email to