Ken'ichi Ohmichi wrote:
> Hi,
> 
> This patch adds the parser of process name in /etc/cgrules.conf.
> 
> A new rule based on process name is as the following, and the process
> name is stored into the member "procname" in struct cgroup_rule.
>   <user>:<process name>  <controllers>   <destination>
> 
> 
> Thanks
> Ken'ichi Ohmichi
>  
> Signed-off-by: Ken'ichi Ohmichi <[email protected]>
> ---
>  include/libcgroup.h      |    7 ++++++-
>  src/api.c                |   43 +++++++++++++++++++++++++++++++++++++++----
>  src/libcgroup-internal.h |    1 +
>  3 files changed, 46 insertions(+), 5 deletions(-)
> 
> diff --git a/include/libcgroup.h b/include/libcgroup.h
> index 7db02d4..10b41aa 100644
> --- a/include/libcgroup.h
> +++ b/include/libcgroup.h
> @@ -48,9 +48,14 @@ __BEGIN_DECLS
>   * would require us to use a scanner/parser that can parse beyond ASCII
>   */
>  
> +/* Task command name length (from linux-2.6.29) */
> +#define TASK_COMM_LEN                16
> +
> +/* Maximum length of a key(<user>:<process name>) in the daemon config file 
> */
> +#define CGROUP_RULE_MAXKEY   (LOGIN_NAME_MAX + TASK_COMM_LEN + 1)
>  
>  /* Maximum length of a line in the daemon config file */
> -#define CGROUP_RULE_MAXLINE (FILENAME_MAX + LOGIN_NAME_MAX + \
> +#define CGROUP_RULE_MAXLINE  (FILENAME_MAX + CGROUP_RULE_MAXKEY + \
>       CG_CONTROLLER_MAX + 3)
>  
>  /* Definitions for the uid and gid members of a cgroup_rules */
> diff --git a/src/api.c b/src/api.c
> index 0739642..3e063cb 100644
> --- a/src/api.c
> +++ b/src/api.c
> @@ -206,7 +206,10 @@ static void cgroup_free_rule(struct cgroup_rule *r)
>               cgroup_dbg("Warning: Attempted to free NULL rule.\n");
>               return;
>       }
> -
> +     if (r->procname) {
> +             free(r->procname);
> +             r->procname = NULL;
> +     }
>       /* We must free any used controller strings, too. */
>       for(i = 0; i < MAX_MNT_ELEMENTS; i++) {
>               if (r->controllers[i])
> @@ -297,6 +300,9 @@ static int cgroup_parse_rules(bool cache, uid_t muid, 
> gid_t mgid)
>       /* Iterator for the line we're working on */
>       char *itr = NULL;
>  
> +     /* Pointer to process name in a line of the configuration file */
> +     char *procname = NULL;
> +
>       /* Pointer to the list that we're using */
>       struct cgroup_rule_list *lst = NULL;
>  
> @@ -310,11 +316,14 @@ static int cgroup_parse_rules(bool cache, uid_t muid, 
> gid_t mgid)
>       struct passwd *pwd = NULL;
>  
>       /* Temporary storage for a configuration rule */
> +     char key[CGROUP_RULE_MAXKEY] = { '\0' };
>       char user[LOGIN_NAME_MAX] = { '\0' };
>       char controllers[CG_CONTROLLER_MAX] = { '\0' };
>       char destination[FILENAME_MAX] = { '\0' };
>       uid_t uid = CGRULE_INVALID;
>       gid_t gid = CGRULE_INVALID;
> +     int len_username;
> +     int len_procname;
>  
>       /* The current line number */
>       unsigned int linenum = 0;
> @@ -381,16 +390,33 @@ static int cgroup_parse_rules(bool cache, uid_t muid, 
> gid_t mgid)
>                * there's an error in the configuration file.
>                */
>               skipped = false;
> +             memset(key, '\0', sizeof(key));
>               memset(user, '\0', sizeof(user));
>               memset(controllers, '\0', sizeof(controllers));
>               memset(destination, '\0', sizeof(destination));

Someone was obsessed with memset :)

