Skip to content
Permalink
Browse files Browse the repository at this point in the history
replace copy_file with copy_file_as_user
  • Loading branch information
netblue30 committed Jan 9, 2017
1 parent d35d25f commit b8a4ff9
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 98 deletions.
2 changes: 2 additions & 0 deletions src/firejail/firejail.h
Expand Up @@ -446,6 +446,8 @@ void logmsg(const char *msg);
void logargs(int argc, char **argv) ;
void logerr(const char *msg);
int copy_file(const char *srcname, const char *destname, uid_t uid, gid_t gid, mode_t mode);
void copy_file_as_user(const char *srcname, const char *destname, uid_t uid, gid_t gid, mode_t mode);
void touch_file_as_user(const char *fname, uid_t uid, gid_t gid, mode_t mode);
int is_dir(const char *fname);
int is_link(const char *fname);
char *line_remove_spaces(const char *buf);
Expand Down
118 changes: 20 additions & 98 deletions src/firejail/fs_home.c
Expand Up @@ -43,18 +43,12 @@ static void skel(const char *homedir, uid_t u, gid_t g) {
if (stat(fname, &s) == 0)
return;
if (stat("/etc/skel/.zshrc", &s) == 0) {
if (copy_file("/etc/skel/.zshrc", fname, u, g, 0644) == 0) {
fs_logger("clone /etc/skel/.zshrc");
}
copy_file("/etc/skel/.zshrc", fname, u, g, 0644);
fs_logger("clone /etc/skel/.zshrc");
}
else { //
FILE *fp = fopen(fname, "w");
if (fp) {
fprintf(fp, "\n");
SET_PERMS_STREAM(fp, u, g, S_IRUSR | S_IWUSR);
fclose(fp);
fs_logger2("touch", fname);
}
else {
touch_file_as_user(fname, u, g, 0644);
fs_logger2("touch", fname);
}
free(fname);
}
Expand All @@ -68,19 +62,12 @@ static void skel(const char *homedir, uid_t u, gid_t g) {
if (stat(fname, &s) == 0)
return;
if (stat("/etc/skel/.cshrc", &s) == 0) {
if (copy_file("/etc/skel/.cshrc", fname, u, g, 0644) == 0) {
fs_logger("clone /etc/skel/.cshrc");
}
copy_file("/etc/skel/.cshrc", fname, u, g, 0644);
fs_logger("clone /etc/skel/.cshrc");
}
else { //
/* coverity[toctou] */
FILE *fp = fopen(fname, "w");
if (fp) {
fprintf(fp, "\n");
SET_PERMS_STREAM(fp, u, g, S_IRUSR | S_IWUSR);
fclose(fp);
fs_logger2("touch", fname);
}
else {
touch_file_as_user(fname, u, g, 0644);
fs_logger2("touch", fname);
}
free(fname);
}
Expand All @@ -94,9 +81,8 @@ static void skel(const char *homedir, uid_t u, gid_t g) {
if (stat(fname, &s) == 0)
return;
if (stat("/etc/skel/.bashrc", &s) == 0) {
if (copy_file("/etc/skel/.bashrc", fname, u, g, 0644) == 0) {
fs_logger("clone /etc/skel/.bashrc");
}
copy_file("/etc/skel/.bashrc", fname, u, g, 0644);
fs_logger("clone /etc/skel/.bashrc");
}
free(fname);
}
Expand Down Expand Up @@ -126,24 +112,8 @@ static int store_xauthority(void) {
return 0;
}

pid_t child = fork();
if (child < 0)
errExit("fork");
if (child == 0) {
// drop privileges
drop_privs(0);

// copy, set permissions and ownership
int rv = copy_file(src, dest, getuid(), getgid(), 0600);
if (rv)
fprintf(stderr, "Warning: cannot transfer .Xauthority in private home directory\n");
else {
fs_logger2("clone", dest);
}
_exit(0);
}
// wait for the child to finish
waitpid(child, NULL, 0);
copy_file_as_user(src, dest, getuid(), getgid(), 0600);
fs_logger2("clone", dest);
return 1; // file copied
}

Expand Down Expand Up @@ -184,24 +154,8 @@ static int store_asoundrc(void) {
free(rp);
}

pid_t child = fork();
if (child < 0)
errExit("fork");
if (child == 0) {
// drop privileges
drop_privs(0);

// copy, set permissions and ownership
int rv = copy_file(src, dest, getuid(), getgid(), 0644);
if (rv)
fprintf(stderr, "Warning: cannot transfer .asoundrc in private home directory\n");
else {
fs_logger2("clone", dest);
}
_exit(0);
}
// wait for the child to finish
waitpid(child, NULL, 0);
copy_file_as_user(src, dest, getuid(), getgid(), 0644);
fs_logger2("clone", dest);
return 1; // file copied
}

