Index: uspace/srv/devman/devman.c
===================================================================
--- uspace/srv/devman/devman.c	(revision eaf4c393435eff53dd64d01e7bd122a43ab6830f)
+++ uspace/srv/devman/devman.c	(revision d6b81941591c65c105ce919d408a42479a50a5d7)
@@ -266,9 +266,10 @@
 	}
 	
-	if (read(fd, buf, len) <= 0) {
+	ssize_t read_bytes = safe_read(fd, buf, len);
+	if (read_bytes <= 0) {
 		printf(NAME ": unable to read file '%s'.\n", conf_path);
 		goto cleanup;
 	}
-	buf[len] = 0;
+	buf[read_bytes] = 0;
 	
 	suc = parse_match_ids(buf, ids);
@@ -1123,4 +1124,11 @@
 fun_node_t *find_fun_node_by_path(dev_tree_t *tree, char *path)
 {
+	assert(path != NULL);
+
+	bool is_absolute = path[0] == '/';
+	if (!is_absolute) {
+		return NULL;
+	}
+
 	fibril_rwlock_read_lock(&tree->rwlock);
 	
@@ -1132,5 +1140,5 @@
 	char *rel_path = path;
 	char *next_path_elem = NULL;
-	bool cont = (rel_path[0] == '/');
+	bool cont = true;
 	
 	while (cont && fun != NULL) {
Index: uspace/srv/devman/main.c
===================================================================
--- uspace/srv/devman/main.c	(revision eaf4c393435eff53dd64d01e7bd122a43ab6830f)
+++ uspace/srv/devman/main.c	(revision d6b81941591c65c105ce919d408a42479a50a5d7)
@@ -477,5 +477,11 @@
 		dev = fun->dev;
 
-	if (fun == NULL && dev == NULL) {
+	/*
+	 * For a valid function to connect to we need a device. The root
+	 * function, for example, has no device and cannot be connected to.
+	 * This means @c dev needs to be valid regardless whether we are
+	 * connecting to a device or to a function.
+	 */
+	if (dev == NULL) {
 		printf(NAME ": devman_forward error - no device or function with "
 		    "handle %" PRIun " was found.\n", handle);
Index: uspace/srv/devman/util.c
===================================================================
--- uspace/srv/devman/util.c	(revision eaf4c393435eff53dd64d01e7bd122a43ab6830f)
+++ uspace/srv/devman/util.c	(revision d6b81941591c65c105ce919d408a42479a50a5d7)
@@ -111,4 +111,31 @@
 }
 
+ssize_t safe_read(int fd, void *buffer, size_t size)
+{
+	if (size == 0) {
+		return 0;
+	}
+
+	uint8_t *buf_ptr = (uint8_t *) buffer;
+
+	size_t total_read = 0;
+	while (total_read < size) {
+		ssize_t bytes_read = read(fd, buf_ptr, size - total_read);
+		if (bytes_read < 0) {
+			/* Error. */
+			return bytes_read;
+		} else if (bytes_read == 0) {
+			/* Possibly end of file. */
+			break;
+		} else {
+			/* Read at least something. */
+			buf_ptr += bytes_read;
+			total_read += bytes_read;
+		}
+	}
+
+	return (ssize_t) total_read;
+}
+
 /** @}
  */
Index: uspace/srv/devman/util.h
===================================================================
--- uspace/srv/devman/util.h	(revision eaf4c393435eff53dd64d01e7bd122a43ab6830f)
+++ uspace/srv/devman/util.h	(revision d6b81941591c65c105ce919d408a42479a50a5d7)
@@ -47,4 +47,6 @@
 extern void replace_char(char *, char, char);
 
+extern ssize_t safe_read(int, void *, size_t);
+
 #endif
 
Index: uspace/srv/hw/netif/ne2000/dp8390.c
===================================================================
--- uspace/srv/hw/netif/ne2000/dp8390.c	(revision eaf4c393435eff53dd64d01e7bd122a43ab6830f)
+++ uspace/srv/hw/netif/ne2000/dp8390.c	(revision d6b81941591c65c105ce919d408a42479a50a5d7)
@@ -391,4 +391,5 @@
 	
 	if ((size < ETH_MIN_PACK_SIZE) || (size > ETH_MAX_PACK_SIZE_TAGGED)) {
+		fibril_mutex_unlock(&ne2k->sq_mutex);
 		fprintf(stderr, "%s: Frame dropped (invalid size %zu bytes)\n",
 		    NAME, size);
Index: uspace/srv/net/il/arp/arp.c
===================================================================
--- uspace/srv/net/il/arp/arp.c	(revision eaf4c393435eff53dd64d01e7bd122a43ab6830f)
+++ uspace/srv/net/il/arp/arp.c	(revision d6b81941591c65c105ce919d408a42479a50a5d7)
@@ -157,9 +157,9 @@
 			
 			arp_clear_addr(&proto->addresses);
-			arp_addr_destroy(&proto->addresses);
-		}
-	}
-	
-	arp_protos_clear(&device->protos);
+			arp_addr_destroy(&proto->addresses, free);
+		}
+	}
+	
+	arp_protos_clear(&device->protos, free);
 }
 