> -             i = sscanf(itr, "%s%s%s", user, controllers, destination);
> +             i = sscanf(itr, "%s%s%s", key, controllers, destination);

Is this construction safe? Who guarantees the values fit to provided 
buffers?

>               if (i != 3) {
>                       cgroup_dbg("Failed to parse configuration file on"
>                                       " line %d.\n", linenum);
>                       goto parsefail;
>               }
>  
> +             if (strchr(key, ':')) {
> +                     /* <user>:<procname>    <subsystem>     <destination> */
> +                     procname = strchr(key, ':') + 1;

You call strchr(key, ':') twice. What about:

procname = strchr(key, ':');
if (procname) {
         /* eventually put *procname='\0'; here, see below */
        procname++; /* skip ':' */
        ...


> +                     len_username = procname - key - 1;
> +                     len_procname = strlen(key) - len_username - 1;

len_procname = strlen(procname)?

> +                     if (len_procname < 0) {
> +                             cgroup_dbg("Failed to parse configuration file 
> on"
> +                                             " line %d.\n", linenum);
> +                             goto parsefail;
> +                     }
> +             } else {
> +                     len_username = strlen(key);
> +                     len_procname = 0;
> +             }
> +             strncpy(user, key, len_username);

Why is it copied? Won't char *user; user = key; work? Of course with ':' 
replaced by '\0', as suggested above.

> +
>               /*
>                * Next, check the user/group.  If it's a % sign, then we
>                * are continuing another rule and UID/GID should not be
> @@ -479,7 +505,13 @@ static int cgroup_parse_rules(bool cache, uid_t muid, 
> gid_t mgid)
>  
>               newrule->uid = uid;
>               newrule->gid = gid;
> -             strncpy(newrule->username, user, strlen(user));
> +             strncpy(newrule->username, user, len_username);
> +             if (len_procname) {
> +                     newrule->procname = calloc(1, len_procname + 1);
> +                     strncpy(newrule->procname, procname, len_procname);

strdup(procname)?
+ check for NULL (i.e. out of memory).

> +             } else {
> +                     newrule->procname = NULL;
> +             }
>               strncpy(newrule->destination, destination, strlen(destination));

heh, I see the old code needs closer look... How did it pass Dhaval's 
and Balbir's review? :)

>               newrule->next = NULL;
>  
> @@ -2008,7 +2040,10 @@ void cgroup_print_rules_config(FILE *fp)
>  
>       itr = rl.head;
>       while (itr) {
> -             fprintf(fp, "Rule: %s\n", itr->username);
> +             fprintf(fp, "Rule: %s", itr->username);
> +             if (itr->procname)
> +                     fprintf(fp, ":%s", itr->procname);
> +             fprintf(fp, "\n");
>  
>               if (itr->uid == CGRULE_WILD)
>                       fprintf(fp, "  UID: any\n");
> diff --git a/src/libcgroup-internal.h b/src/libcgroup-internal.h
> index 9e69f10..6f314b6 100644
> --- a/src/libcgroup-internal.h
> +++ b/src/libcgroup-internal.h
> @@ -74,6 +74,7 @@ struct cgroup_rules_data {
>  struct cgroup_rule {
>       uid_t uid;
>       gid_t gid;
> +     char *procname;

Should be the procname an array, like the other members? Or make the 
other members allocated/freed as well? This state looks inconsistent to me.

>       char username[LOGIN_NAME_MAX];
>       char destination[FILENAME_MAX];
>       char *controllers[MAX_MNT_ELEMENTS];
> 
> ------------------------------------------------------------------------------
> 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


------------------------------------------------------------------------------
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 as they present alongside digital heavyweights like Barbarian 
Group, R/GA, & Big Spaceship. http://p.sf.net/sfu/creativitycat-com 
_______________________________________________
Libcg-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/libcg-devel

Reply via email to