aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kris7topher@gmail.com>2020-02-22 21:52:23 +0100
committerLibravatar Kristóf Marussy <kris7topher@gmail.com>2020-02-23 17:13:13 +0100
commit9860590b25e1478367650a1c5ff694abf70a5b65 (patch)
tree943f410d5f11e0b14a8ee317c893a3b190cb82d7 /src
parentmisc things (diff)
downloadfirejail-9860590b25e1478367650a1c5ff694abf70a5b65.tar.gz
firejail-9860590b25e1478367650a1c5ff694abf70a5b65.tar.zst
firejail-9860590b25e1478367650a1c5ff694abf70a5b65.zip
Harden dhcp by checking for /sbin/dhclient
Running /sbin/dhclient or /usr/sbin/dhclient avoids PATH-based vulnerabilities. We also check that the dhclient is owned by root. We take an approach similar to netfiler.c and assume that the required binary ar in /sbin or /usr/sbin, or (like on Arch) /sbin is a symlink to /usr/bin.
Diffstat (limited to 'src')
-rw-r--r--src/firejail/dhcp.c27
1 files changed, 21 insertions, 6 deletions
diff --git a/src/firejail/dhcp.c b/src/firejail/dhcp.c
index 7593a47f2..4a7806a7f 100644
--- a/src/firejail/dhcp.c
+++ b/src/firejail/dhcp.c
@@ -18,6 +18,7 @@
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */ 19 */
20#include "firejail.h" 20#include "firejail.h"
21#include <sys/stat.h>
21#include <sys/types.h> 22#include <sys/types.h>
22#include <sys/wait.h> 23#include <sys/wait.h>
23#include <errno.h> 24#include <errno.h>
@@ -56,9 +57,9 @@ static const Dhclient dhclient6 = {
56 .arg_offset = offsetof(Bridge, arg_ip6_dhcp) 57 .arg_offset = offsetof(Bridge, arg_ip6_dhcp)
57}; 58};
58 59
59static void dhcp_run_dhclient(const Dhclient *client) { 60static void dhcp_run_dhclient(char *dhclient_path, const Dhclient *client) {
60 char *argv[256] = { 61 char *argv[256] = {
61 "dhclient", 62 dhclient_path,
62 client->version_arg, 63 client->version_arg,
63 "-pf", client->pid_file, 64 "-pf", client->pid_file,
64 "-lf", client->leases_file, 65 "-lf", client->leases_file,
@@ -115,8 +116,8 @@ static pid_t dhcp_read_pidfile(const Dhclient *client) {
115 return found; 116 return found;
116} 117}
117 118
118static void dhcp_start_dhclient(const Dhclient *client) { 119static void dhcp_start_dhclient(char *dhclient_path, const Dhclient *client) {
119 dhcp_run_dhclient(client); 120 dhcp_run_dhclient(dhclient_path, client);
120 *(client->pid) = dhcp_read_pidfile(client); 121 *(client->pid) = dhcp_read_pidfile(client);
121} 122}
122 123
@@ -139,18 +140,32 @@ void dhcp_start(void) {
139 if (!any_dhcp()) 140 if (!any_dhcp())
140 return; 141 return;
141 142
143 char *dhclient_path = "/sbin/dhclient";
144 struct stat s;
145 if (stat(dhclient_path, &s) == -1) {
146 dhclient_path = "/usr/sbin/dhclient";
147 if (stat(dhclient_path, &s) == -1) {
148 fprintf(stderr, "Error: dhclient was not found.\n");
149 exit(1);
150 }
151 }
152 if (s.st_uid != 0 && s.st_gid != 0) {
153 fprintf(stderr, "Error: invalid dhclient executable\n");
154 exit(1);
155 }
156
142 EUID_ROOT(); 157 EUID_ROOT();
143 if (mkdir(RUN_DHCLIENT_DIR, 0700)) 158 if (mkdir(RUN_DHCLIENT_DIR, 0700))
144 errExit("mkdir"); 159 errExit("mkdir");
145 160
146 if (any_ip_dhcp()) { 161 if (any_ip_dhcp()) {
147 dhcp_start_dhclient(&dhclient4); 162 dhcp_start_dhclient(dhclient_path, &dhclient4);
148 if (arg_debug) 163 if (arg_debug)
149 printf("Running dhclient -4 in the background as pid %ld\n", (long) dhclient4_pid); 164 printf("Running dhclient -4 in the background as pid %ld\n", (long) dhclient4_pid);
150 } 165 }
151 if (any_ip6_dhcp()) { 166 if (any_ip6_dhcp()) {
152 dhcp_waitll_all(); 167 dhcp_waitll_all();
153 dhcp_start_dhclient(&dhclient6); 168 dhcp_start_dhclient(dhclient_path, &dhclient6);
154 if (arg_debug) 169 if (arg_debug)
155 printf("Running dhclient -6 in the background as pid %ld\n", (long) dhclient6_pid); 170 printf("Running dhclient -6 in the background as pid %ld\n", (long) dhclient6_pid);
156 if (dhclient4_pid == dhclient6_pid) { 171 if (dhclient4_pid == dhclient6_pid) {