@@ -184,5 +184,5 @@
 	}
 	
-	arp_cache_clear(&arp_globals.cache);
+	arp_cache_clear(&arp_globals.cache, free);
 	fibril_mutex_unlock(&arp_globals.lock);
 	
@@ -212,5 +212,5 @@
 		arp_clear_trans(trans);
 	
-	arp_addr_exclude(&proto->addresses, address->value, address->length);
+	arp_addr_exclude(&proto->addresses, address->value, address->length, free);
 	
 	fibril_mutex_unlock(&arp_globals.lock);
@@ -345,5 +345,5 @@
 			    header->protocol_length, trans);
 			if (rc != EOK) {
-				/* The generic char map has already freed trans! */
+				free(trans);
 				return rc;
 			}
@@ -556,5 +556,5 @@
 		if (index < 0) {
 			fibril_mutex_unlock(&arp_globals.lock);
-			arp_protos_destroy(&device->protos);
+			arp_protos_destroy(&device->protos, free);
 			free(device);
 			return index;
@@ -569,5 +569,5 @@
 		if (device->phone < 0) {
 			fibril_mutex_unlock(&arp_globals.lock);
-			arp_protos_destroy(&device->protos);
+			arp_protos_destroy(&device->protos, free);
 			free(device);
 			return EREFUSED;
@@ -579,5 +579,5 @@
 		if (rc != EOK) {
 			fibril_mutex_unlock(&arp_globals.lock);
-			arp_protos_destroy(&device->protos);
+			arp_protos_destroy(&device->protos, free);
 			free(device);
 			return rc;
@@ -589,5 +589,5 @@
 		if (rc != EOK) {
 			fibril_mutex_unlock(&arp_globals.lock);
-			arp_protos_destroy(&device->protos);
+			arp_protos_destroy(&device->protos, free);
 			free(device);
 			return rc;
@@ -601,5 +601,5 @@
 			free(device->addr);
 			free(device->addr_data);
-			arp_protos_destroy(&device->protos);
+			arp_protos_destroy(&device->protos, free);
 			free(device);
 			return rc;
@@ -614,5 +614,5 @@
 			free(device->broadcast_addr);
 			free(device->broadcast_data);
-			arp_protos_destroy(&device->protos);
+			arp_protos_destroy(&device->protos, free);
 			free(device);
 			return rc;
@@ -746,5 +746,5 @@
 			arp_clear_trans(trans);
 			arp_addr_exclude(&proto->addresses, target->value,
-			    target->length);
+			    target->length, free);
 			return EAGAIN;
 		}
@@ -794,5 +794,5 @@
 	    trans);
 	if (rc != EOK) {
-		/* The generic char map has already freed trans! */
+		free(trans);
 		return rc;
 	}
@@ -807,5 +807,5 @@
 		arp_clear_trans(trans);
 		arp_addr_exclude(&proto->addresses, target->value,
-		    target->length);
+		    target->length, free);
 		return ENOENT;
 	}
