chiark / gitweb /
networkd: fix use-after-free
[elogind.git] / src / network / networkd-manager.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2013 Tom Gundersen <teg@jklm.no>
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20  ***/
21
22 #include <sys/socket.h>
23 #include <linux/if.h>
24
25 #include "conf-parser.h"
26 #include "path-util.h"
27 #include "networkd.h"
28 #include "networkd-netdev.h"
29 #include "networkd-link.h"
30 #include "network-internal.h"
31 #include "libudev-private.h"
32 #include "udev-util.h"
33 #include "rtnl-util.h"
34 #include "mkdir.h"
35 #include "virt.h"
36
37 #include "sd-rtnl.h"
38
39 const char* const network_dirs[] = {
40         "/etc/systemd/network",
41         "/run/systemd/network",
42         "/usr/lib/systemd/network",
43 #ifdef HAVE_SPLIT_USR
44         "/lib/systemd/network",
45 #endif
46         NULL};
47
48 static int setup_default_address_pool(Manager *m) {
49         AddressPool *p;
50         int r;
51
52         assert(m);
53
54         /* Add in the well-known private address ranges. */
55
56         r = address_pool_new_from_string(m, &p, AF_INET6, "fc00::", 7);
57         if (r < 0)
58                 return r;
59
60         r = address_pool_new_from_string(m, &p, AF_INET, "192.168.0.0", 16);
61         if (r < 0)
62                 return r;
63
64         r = address_pool_new_from_string(m, &p, AF_INET, "172.16.0.0", 12);
65         if (r < 0)
66                 return r;
67
68         r = address_pool_new_from_string(m, &p, AF_INET, "10.0.0.0", 8);
69         if (r < 0)
70                 return r;
71
72         return 0;
73 }
74
75 int manager_new(Manager **ret) {
76         _cleanup_manager_free_ Manager *m = NULL;
77         int r;
78
79         m = new0(Manager, 1);
80         if (!m)
81                 return -ENOMEM;
82
83         m->state_file = strdup("/run/systemd/netif/state");
84         if (!m->state_file)
85                 return -ENOMEM;
86
87         r = sd_event_default(&m->event);
88         if (r < 0)
89                 return r;
90
91         sd_event_set_watchdog(m->event, true);
92
93         sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL);
94         sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL);
95
96         r = sd_rtnl_open(&m->rtnl, 3, RTNLGRP_LINK, RTNLGRP_IPV4_IFADDR,
97                          RTNLGRP_IPV6_IFADDR);
98         if (r < 0)
99                 return r;
100
101         r = sd_bus_default_system(&m->bus);
102         if (r < 0 && r != -ENOENT) /* TODO: drop when we can rely on kdbus */
103                 return r;
104
105         /* udev does not initialize devices inside containers,
106          * so we rely on them being already initialized before
107          * entering the container */
108         if (detect_container(NULL) <= 0) {
109                 m->udev = udev_new();
110                 if (!m->udev)
111                         return -ENOMEM;
112
113                 m->udev_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
114                 if (!m->udev_monitor)
115                         return -ENOMEM;
116         }
117
118         m->netdevs = hashmap_new(string_hash_func, string_compare_func);
119         if (!m->netdevs)
120                 return -ENOMEM;
121
122         LIST_HEAD_INIT(m->networks);
123
124         r = setup_default_address_pool(m);
125         if (r < 0)
126                 return r;
127
128         *ret = m;
129         m = NULL;
130
131         return 0;
132 }
133
134 void manager_free(Manager *m) {
135         Network *network;
136         NetDev *netdev;
137         Link *link;
138         AddressPool *pool;
139
140         if (!m)
141                 return;
142
143         free(m->state_file);
144
145         udev_monitor_unref(m->udev_monitor);
146         udev_unref(m->udev);
147         sd_bus_unref(m->bus);
148         sd_event_source_unref(m->udev_event_source);
149         sd_event_source_unref(m->sigterm_event_source);
150         sd_event_source_unref(m->sigint_event_source);
151         sd_event_unref(m->event);
152
153         while ((link = hashmap_first(m->links)))
154                 link_unref(link);
155         hashmap_free(m->links);
156
157         while ((network = m->networks))
158                 network_free(network);
159
160         while ((netdev = hashmap_first(m->netdevs)))
161                 netdev_unref(netdev);
162         hashmap_free(m->netdevs);
163
164         while ((pool = m->address_pools))
165                 address_pool_free(pool);
166
167         sd_rtnl_unref(m->rtnl);
168
169         free(m);
170 }
171
172 int manager_load_config(Manager *m) {
173         int r;
174
175         /* update timestamp */
176         paths_check_timestamp(network_dirs, &m->network_dirs_ts_usec, true);
177
178         r = netdev_load(m);
179         if (r < 0)
180                 return r;
181
182         r = network_load(m);
183         if (r < 0)
184                 return r;
185
186         return 0;
187 }
188
189 bool manager_should_reload(Manager *m) {
190         return paths_check_timestamp(network_dirs, &m->network_dirs_ts_usec, false);
191 }
192
193 static int manager_udev_process_link(Manager *m, struct udev_device *device) {
194         Link *link = NULL;
195         int r, ifindex;
196
197         assert(m);
198         assert(device);
199
200         if (!streq_ptr(udev_device_get_action(device), "add"))
201                 return 0;
202
203         ifindex = udev_device_get_ifindex(device);
204         if (ifindex <= 0) {
205                 log_debug("ignoring udev ADD event for device with invalid ifindex");
206                 return 0;
207         }
208
209         r = link_get(m, ifindex, &link);
210         if (r == -ENODEV)
211                 return 0;
212         else if (r < 0)
213                 return r;
214
215         r = link_initialized(link, device);
216         if (r < 0)
217                 return r;
218
219         return 0;
220 }
221
222 static int manager_rtnl_process_link(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata) {
223         Manager *m = userdata;
224         Link *link = NULL;
225         NetDev *netdev = NULL;
226         uint16_t type;
227         const char *name;
228         int r, ifindex;
229
230         assert(rtnl);
231         assert(message);
232         assert(m);
233
234         r = sd_rtnl_message_get_type(message, &type);
235         if (r < 0) {
236                 log_warning("rtnl: could not get message type");
237                 return 0;
238         }
239
240         r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
241         if (r < 0 || ifindex <= 0) {
242                 log_warning("rtnl: received link message without valid ifindex");
243                 return 0;
244         } else
245                 link_get(m, ifindex, &link);
246
247         r = sd_rtnl_message_read_string(message, IFLA_IFNAME, &name);
248         if (r < 0 || !name) {
249                 log_warning("rtnl: received link message without valid ifname");
250                 return 0;
251         } else
252                 netdev_get(m, name, &netdev);
253
254         switch (type) {
255         case RTM_NEWLINK:
256                 if (!link) {
257                         /* link is new, so add it */
258                         r = link_add(m, message, &link);
259                         if (r < 0) {
260                                 log_debug("could not add new link: %s",
261                                            strerror(-r));
262                                 return 0;
263                         }
264                 }
265
266                 if (netdev) {
267                         /* netdev exists, so make sure the ifindex matches */
268                         r = netdev_set_ifindex(netdev, message);
269                         if (r < 0) {
270                                 log_debug("could not set ifindex on netdev");
271                                 return 0;
272                         }
273                 }
274
275                 r = link_update(link, message);
276                 if (r < 0)
277                         return 0;
278
279                 break;
280
281         case RTM_DELLINK:
282                 link_drop(link);
283                 netdev_drop(netdev);
284
285                 break;
286
287         default:
288                 assert_not_reached("Received invalid RTNL message type.");
289         }
290
291         return 1;
292 }
293
294 int manager_rtnl_enumerate_links(Manager *m) {
295         _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
296         sd_rtnl_message *link;
297         int r, k;
298
299         assert(m);
300         assert(m->rtnl);
301
302         r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0);
303         if (r < 0)
304                 return r;
305
306         r = sd_rtnl_message_request_dump(req, true);
307         if (r < 0)
308                 return r;
309
310         r = sd_rtnl_call(m->rtnl, req, 0, &reply);
311         if (r < 0)
312                 return r;
313
314         for (link = reply; link; link = sd_rtnl_message_next(link)) {
315                 uint16_t type;
316
317                 k = sd_rtnl_message_get_type(link, &type);
318                 if (k < 0)
319                         return k;
320
321                 if (type != RTM_NEWLINK)
322                         continue;
323
324                 k = manager_rtnl_process_link(m->rtnl, link, m);
325                 if (k < 0)
326                         r = k;
327         }
328
329         return r;
330 }
331
332 static int manager_dispatch_link_udev(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
333         Manager *m = userdata;
334         struct udev_monitor *monitor = m->udev_monitor;
335         _cleanup_udev_device_unref_ struct udev_device *device = NULL;
336
337         device = udev_monitor_receive_device(monitor);
338         if (!device)
339                 return -ENOMEM;
340
341         manager_udev_process_link(m, device);
342         return 0;
343 }
344
345 int manager_udev_listen(Manager *m) {
346         int r;
347
348         if (detect_container(NULL) > 0)
349                 return 0;
350
351         assert(m->udev_monitor);
352
353         r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_monitor, "net", NULL);
354         if (r < 0) {
355                 log_error("Could not add udev monitor filter: %s", strerror(-r));
356                 return r;
357         }
358
359         r = udev_monitor_enable_receiving(m->udev_monitor);
360         if (r < 0) {
361                 log_error("Could not enable udev monitor");
362                 return r;
363         }
364
365         r = sd_event_add_io(m->event,
366                         &m->udev_event_source,
367                         udev_monitor_get_fd(m->udev_monitor),
368                         EPOLLIN, manager_dispatch_link_udev,
369                         m);
370         if (r < 0)
371                 return r;
372
373         return 0;
374 }
375
376 int manager_rtnl_listen(Manager *m) {
377         int r;
378
379         assert(m);
380
381         r = sd_rtnl_attach_event(m->rtnl, m->event, 0);
382         if (r < 0)
383                 return r;
384
385         r = sd_rtnl_add_match(m->rtnl, RTM_NEWLINK, &manager_rtnl_process_link, m);
386         if (r < 0)
387                 return r;
388
389         r = sd_rtnl_add_match(m->rtnl, RTM_DELLINK, &manager_rtnl_process_link, m);
390         if (r < 0)
391                 return r;
392
393         r = sd_rtnl_add_match(m->rtnl, RTM_NEWADDR, &link_rtnl_process_address, m);
394         if (r < 0)
395                 return r;
396
397         r = sd_rtnl_add_match(m->rtnl, RTM_DELADDR, &link_rtnl_process_address, m);
398         if (r < 0)
399                 return r;
400
401         return 0;
402 }
403
404 int manager_bus_listen(Manager *m) {
405         int r;
406
407         assert(m->event);
408
409         if (!m->bus) /* TODO: drop when we can rely on kdbus */
410                 return 0;
411
412         r = sd_bus_attach_event(m->bus, m->event, 0);
413         if (r < 0)
414                 return r;
415
416         return 0;
417 }
418
419 static int set_put_in_addr(Set *s, const struct in_addr *address) {
420         char *p;
421         int r;
422
423         assert(s);
424
425         r = in_addr_to_string(AF_INET, (const union in_addr_union*) address, &p);
426         if (r < 0)
427                 return r;
428
429         r = set_consume(s, p);
430         if (r == -EEXIST)
431                 return 0;
432
433         return r;
434 }
435
436 static int set_put_in_addrv(Set *s, const struct in_addr *addresses, int n) {
437         int r, i, c = 0;
438
439         assert(s);
440         assert(n <= 0 || addresses);
441
442         for (i = 0; i < n; i++) {
443                 r = set_put_in_addr(s, addresses+i);
444                 if (r < 0)
445                         return r;
446
447                 c += r;
448         }
449
450         return c;
451 }
452
453 static void print_string_set(FILE *f, const char *field, Set *s) {
454         bool space = false;
455         Iterator i;
456         char *p;
457
458         if (set_isempty(s))
459                 return;
460
461         fputs(field, f);
462
463         SET_FOREACH(p, s, i) {
464                 if (space)
465                         fputc(' ', f);
466                 fputs(p, f);
467                 space = true;
468         }
469         fputc('\n', f);
470 }
471
472 int manager_save(Manager *m) {
473         _cleanup_set_free_free_ Set *dns = NULL, *ntp = NULL, *domains = NULL;
474         Link *link;
475         Iterator i;
476         _cleanup_free_ char *temp_path = NULL;
477         _cleanup_fclose_ FILE *f = NULL;
478         LinkOperationalState operstate = LINK_OPERSTATE_OFF;
479         const char *operstate_str;
480         int r;
481
482         assert(m);
483         assert(m->state_file);
484
485         /* We add all NTP and DNS server to a set, to filter out duplicates */
486         dns = set_new(string_hash_func, string_compare_func);
487         if (!dns)
488                 return -ENOMEM;
489
490         ntp = set_new(string_hash_func, string_compare_func);
491         if (!ntp)
492                 return -ENOMEM;
493
494         domains = set_new(string_hash_func, string_compare_func);
495         if (!domains)
496                 return -ENOMEM;
497
498         HASHMAP_FOREACH(link, m->links, i) {
499                 if (link->flags & IFF_LOOPBACK)
500                         continue;
501
502                 if (link->operstate > operstate)
503                         operstate = link->operstate;
504
505                 if (!link->network)
506                         continue;
507
508                 /* First add the static configured entries */
509                 r = set_put_strdupv(dns, link->network->dns);
510                 if (r < 0)
511                         return r;
512
513                 r = set_put_strdupv(ntp, link->network->ntp);
514                 if (r < 0)
515                         return r;
516
517                 r = set_put_strdupv(domains, link->network->domains);
518                 if (r < 0)
519                         return r;
520
521                 if (!link->dhcp_lease)
522                         continue;
523
524                 /* Secondly, add the entries acquired via DHCP */
525                 if (link->network->dhcp_dns) {
526                         const struct in_addr *addresses;
527
528                         r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
529                         if (r > 0) {
530                                 r = set_put_in_addrv(dns, addresses, r);
531                                 if (r < 0)
532                                         return r;
533                         } else if (r < 0 && r != -ENOENT)
534                                 return r;
535                 }
536
537                 if (link->network->dhcp_ntp) {
538                         const struct in_addr *addresses;
539
540                         r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
541                         if (r > 0) {
542                                 r = set_put_in_addrv(ntp, addresses, r);
543                                 if (r < 0)
544                                         return r;
545                         } else if (r < 0 && r != -ENOENT)
546                                 return r;
547                 }
548
549                 if (link->network->dhcp_domains) {
550                         const char *domainname;
551
552                         r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname);
553                         if (r >= 0) {
554                                 r = set_put_strdup(domains, domainname);
555                                 if (r < 0)
556                                         return r;
557                         } else if (r != -ENOENT)
558                                 return r;
559                 }
560         }
561
562         operstate_str = link_operstate_to_string(operstate);
563         assert(operstate_str);
564
565         r = fopen_temporary(m->state_file, &f, &temp_path);
566         if (r < 0)
567                 return r;
568
569         fchmod(fileno(f), 0644);
570
571         fprintf(f,
572                 "# This is private data. Do not parse.\n"
573                 "OPER_STATE=%s\n", operstate_str);
574
575         print_string_set(f, "DNS=", dns);
576         print_string_set(f, "NTP=", ntp);
577         print_string_set(f, "DOMAINS=", domains);
578
579         r = fflush_and_check(f);
580         if (r < 0)
581                 goto fail;
582
583         if (rename(temp_path, m->state_file) < 0) {
584                 r = -errno;
585                 goto fail;
586         }
587
588         return 0;
589
590 fail:
591         log_error("Failed to save network state to %s: %s", m->state_file, strerror(-r));
592         unlink(m->state_file);
593         unlink(temp_path);
594         return r;
595 }
596
597 int manager_address_pool_acquire(Manager *m, int family, unsigned prefixlen, union in_addr_union *found) {
598         AddressPool *p;
599         int r;
600
601         assert(m);
602         assert(prefixlen > 0);
603         assert(found);
604
605         LIST_FOREACH(address_pools, p, m->address_pools) {
606                 if (p->family != family)
607                         continue;
608
609                 r = address_pool_acquire(p, prefixlen, found);
610                 if (r != 0)
611                         return r;
612         }
613
614         return 0;
615 }