mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-10-29 05:40:23 -04:00
core-util: Fix permissions handling while creating directories
This makes updating of permissions on existing directories optional with pa_make_secure_dir() and pa_make_secure_parent_dir(). This makes sure that the recursive directory creation doesn't end up modifying existing directories, and also fixes a problem where creating an auth cookie (specifically ~/.esd_auth) would end up modifying permissions on ~. Thanks to Frédéric Danis for reporting this.
This commit is contained in:
parent
508ca489d2
commit
1ff604c298
5 changed files with 20 additions and 15 deletions
|
|
@ -202,12 +202,12 @@ static int change_user(void) {
|
|||
if (!pa_streq(pw->pw_dir, PA_SYSTEM_RUNTIME_PATH))
|
||||
pa_log_warn(_("Home directory of user '%s' is not '%s', ignoring."), PA_SYSTEM_USER, PA_SYSTEM_RUNTIME_PATH);
|
||||
|
||||
if (pa_make_secure_dir(PA_SYSTEM_RUNTIME_PATH, 0755, pw->pw_uid, gr->gr_gid) < 0) {
|
||||
if (pa_make_secure_dir(PA_SYSTEM_RUNTIME_PATH, 0755, pw->pw_uid, gr->gr_gid, TRUE) < 0) {
|
||||
pa_log(_("Failed to create '%s': %s"), PA_SYSTEM_RUNTIME_PATH, pa_cstrerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pa_make_secure_dir(PA_SYSTEM_STATE_PATH, 0700, pw->pw_uid, gr->gr_gid) < 0) {
|
||||
if (pa_make_secure_dir(PA_SYSTEM_STATE_PATH, 0700, pw->pw_uid, gr->gr_gid, TRUE) < 0) {
|
||||
pa_log(_("Failed to create '%s': %s"), PA_SYSTEM_STATE_PATH, pa_cstrerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -337,7 +337,7 @@ int pa__init(pa_module*m) {
|
|||
/* This socket doesn't reside in our own runtime dir but in
|
||||
* /tmp/.esd/, hence we have to create the dir first */
|
||||
|
||||
if (pa_make_secure_parent_dir(u->socket_path, pa_in_system_mode() ? 0755U : 0700U, (uid_t)-1, (gid_t)-1) < 0) {
|
||||
if (pa_make_secure_parent_dir(u->socket_path, pa_in_system_mode() ? 0755U : 0700U, (uid_t)-1, (gid_t)-1, FALSE) < 0) {
|
||||
pa_log("Failed to create socket directory '%s': %s\n", u->socket_path, pa_cstrerror(errno));
|
||||
goto fail;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ static int load(const char *fn, pa_bool_t create, void *data, size_t length) {
|
|||
pa_assert(length > 0);
|
||||
|
||||
if (create)
|
||||
pa_make_secure_parent_dir(fn, pa_in_system_mode() ? 0755U : 0700U, -1, -1);
|
||||
pa_make_secure_parent_dir(fn, pa_in_system_mode() ? 0755U : 0700U, -1, -1, FALSE);
|
||||
|
||||
if ((fd = pa_open_cloexec(fn, (create ? O_RDWR|O_CREAT : O_RDONLY)|O_BINARY, S_IRUSR|S_IWUSR)) < 0) {
|
||||
|
||||
|
|
|
|||
|
|
@ -216,8 +216,10 @@ void pa_make_fd_cloexec(int fd) {
|
|||
|
||||
}
|
||||
|
||||
/** Creates a directory securely */
|
||||
int pa_make_secure_dir(const char* dir, mode_t m, uid_t uid, gid_t gid) {
|
||||
/** Creates a directory securely. Will create parent directories recursively if
|
||||
* required. This will not update permissions on parent directories if they
|
||||
* already exist, however. */
|
||||
int pa_make_secure_dir(const char* dir, mode_t m, uid_t uid, gid_t gid, pa_bool_t update_perms) {
|
||||
struct stat st;
|
||||
int r, saved_errno;
|
||||
pa_bool_t retry = TRUE;
|
||||
|
|
@ -239,7 +241,7 @@ again:
|
|||
if (r < 0 && errno == ENOENT && retry) {
|
||||
/* If a parent directory in the path doesn't exist, try to create that
|
||||
* first, then try again. */
|
||||
pa_make_secure_parent_dir(dir, m, uid, gid);
|
||||
pa_make_secure_parent_dir(dir, m, uid, gid, FALSE);
|
||||
retry = FALSE;
|
||||
goto again;
|
||||
}
|
||||
|
|
@ -274,6 +276,9 @@ again:
|
|||
goto fail;
|
||||
}
|
||||
|
||||
if (!update_perms)
|
||||
return 0;
|
||||
|
||||
#ifdef HAVE_FCHOWN
|
||||
if (uid == (uid_t) -1)
|
||||
uid = getuid();
|
||||
|
|
@ -335,14 +340,14 @@ char *pa_parent_dir(const char *fn) {
|
|||
}
|
||||
|
||||
/* Creates a the parent directory of the specified path securely */
|
||||
int pa_make_secure_parent_dir(const char *fn, mode_t m, uid_t uid, gid_t gid) {
|
||||
int pa_make_secure_parent_dir(const char *fn, mode_t m, uid_t uid, gid_t gid, pa_bool_t update_perms) {
|
||||
int ret = -1;
|
||||
char *dir;
|
||||
|
||||
if (!(dir = pa_parent_dir(fn)))
|
||||
goto finish;
|
||||
|
||||
if (pa_make_secure_dir(dir, m, uid, gid) < 0)
|
||||
if (pa_make_secure_dir(dir, m, uid, gid, update_perms) < 0)
|
||||
goto finish;
|
||||
|
||||
ret = 0;
|
||||
|
|
@ -1502,7 +1507,7 @@ char *pa_get_state_dir(void) {
|
|||
/* If PULSE_STATE_PATH and PULSE_RUNTIME_PATH point to the same
|
||||
* dir then this will break. */
|
||||
|
||||
if (pa_make_secure_dir(d, 0700U, (uid_t) -1, (gid_t) -1) < 0) {
|
||||
if (pa_make_secure_dir(d, 0700U, (uid_t) -1, (gid_t) -1, TRUE) < 0) {
|
||||
pa_log_error("Failed to create secure directory: %s", pa_cstrerror(errno));
|
||||
pa_xfree(d);
|
||||
return NULL;
|
||||
|
|
@ -1644,7 +1649,7 @@ char *pa_get_runtime_dir(void) {
|
|||
d = getenv("PULSE_RUNTIME_PATH");
|
||||
if (d) {
|
||||
|
||||
if (pa_make_secure_dir(d, m, (uid_t) -1, (gid_t) -1) < 0) {
|
||||
if (pa_make_secure_dir(d, m, (uid_t) -1, (gid_t) -1, TRUE) < 0) {
|
||||
pa_log_error("Failed to create secure directory: %s", pa_cstrerror(errno));
|
||||
goto fail;
|
||||
}
|
||||
|
|
@ -1657,7 +1662,7 @@ char *pa_get_runtime_dir(void) {
|
|||
if (d) {
|
||||
k = pa_sprintf_malloc("%s" PA_PATH_SEP "pulse", d);
|
||||
|
||||
if (pa_make_secure_dir(k, m, (uid_t) -1, (gid_t) -1) < 0) {
|
||||
if (pa_make_secure_dir(k, m, (uid_t) -1, (gid_t) -1, TRUE) < 0) {
|
||||
free(k);
|
||||
pa_log_error("Failed to create secure directory: %s", pa_cstrerror(errno));
|
||||
goto fail;
|
||||
|
|
@ -1671,7 +1676,7 @@ char *pa_get_runtime_dir(void) {
|
|||
if (!d)
|
||||
goto fail;
|
||||
|
||||
if (pa_make_secure_dir(d, m, (uid_t) -1, (gid_t) -1) < 0) {
|
||||
if (pa_make_secure_dir(d, m, (uid_t) -1, (gid_t) -1, TRUE) < 0) {
|
||||
pa_log_error("Failed to create secure directory: %s", pa_cstrerror(errno));
|
||||
pa_xfree(d);
|
||||
goto fail;
|
||||
|
|
|
|||
|
|
@ -58,8 +58,8 @@ struct timeval;
|
|||
void pa_make_fd_nonblock(int fd);
|
||||
void pa_make_fd_cloexec(int fd);
|
||||
|
||||
int pa_make_secure_dir(const char* dir, mode_t m, uid_t uid, gid_t gid);
|
||||
int pa_make_secure_parent_dir(const char *fn, mode_t, uid_t uid, gid_t gid);
|
||||
int pa_make_secure_dir(const char* dir, mode_t m, uid_t uid, gid_t gid, pa_bool_t update_perms);
|
||||
int pa_make_secure_parent_dir(const char *fn, mode_t, uid_t uid, gid_t gid, pa_bool_t update_perms);
|
||||
|
||||
ssize_t pa_read(int fd, void *buf, size_t count, int *type);
|
||||
ssize_t pa_write(int fd, const void *buf, size_t count, int *type);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue