diff options
Diffstat (limited to 'src/firejail/pulseaudio.c')
-rw-r--r-- | src/firejail/pulseaudio.c | 62 |
1 files changed, 21 insertions, 41 deletions
diff --git a/src/firejail/pulseaudio.c b/src/firejail/pulseaudio.c index be0f5aea6..f8d4c2f3c 100644 --- a/src/firejail/pulseaudio.c +++ b/src/firejail/pulseaudio.c | |||
@@ -75,31 +75,34 @@ void pulseaudio_disable(void) { | |||
75 | closedir(dir); | 75 | closedir(dir); |
76 | } | 76 | } |
77 | 77 | ||
78 | static void pulseaudio_fallback(const char *path) { | ||
79 | assert(path); | ||
80 | |||
81 | fmessage("Cannot mount tmpfs on %s/.config/pulse\n", cfg.homedir); | ||
82 | env_store_name_val("PULSE_CLIENTCONFIG", path, SETENV); | ||
83 | } | ||
84 | |||
85 | // disable shm in pulseaudio (issue #69) | 78 | // disable shm in pulseaudio (issue #69) |
86 | void pulseaudio_init(void) { | 79 | void pulseaudio_init(void) { |
87 | struct stat s; | ||
88 | |||
89 | // do we have pulseaudio in the system? | 80 | // do we have pulseaudio in the system? |
90 | if (stat(PULSE_CLIENT_SYSCONF, &s) == -1) { | 81 | if (access(PULSE_CLIENT_SYSCONF, R_OK)) { |
91 | if (arg_debug) | 82 | if (arg_debug) |
92 | printf("%s not found\n", PULSE_CLIENT_SYSCONF); | 83 | printf("Cannot read %s\n", PULSE_CLIENT_SYSCONF); |
93 | return; | 84 | return; |
94 | } | 85 | } |
95 | 86 | ||
87 | // create ~/.config/pulse directory if not present | ||
88 | char *homeusercfg = NULL; | ||
89 | if (asprintf(&homeusercfg, "%s/.config", cfg.homedir) == -1) | ||
90 | errExit("asprintf"); | ||
91 | if (create_empty_dir_as_user(homeusercfg, 0700)) | ||
92 | fs_logger2("create", homeusercfg); | ||
93 | |||
94 | free(homeusercfg); | ||
95 | if (asprintf(&homeusercfg, "%s/.config/pulse", cfg.homedir) == -1) | ||
96 | errExit("asprintf"); | ||
97 | if (create_empty_dir_as_user(homeusercfg, 0700)) | ||
98 | fs_logger2("create", homeusercfg); | ||
99 | |||
96 | // create the new user pulseaudio directory | 100 | // create the new user pulseaudio directory |
101 | // that will be mounted over ~/.config/pulse | ||
97 | if (mkdir(RUN_PULSE_DIR, 0700) == -1) | 102 | if (mkdir(RUN_PULSE_DIR, 0700) == -1) |
98 | errExit("mkdir"); | 103 | errExit("mkdir"); |
99 | selinux_relabel_path(RUN_PULSE_DIR, RUN_PULSE_DIR); | 104 | selinux_relabel_path(RUN_PULSE_DIR, homeusercfg); |
100 | // mount it nosuid, noexec, nodev | ||
101 | fs_remount(RUN_PULSE_DIR, MOUNT_NOEXEC, 0); | 105 | fs_remount(RUN_PULSE_DIR, MOUNT_NOEXEC, 0); |
102 | |||
103 | // create the new client.conf file | 106 | // create the new client.conf file |
104 | char *pulsecfg = NULL; | 107 | char *pulsecfg = NULL; |
105 | if (asprintf(&pulsecfg, "%s/client.conf", RUN_PULSE_DIR) == -1) | 108 | if (asprintf(&pulsecfg, "%s/client.conf", RUN_PULSE_DIR) == -1) |
@@ -116,37 +119,14 @@ void pulseaudio_init(void) { | |||
116 | if (set_perms(RUN_PULSE_DIR, getuid(), getgid(), 0700)) | 119 | if (set_perms(RUN_PULSE_DIR, getuid(), getgid(), 0700)) |
117 | errExit("set_perms"); | 120 | errExit("set_perms"); |
118 | 121 | ||
119 | // create ~/.config/pulse directory if not present | ||
120 | char *homeusercfg = NULL; | ||
121 | if (asprintf(&homeusercfg, "%s/.config", cfg.homedir) == -1) | ||
122 | errExit("asprintf"); | ||
123 | if (create_empty_dir_as_user(homeusercfg, 0700)) | ||
124 | fs_logger2("create", homeusercfg); | ||
125 | |||
126 | free(homeusercfg); | ||
127 | if (asprintf(&homeusercfg, "%s/.config/pulse", cfg.homedir) == -1) | ||
128 | errExit("asprintf"); | ||
129 | if (create_empty_dir_as_user(homeusercfg, 0700)) | ||
130 | fs_logger2("create", homeusercfg); | ||
131 | |||
132 | // if ~/.config/pulse exists and there are no symbolic links, mount the new directory | 122 | // if ~/.config/pulse exists and there are no symbolic links, mount the new directory |
133 | // else set environment variable | 123 | // else set environment variable |
124 | EUID_USER(); | ||
134 | int fd = safer_openat(-1, homeusercfg, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); | 125 | int fd = safer_openat(-1, homeusercfg, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); |
126 | EUID_ROOT(); | ||
135 | if (fd == -1) { | 127 | if (fd == -1) { |
136 | pulseaudio_fallback(pulsecfg); | 128 | fwarning("not mounting tmpfs on %s\n", homeusercfg); |
137 | goto out; | 129 | env_store_name_val("PULSE_CLIENTCONFIG", pulsecfg, SETENV); |
138 | } | ||
139 | // confirm the actual mount destination is owned by the user | ||
140 | if (fstat(fd, &s) == -1) { // FUSE | ||
141 | if (errno != EACCES) | ||
142 | errExit("fstat"); | ||
143 | close(fd); | ||
144 | pulseaudio_fallback(pulsecfg); | ||
145 | goto out; | ||
146 | } | ||
147 | if (s.st_uid != getuid()) { | ||
148 | close(fd); | ||
149 | pulseaudio_fallback(pulsecfg); | ||
150 | goto out; | 130 | goto out; |
151 | } | 131 | } |
152 | // preserve a read-only mount | 132 | // preserve a read-only mount |