On 09/01/2010 02:38 PM, Jan Safranek wrote:
> Rewrite cg_mkdir_p so it does not change current working directory.
>
> Old sequence of operations when creating e.g. /cgroup/cpu
> $OLDCWD=$PWD
> cd /
> mkdir cgroup
> cd cgroup
> mkdir cpu
> cd $OLDCWD
>
> New sequence is:
> mkdir /cgroup
> mkdir /cgroup/cpu
>
> Some tools, namely those used in /etc/init.d/cgconfig, might be executed with
> security constrained context, which does not allow them to access certain
> directories (like /var/log/audit). And when e.g. cgconfigparser is executed in
> /var/log/audit as current working directory, chdir("/var/log/audit") in
> cg_mkdir_p() fails. As consequence, "/etc/init.d/cgconfig start" randomly
> fails
> or succeeds, depending on current working directory and current SELinux
> policy.
>
> Signed-off-by: Jan Safranek<[email protected]>
>
Acked-by: Ivana Hutarova Varekova <[email protected]>
> ---
>
> src/api.c | 57 +++++++++++----------------------------------------------
> 1 files changed, 11 insertions(+), 46 deletions(-)
>
> diff --git a/src/api.c b/src/api.c
> index 4bd6b46..66734ed 100644
> --- a/src/api.c
> +++ b/src/api.c
> @@ -1026,20 +1026,9 @@ int cgroup_attach_task(struct cgroup *cgroup)
> int cg_mkdir_p(const char *path)
> {
> char *real_path = NULL;
> - char *wd = NULL;
> - int i = 0, j = 0;
> + int i = 0;
> char pos;
> - char *str = NULL;
> int ret = 0;
> - char cwd[FILENAME_MAX];
> - char *buf = NULL;
> -
> - buf = getcwd(cwd, FILENAME_MAX);
> -
> - if (!buf) {
> - last_errno = errno;
> - return ECGOTHER;
> - }
>
> real_path = strdup(path);
> if (!real_path) {
> @@ -1048,23 +1037,16 @@ int cg_mkdir_p(const char *path)
> }
>
> do {
> - while (real_path[j] != '\0'&& real_path[j] != '/')
> - j++;
> - while (real_path[j] != '\0'&& real_path[j] == '/')
> - j++;
> - if (i == j)
> - continue;
> - pos = real_path[j];
> - real_path[j] = '\0'; /* Temporarily overwrite "/" */
> - str =&real_path[i];
> - ret = mkdir(str, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
> - wd = strdup(str);
> - if (!wd) {
> - last_errno = errno;
> - ret = ECGOTHER;
> - break;
> - }
> - real_path[j] = pos;
> + while (real_path[i] != '\0'&& real_path[i] == '/')
> + i++;
> + if (real_path[i] == '\0')
> + break; /* The path ends with '/', ignore it. */
> + while (real_path[i] != '\0'&& real_path[i] != '/')
> + i++;
> + pos = real_path[i];
> + real_path[i] = '\0'; /* Temporarily overwrite "/" */
> + ret = mkdir(real_path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
> + real_path[i] = pos;
> if (ret) {
> switch (errno) {
> case EEXIST:
> @@ -1072,31 +1054,14 @@ int cg_mkdir_p(const char *path)
> break;
> case EPERM:
> ret = ECGROUPNOTOWNER;
> - free(wd);
> goto done;
> default:
> ret = ECGROUPNOTALLOWED;
> - free(wd);
> goto done;
> }
> }
> - i = j;
> - ret = chdir(wd);
> - if (ret) {
> - cgroup_dbg("could not chdir to child directory (%s)\n",
> - wd);
> - break;
> - }
> - free(wd);
> } while (real_path[i]);
>
> - ret = chdir(buf);
> - if (ret) {
> - last_errno = errno;
> - ret = ECGOTHER;
> - cgroup_dbg("could not go back to old directory (%s)\n", cwd);
> - }
> -
> done:
> free(real_path);
> return ret;
>
>
> ------------------------------------------------------------------------------
> This SF.net Dev2Dev email is sponsored by:
>
> Show off your parallel programming skills.
> Enter the Intel(R) Threading Challenge 2010.
> http://p.sf.net/sfu/intel-thread-sfd
> _______________________________________________
> Libcg-devel mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/libcg-devel
>
------------------------------------------------------------------------------
This SF.net Dev2Dev email is sponsored by:
Show off your parallel programming skills.
Enter the Intel(R) Threading Challenge 2010.
http://p.sf.net/sfu/intel-thread-sfd
_______________________________________________
Libcg-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/libcg-devel