Skip to content

Commit

Permalink
check metadata on chown/chmod errors when cloning
Browse files Browse the repository at this point in the history
  • Loading branch information
trapexit committed Feb 15, 2017
1 parent 899670b commit 492d895
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 4 deletions.
56 changes: 56 additions & 0 deletions src/fs_base_chmod.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@

#include <sys/stat.h>

#include "fs_base_stat.hpp"

#define MODE_BITS (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO)

namespace fs
{
static
Expand Down Expand Up @@ -49,6 +53,58 @@ namespace fs
{
return ::fchmod(fd,st.st_mode);
}

static
inline
int
chmod_check_on_error(const std::string &path,
const mode_t mode)
{
int rv;

rv = fs::chmod(path,mode);
if(rv == -1)
{
int error;
struct stat st;

error = errno;
rv = fs::stat(path,st);
if(rv == -1)
return -1;

if((st.st_mode & MODE_BITS) != (mode & MODE_BITS))
return (errno=error,-1);
}

return 0;
}

static
inline
int
fchmod_check_on_error(const int fd,
const struct stat &st)
{
int rv;

rv = fs::fchmod(fd,st);
if(rv == -1)
{
int error;
struct stat tmpst;

error = errno;
rv = fs::fstat(fd,tmpst);
if(rv == -1)
return -1;

if((st.st_mode & MODE_BITS) != (tmpst.st_mode & MODE_BITS))
return (errno=error,-1);
}

return 0;
}
}

#endif
65 changes: 65 additions & 0 deletions src/fs_base_chown.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
#include <sys/types.h>
#include <unistd.h>

#include "fs_base_stat.hpp"

namespace fs
{
static
Expand Down Expand Up @@ -56,6 +58,15 @@ namespace fs
return ::lchown(path.c_str(),uid,gid);
}

static
inline
int
lchown(const std::string &path,
const struct stat &st)
{
return fs::lchown(path,st.st_uid,st.st_gid);
}

static
inline
int
Expand All @@ -74,6 +85,60 @@ namespace fs
{
return fs::fchown(fd,st.st_uid,st.st_gid);
}

static
inline
int
lchown_check_on_error(const std::string &path,
const struct stat &st)
{
int rv;

rv = fs::lchown(path,st);
if(rv == -1)
{
int error;
struct stat tmpst;

error = errno;
rv = fs::lstat(path,tmpst);
if(rv == -1)
return -1;

if((st.st_uid != tmpst.st_uid) ||
(st.st_gid != tmpst.st_gid))
return (errno=error,-1);
}

return 0;
}

static
inline
int
fchown_check_on_error(const int fd,
const struct stat &st)
{
int rv;

rv = fs::fchown(fd,st);
if(rv == -1)
{
int error;
struct stat tmpst;

error = errno;
rv = fs::fstat(fd,tmpst);
if(rv == -1)
return -1;

if((st.st_uid != tmpst.st_uid) ||
(st.st_gid != tmpst.st_gid))
return (errno=error,-1);
}

return 0;
}
}

#endif
4 changes: 2 additions & 2 deletions src/fs_clonefile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,11 +176,11 @@ namespace fs
if((rv == -1) && !ignorable_error(errno))
return -1;

rv = fs::fchown(fdout,stin);
rv = fs::fchown_check_on_error(fdout,stin);
if(rv == -1)
return -1;

rv = fs::fchmod(fdout,stin);
rv = fs::fchmod_check_on_error(fdout,stin);
if(rv == -1)
return -1;

Expand Down
4 changes: 2 additions & 2 deletions src/fs_clonepath.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ namespace fs
if(errno != EEXIST)
return -1;

rv = fs::chmod(topath,st.st_mode);
rv = fs::chmod_check_on_error(topath,st.st_mode);
if(rv == -1)
return -1;
}
Expand All @@ -96,7 +96,7 @@ namespace fs
if((rv == -1) && !ignorable_error(errno))
return -1;

rv = fs::chown(topath,st);
rv = fs::lchown_check_on_error(topath,st);
if(rv == -1)
return -1;

Expand Down

0 comments on commit 492d895

Please sign in to comment.