On 02/13/2013 09:20 AM, Jan Safranek wrote:
> On 02/11/2013 06:09 PM, Peter Schiffer wrote:
>> mkdir(2) function returns EROFS error even when the path already exists on 
>> the
>> read only file system, so it is impossible to determine whether the path 
>> already
>> exists on this kind of fs only be return code from the mkdir(2). To make
>> cg_mkdir_p() compatible with the ro fs, the function checks whether the path
>> exists with stat(2) before trying to create it.
>>
>> Signed-off-by: Peter Schiffer <pschi...@redhat.com>
>> ---
>>   0 files changed
>>
>> diff --git a/src/api.c b/src/api.c
>> index 11cd1b4..4acdc30 100644
>> --- a/src/api.c
>> +++ b/src/api.c
>> @@ -1271,6 +1271,7 @@ int cg_mkdir_p(const char *path)
>>      int i = 0;
>>      char pos;
>>      int ret = 0;
>> +    struct stat st;
>>
>>      real_path = strdup(path);
>>      if (!real_path) {
>> @@ -1287,6 +1288,10 @@ int cg_mkdir_p(const char *path)
>>                      i++;
>>              pos = real_path[i];
>>              real_path[i] = '\0';            /* Temporarily overwrite "/" */
>> +            if (stat(real_path, &st) == 0) {                /* Continue if 
>> dir exists */
>> +                    real_path[i] = pos;
>> +                    continue;
>> +            }
>>              ret = mkdir(real_path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
>>              real_path[i] = pos;
>>              if (ret) {
>
> This is classical TOCTTOU. While it does not have any security
> implications, it would be better to mkdir() and only if it fails, then
> check if the directory was already there.
>
> Jan
>

Thanks. What about this one?

peter

diff --git a/src/api.c b/src/api.c
index 11cd1b4..b5bbb74 100644
--- a/src/api.c
+++ b/src/api.c
@@ -1270,7 +1270,8 @@ int cg_mkdir_p(const char *path)
        char *real_path = NULL;
        int i = 0;
        char pos;
-       int ret = 0;
+       int ret = 0, stat_ret;
+       struct stat st;

        real_path = strdup(path);
        if (!real_path) {
@@ -1298,6 +1299,14 @@ int cg_mkdir_p(const char *path)
                                ret = ECGROUPNOTOWNER;
                                goto done;
                        default:
+                               /* Check if path exists */
+                               real_path[i] = '\0';
+                               stat_ret = stat(real_path, &st);
+                               real_path[i] = pos;
+                               if (stat_ret == 0) {
+                                       ret = 0;        /* Path exists */
+                                       break;
+                               }
                                ret = ECGROUPNOTALLOWED;
                                goto done;
                        }

------------------------------------------------------------------------------
Free Next-Gen Firewall Hardware Offer
Buy your Sophos next-gen firewall before the end March 2013 
and get the hardware for free! Learn more.
http://p.sf.net/sfu/sophos-d2d-feb
_______________________________________________
Libcg-devel mailing list
Libcg-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libcg-devel

Reply via email to