Expand All @@ -221,24 +175,8 @@ static void copy_xauthority(void) {
exit(1);
}

pid_t child = fork();
if (child < 0)
errExit("fork");
if (child == 0) {
// drop privileges
drop_privs(0);

// copy, set permissions and ownership
int rv = copy_file(src, dest, getuid(), getgid(), S_IRUSR | S_IWUSR);
if (rv)
fprintf(stderr, "Warning: cannot transfer .Xauthority in private home directory\n");
else {
fs_logger2("clone", dest);
}
_exit(0);
}
// wait for the child to finish
waitpid(child, NULL, 0);
copy_file_as_user(src, dest, getuid(), getgid(), S_IRUSR | S_IWUSR);
fs_logger2("clone", dest);

// delete the temporary file
unlink(src);
Expand All @@ -257,24 +195,8 @@ static void copy_asoundrc(void) {
exit(1);
}

pid_t child = fork();
if (child < 0)
errExit("fork");
if (child == 0) {
// drop privileges
drop_privs(0);

// copy, set permissions and ownership
int rv = copy_file(src, dest, getuid(), getgid(), S_IRUSR | S_IWUSR);
if (rv)
fprintf(stderr, "Warning: cannot transfer .asoundrc in private home directory\n");
else {
fs_logger2("clone", dest);
}
_exit(0);
}
// wait for the child to finish
waitpid(child, NULL, 0);
copy_file_as_user(src, dest, getuid(), getgid(), S_IRUSR | S_IWUSR);
fs_logger2("clone", dest);

// delete the temporary file
unlink(src);
Expand Down
40 changes: 40 additions & 0 deletions src/firejail/util.c
Expand Up @@ -28,6 +28,7 @@
#include <grp.h>
#include <sys/ioctl.h>
#include <termios.h>
#include <sys/wait.h>

#define MAX_GROUPS 1024
// drop privileges
Expand Down Expand Up @@ -219,6 +220,45 @@ int copy_file(const char *srcname, const char *destname, uid_t uid, gid_t gid, m
return 0;
}

// return -1 if error, 0 if no error
void copy_file_as_user(const char *srcname, const char *destname, uid_t uid, gid_t gid, mode_t mode) {
pid_t child = fork();
if (child < 0)
errExit("fork");
if (child == 0) {
// drop privileges
drop_privs(0);

// copy, set permissions and ownership
int rv = copy_file(srcname, destname, uid, gid, mode);
if (rv)
fprintf(stderr, "Warning: cannot transfer .Xauthority in private home directory\n");
_exit(0);
}
// wait for the child to finish
waitpid(child, NULL, 0);
}

// return -1 if error, 0 if no error
void touch_file_as_user(const char *fname, uid_t uid, gid_t gid, mode_t mode) {
pid_t child = fork();
if (child < 0)
errExit("fork");
if (child == 0) {
// drop privileges
drop_privs(0);

FILE *fp = fopen(fname, "w");
if (fp) {
fprintf(fp, "\n");
SET_PERMS_STREAM(fp, uid, gid, mode);
fclose(fp);
}
_exit(0);
}
// wait for the child to finish
waitpid(child, NULL, 0);
}

// return 1 if the file is a directory
int is_dir(const char *fname) {
Expand Down

0 comments on commit b8a4ff9

Please sign in to comment.