]>
Commit | Line | Data |
---|---|---|
530cba5e SS |
1 | From 291f738f341a78f8c7974a7603d1a2eaa01ebacc Mon Sep 17 00:00:00 2001 |
2 | From: Pavel Zhukov <pzhukov@redhat.com> | |
3 | Date: Thu, 21 Feb 2019 10:30:28 +0100 | |
4 | Subject: [PATCH 11/21] Drop unnecessary capabilities | |
5 | Cc: pzhukov@redhat.com | |
6 | ||
7 | dhclient (#517649, #546765), dhcpd/dhcrelay (#699713) | |
8 | --- | |
9 | client/Makefile.am | 3 ++- | |
10 | client/dhclient-script.8 | 10 ++++++++++ | |
11 | client/dhclient.8 | 29 +++++++++++++++++++++++++++++ | |
12 | client/dhclient.c | 24 ++++++++++++++++++++++++ | |
13 | configure.ac | 35 +++++++++++++++++++++++++++++++++++ | |
14 | relay/Makefile.am | 3 ++- | |
15 | relay/dhcrelay.c | 29 +++++++++++++++++++++++++++++ | |
16 | 7 files changed, 131 insertions(+), 2 deletions(-) | |
17 | ||
18 | diff --git a/client/Makefile.am b/client/Makefile.am | |
19 | index d177159..0689185 100644 | |
20 | --- a/client/Makefile.am | |
21 | +++ b/client/Makefile.am | |
22 | @@ -17,6 +17,7 @@ dhclient_LDADD = ../common/libdhcp.@A@ ../omapip/libomapi.@A@ \ | |
23 | @BINDLIBIRSDIR@/libirs.@A@ \ | |
24 | @BINDLIBDNSDIR@/libdns.@A@ \ | |
25 | @BINDLIBISCCFGDIR@/libisccfg.@A@ \ | |
26 | - @BINDLIBISCDIR@/libisc.@A@ | |
27 | + @BINDLIBISCDIR@/libisc.@A@ \ | |
28 | + $(CAPNG_LDADD) | |
29 | man_MANS = dhclient.8 dhclient-script.8 dhclient.conf.5 dhclient.leases.5 | |
30 | EXTRA_DIST = $(man_MANS) | |
31 | diff --git a/client/dhclient-script.8 b/client/dhclient-script.8 | |
32 | index 0db5516..2eddb8f 100644 | |
33 | --- a/client/dhclient-script.8 | |
34 | +++ b/client/dhclient-script.8 | |
35 | @@ -243,6 +243,16 @@ repeatedly initialized to the values provided by one server, and then | |
36 | the other. Assuming the information provided by both servers is | |
37 | valid, this shouldn't cause any real problems, but it could be | |
38 | confusing. | |
39 | +.PP | |
40 | +Normally, if dhclient was compiled with libcap-ng support, | |
41 | +dhclient drops most capabilities immediately upon startup. | |
42 | +While more secure, this greatly restricts the additional actions that | |
43 | +hooks in dhclient-script can take. For example, any daemons that | |
44 | +dhclient-script starts or restarts will inherit the restricted | |
45 | +capabilities as well, which may interfere with their correct operation. | |
46 | +Thus, the | |
47 | +.BI \-nc | |
48 | +option can be used to prevent dhclient from dropping capabilities. | |
49 | .SH SEE ALSO | |
50 | dhclient(8), dhcpd(8), dhcrelay(8), dhclient.conf(5) and | |
51 | dhclient.leases(5). | |
52 | diff --git a/client/dhclient.8 b/client/dhclient.8 | |
53 | index 6d7fbdb..0145b9f 100644 | |
54 | --- a/client/dhclient.8 | |
55 | +++ b/client/dhclient.8 | |
56 | @@ -134,6 +134,9 @@ dhclient - Dynamic Host Configuration Protocol Client | |
6df985df SS |
57 | .B -w |
58 | ] | |
59 | [ | |
60 | +.B -nc | |
61 | +] | |
62 | +[ | |
63 | .B -B | |
64 | ] | |
65 | [ | |
530cba5e SS |
66 | @@ -328,6 +331,32 @@ not to exit when it doesn't find any such interfaces. The |
67 | program can then be used to notify the client when a network interface | |
68 | has been added or removed, so that the client can attempt to configure an IP | |
6df985df | 69 | address on that interface. |
530cba5e | 70 | +.TP |
6df985df SS |
71 | +.BI \-nc |
72 | +Do not drop capabilities. | |
73 | + | |
74 | +Normally, if | |
75 | +.B dhclient | |
76 | +was compiled with libcap-ng support, | |
77 | +.B dhclient | |
78 | +drops most capabilities immediately upon startup. While more secure, | |
79 | +this greatly restricts the additional actions that hooks in | |
80 | +.B dhclient-script (8) | |
530cba5e | 81 | +can take. (For example, any daemons that |
6df985df SS |
82 | +.B dhclient-script (8) |
83 | +starts or restarts will inherit the restricted capabilities as well, | |
84 | +which may interfere with their correct operation.) Thus, the | |
85 | +.BI \-nc | |
86 | +option can be used to prevent | |
87 | +.B dhclient | |
88 | +from dropping capabilities. | |
89 | + | |
90 | +The | |
91 | +.BI \-nc | |
92 | +option is ignored if | |
93 | +.B dhclient | |
94 | +was not compiled with libcap-ng support. | |
95 | + | |
530cba5e SS |
96 | .TP |
97 | .BI \-n | |
98 | Do not configure any interfaces. This is most likely to be useful in | |
99 | diff --git a/client/dhclient.c b/client/dhclient.c | |
100 | index a86ab9e..5d3f5bc 100644 | |
101 | --- a/client/dhclient.c | |
102 | +++ b/client/dhclient.c | |
103 | @@ -41,6 +41,10 @@ | |
104 | #include <sys/wait.h> | |
105 | #include <limits.h> | |
106 | ||
6df985df SS |
107 | +#ifdef HAVE_LIBCAP_NG |
108 | +#include <cap-ng.h> | |
109 | +#endif | |
110 | + | |
111 | /* | |
112 | * Defined in stdio.h when _GNU_SOURCE is set, but we don't want to define | |
113 | * that when building ISC code. | |
530cba5e SS |
114 | @@ -266,6 +270,9 @@ main(int argc, char **argv) { |
115 | int timeout_arg = 0; | |
116 | char *arg_conf = NULL; | |
117 | int arg_conf_len = 0; | |
6df985df SS |
118 | +#ifdef HAVE_LIBCAP_NG |
119 | + int keep_capabilities = 0; | |
120 | +#endif | |
530cba5e SS |
121 | |
122 | /* Initialize client globals. */ | |
123 | memset(&default_duid, 0, sizeof(default_duid)); | |
124 | @@ -665,6 +672,10 @@ main(int argc, char **argv) { | |
125 | ||
126 | dhclient_request_options = argv[i]; | |
127 | ||
6df985df SS |
128 | + } else if (!strcmp(argv[i], "-nc")) { |
129 | +#ifdef HAVE_LIBCAP_NG | |
530cba5e | 130 | + keep_capabilities = 1; |
6df985df | 131 | +#endif |
530cba5e SS |
132 | } else if (argv[i][0] == '-') { |
133 | usage("Unknown command: %s", argv[i]); | |
134 | } else if (interfaces_requested < 0) { | |
135 | @@ -725,6 +736,19 @@ main(int argc, char **argv) { | |
136 | path_dhclient_script = s; | |
137 | } | |
138 | ||
6df985df SS |
139 | +#ifdef HAVE_LIBCAP_NG |
140 | + /* Drop capabilities */ | |
141 | + if (!keep_capabilities) { | |
142 | + capng_clear(CAPNG_SELECT_CAPS); | |
143 | + capng_update(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED, | |
144 | + CAP_DAC_OVERRIDE); // Drop this someday | |
145 | + capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED, | |
146 | + CAP_NET_ADMIN, CAP_NET_RAW, | |
147 | + CAP_NET_BIND_SERVICE, CAP_SYS_ADMIN, -1); | |
148 | + capng_apply(CAPNG_SELECT_CAPS); | |
149 | + } | |
150 | +#endif | |
151 | + | |
530cba5e SS |
152 | /* Set up the initial dhcp option universe. */ |
153 | initialize_common_option_spaces(); | |
154 | ||
155 | diff --git a/configure.ac b/configure.ac | |
156 | index a797438..15fc0d7 100644 | |
157 | --- a/configure.ac | |
158 | +++ b/configure.ac | |
159 | @@ -612,6 +612,41 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[void foo() __attribute__((noreturn)); | |
6df985df SS |
160 | # Look for optional headers. |
161 | AC_CHECK_HEADERS(sys/socket.h net/if_dl.h net/if6.h regex.h) | |
530cba5e | 162 | |
6df985df SS |
163 | +# look for capabilities library |
164 | +AC_ARG_WITH(libcap-ng, | |
165 | + [ --with-libcap-ng=[auto/yes/no] Add Libcap-ng support [default=auto]],, | |
166 | + with_libcap_ng=auto) | |
167 | + | |
168 | +# Check for Libcap-ng API | |
169 | +# | |
170 | +# libcap-ng detection | |
171 | +if test x$with_libcap_ng = xno ; then | |
172 | + have_libcap_ng=no; | |
173 | +else | |
174 | + # Start by checking for header file | |
175 | + AC_CHECK_HEADER(cap-ng.h, capng_headers=yes, capng_headers=no) | |
176 | + | |
177 | + # See if we have libcap-ng library | |
178 | + AC_CHECK_LIB(cap-ng, capng_clear, | |
179 | + CAPNG_LDADD=-lcap-ng,) | |
180 | + | |
181 | + # Check results are usable | |
182 | + if test x$with_libcap_ng = xyes -a x$CAPNG_LDADD = x ; then | |
183 | + AC_MSG_ERROR(libcap-ng support was requested and the library was not found) | |
184 | + fi | |
185 | + if test x$CAPNG_LDADD != x -a $capng_headers = no ; then | |
186 | + AC_MSG_ERROR(libcap-ng libraries found but headers are missing) | |
187 | + fi | |
188 | +fi | |
189 | +AC_SUBST(CAPNG_LDADD) | |
190 | +AC_MSG_CHECKING(whether to use libcap-ng) | |
191 | +if test x$CAPNG_LDADD != x ; then | |
192 | + AC_DEFINE(HAVE_LIBCAP_NG,1,[libcap-ng support]) | |
193 | + AC_MSG_RESULT(yes) | |
194 | +else | |
195 | + AC_MSG_RESULT(no) | |
196 | +fi | |
197 | + | |
198 | # Solaris needs some libraries for functions | |
199 | AC_SEARCH_LIBS(socket, [socket]) | |
200 | AC_SEARCH_LIBS(inet_ntoa, [nsl]) | |
530cba5e SS |
201 | diff --git a/relay/Makefile.am b/relay/Makefile.am |
202 | index 2ba5979..8900e0b 100644 | |
203 | --- a/relay/Makefile.am | |
204 | +++ b/relay/Makefile.am | |
205 | @@ -6,7 +6,8 @@ dhcrelay_LDADD = ../common/libdhcp.@A@ ../omapip/libomapi.@A@ \ | |
206 | @BINDLIBIRSDIR@/libirs.@A@ \ | |
207 | @BINDLIBDNSDIR@/libdns.@A@ \ | |
208 | @BINDLIBISCCFGDIR@/libisccfg.@A@ \ | |
209 | - @BINDLIBISCDIR@/libisc.@A@ | |
210 | + @BINDLIBISCDIR@/libisc.@A@ \ | |
211 | + $(CAPNG_LDADD) | |
212 | man_MANS = dhcrelay.8 | |
213 | EXTRA_DIST = $(man_MANS) | |
214 | ||
215 | diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c | |
216 | index ea1be18..7b4f4f1 100644 | |
217 | --- a/relay/dhcrelay.c | |
218 | +++ b/relay/dhcrelay.c | |
d8feb2d7 | 219 | @@ -32,6 +32,11 @@ |
6df985df | 220 | #include <sys/time.h> |
d8feb2d7 | 221 | #include <isc/file.h> |
530cba5e | 222 | |
6df985df SS |
223 | +#ifdef HAVE_LIBCAP_NG |
224 | +# include <cap-ng.h> | |
225 | + int keep_capabilities = 0; | |
226 | +#endif | |
227 | + | |
228 | TIME default_lease_time = 43200; /* 12 hours... */ | |
229 | TIME max_lease_time = 86400; /* 24 hours... */ | |
230 | struct tree_cache *global_options[256]; | |
530cba5e SS |
231 | @@ -590,6 +595,10 @@ main(int argc, char **argv) { |
232 | if (++i == argc) | |
233 | usage(use_noarg, argv[i-1]); | |
234 | dhcrelay_sub_id = argv[i]; | |
235 | +#endif | |
6df985df SS |
236 | + } else if (!strcmp(argv[i], "-nc")) { |
237 | +#ifdef HAVE_LIBCAP_NG | |
238 | + keep_capabilities = 1; | |
6df985df | 239 | #endif |
530cba5e SS |
240 | } else if (!strcmp(argv[i], "-pf")) { |
241 | if (++i == argc) | |
242 | @@ -660,6 +669,17 @@ main(int argc, char **argv) { | |
243 | #endif | |
244 | } | |
245 | ||
6df985df SS |
246 | +#ifdef HAVE_LIBCAP_NG |
247 | + /* Drop capabilities */ | |
248 | + if (!keep_capabilities) { | |
249 | + capng_clear(CAPNG_SELECT_BOTH); | |
250 | + capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED, | |
251 | + CAP_NET_RAW, CAP_NET_BIND_SERVICE, -1); | |
252 | + capng_apply(CAPNG_SELECT_BOTH); | |
253 | + log_info ("Dropped all unnecessary capabilities."); | |
254 | + } | |
255 | +#endif | |
256 | + | |
530cba5e SS |
257 | if (!quiet) { |
258 | log_info("%s %s", message, PACKAGE_VERSION); | |
259 | log_info(copyright); | |
260 | @@ -816,6 +836,15 @@ main(int argc, char **argv) { | |
261 | signal(SIGTERM, dhcp_signal_handler); /* kill */ | |
6df985df | 262 | #endif |
530cba5e | 263 | |
6df985df SS |
264 | +#ifdef HAVE_LIBCAP_NG |
265 | + /* Drop all capabilities */ | |
266 | + if (!keep_capabilities) { | |
267 | + capng_clear(CAPNG_SELECT_BOTH); | |
268 | + capng_apply(CAPNG_SELECT_BOTH); | |
269 | + log_info ("Dropped all capabilities."); | |
270 | + } | |
271 | +#endif | |
272 | + | |
530cba5e SS |
273 | /* Start dispatching packets and timeouts... */ |
274 | dispatch(); | |
275 | ||
276 | -- | |
277 | 2.14.5 |