Index: uspace/srv/net/il/ip/ip.c
===================================================================
--- uspace/srv/net/il/ip/ip.c	(revision eaf4c393435eff53dd64d01e7bd122a43ab6830f)
+++ uspace/srv/net/il/ip/ip.c	(revision d6b81941591c65c105ce919d408a42479a50a5d7)
@@ -505,5 +505,5 @@
 	if (rc != EOK) {
 		fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
-		ip_routes_destroy(&ip_netif->routes);
+		ip_routes_destroy(&ip_netif->routes, free);
 		free(ip_netif);
 		return rc;
Index: uspace/srv/net/net/net.c
===================================================================
--- uspace/srv/net/net/net.c	(revision eaf4c393435eff53dd64d01e7bd122a43ab6830f)
+++ uspace/srv/net/net/net.c	(revision d6b81941591c65c105ce919d408a42479a50a5d7)
@@ -555,5 +555,5 @@
 		rc = read_netif_configuration(conf_files[i], netif);
 		if (rc != EOK) {
-			measured_strings_destroy(&netif->configuration);
+			measured_strings_destroy(&netif->configuration, free);
 			free(netif);
 			return rc;
@@ -565,5 +565,5 @@
 		if (!setting) {
 			fprintf(stderr, "%s: Network interface name is missing\n", NAME);
-			measured_strings_destroy(&netif->configuration);
+			measured_strings_destroy(&netif->configuration, free);
 			free(netif);
 			return EINVAL;
@@ -574,5 +574,5 @@
 		int index = netifs_add(&net_globals.netifs, netif->id, netif);
 		if (index < 0) {
-			measured_strings_destroy(&netif->configuration);
+			measured_strings_destroy(&netif->configuration, free);
 			free(netif);
 			return index;
@@ -586,6 +586,6 @@
 		    index);
 		if (rc != EOK) {
-			measured_strings_destroy(&netif->configuration);
-			netifs_exclude_index(&net_globals.netifs, index);
+			measured_strings_destroy(&netif->configuration, free);
+			netifs_exclude_index(&net_globals.netifs, index, free);
 			return rc;
 		}
@@ -595,6 +595,6 @@
 			printf("%s: Ignoring failed interface %s (%s)\n", NAME,
 			    netif->name, str_error(rc));
-			measured_strings_destroy(&netif->configuration);
-			netifs_exclude_index(&net_globals.netifs, index);
+			measured_strings_destroy(&netif->configuration, free);
+			netifs_exclude_index(&net_globals.netifs, index, free);
 			continue;
 		}
Index: uspace/srv/net/nil/eth/eth.c
===================================================================
--- uspace/srv/net/nil/eth/eth.c	(revision eaf4c393435eff53dd64d01e7bd122a43ab6830f)
+++ uspace/srv/net/nil/eth/eth.c	(revision d6b81941591c65c105ce919d408a42479a50a5d7)
@@ -214,5 +214,5 @@
 	if (rc != EOK) {
 		free(eth_globals.broadcast_addr);
-		eth_devices_destroy(&eth_globals.devices);
+		eth_devices_destroy(&eth_globals.devices, free);
 	}
 out:
Index: uspace/srv/net/tl/tcp/tcp.c
===================================================================
--- uspace/srv/net/tl/tcp/tcp.c	(revision eaf4c393435eff53dd64d01e7bd122a43ab6830f)
+++ uspace/srv/net/tl/tcp/tcp.c	(revision d6b81941591c65c105ce919d408a42479a50a5d7)
@@ -1707,5 +1707,5 @@
 		if (socket->port > 0) {
 			socket_ports_exclude(&tcp_globals.sockets,
-			    socket->port);
+			    socket->port, free);
 			socket->port = 0;
 		}
@@ -2492,5 +2492,5 @@
 	rc = packet_dimensions_initialize(&tcp_globals.dimensions);
 	if (rc != EOK) {
-		socket_ports_destroy(&tcp_globals.sockets);
+		socket_ports_destroy(&tcp_globals.sockets, free);
 		goto out;
 	}
Index: uspace/srv/net/tl/udp/udp.c
===================================================================
--- uspace/srv/net/tl/udp/udp.c	(revision eaf4c393435eff53dd64d01e7bd122a43ab6830f)
+++ uspace/srv/net/tl/udp/udp.c	(revision d6b81941591c65c105ce919d408a42479a50a5d7)
@@ -417,5 +417,5 @@
 	rc = packet_dimensions_initialize(&udp_globals.dimensions);
 	if (rc != EOK) {
-		socket_ports_destroy(&udp_globals.sockets);
+		socket_ports_destroy(&udp_globals.sockets, free);
 		fibril_rwlock_write_unlock(&udp_globals.lock);
 		return rc;
@@ -434,5 +434,5 @@
 	    &data);
 	if (rc != EOK) {
-		socket_ports_destroy(&udp_globals.sockets);
+		socket_ports_destroy(&udp_globals.sockets, free);
 		fibril_rwlock_write_unlock(&udp_globals.lock);
 		return rc;
