Index: uspace/srv/vfs/vfs.h
===================================================================
--- uspace/srv/vfs/vfs.h	(revision 9bb85f3480d8697d332ae4f46dabcd45bc5ab0c5)
+++ uspace/srv/vfs/vfs.h	(revision d6084ef92b6611a19749ebcfb70d5730dc0cb07b)
@@ -251,6 +251,5 @@
 extern int fs_name_to_handle(char *, bool);
 
-extern int vfs_lookup_internal(char *, size_t, int, vfs_lookup_res_t *,
-    vfs_pair_t *);
+extern int vfs_lookup_internal(char *, int, vfs_lookup_res_t *, vfs_pair_t *);
 
 extern bool vfs_nodes_init(void);
Index: uspace/srv/vfs/vfs_lookup.c
===================================================================
--- uspace/srv/vfs/vfs_lookup.c	(revision 9bb85f3480d8697d332ae4f46dabcd45bc5ab0c5)
+++ uspace/srv/vfs/vfs_lookup.c	(revision d6084ef92b6611a19749ebcfb70d5730dc0cb07b)
@@ -50,5 +50,5 @@
 
 /* Forward static declarations. */
-static char *canonify(char *path);
+static char *canonify(char *path, size_t *lenp);
 
 atomic_t plb_futex = FUTEX_INITIALIZER;
@@ -58,6 +58,6 @@
 /** Perform a path lookup.
  *
- * @param path		Path to be resolved; it needn't be an ASCIIZ string.
- * @param len		Number of path characters pointed by path.
+ * @param path		Path to be resolved; it must be a NULL-terminated
+ *			string.
  * @param lflag		Flags to be used during lookup.
  * @param result	Empty structure where the lookup result will be stored.
@@ -68,11 +68,8 @@
  * @return		EOK on success or an error code from errno.h.
  */
-int vfs_lookup_internal(char *path, size_t len, int lflag,
-    vfs_lookup_res_t *result, vfs_pair_t *altroot)
+int vfs_lookup_internal(char *path, int lflag, vfs_lookup_res_t *result,
+    vfs_pair_t *altroot)
 {
 	vfs_pair_t *root;
-
-	if (!len)
-		return EINVAL;
 
 	if (altroot)
@@ -83,4 +80,9 @@
 	if (!root->fs_handle)
 		return ENOENT;
+	
+	size_t len;
+	path = canonify(path, &len);
+	if (!path)
+		return EINVAL;
 	
 	futex_down(&plb_futex);
@@ -274,5 +276,6 @@
 static void terminate_slash(token_t *t, token_t *tfsl, token_t *tlcomp)
 {
-	tfsl->stop[1] = '\0';
+	if (tfsl->stop[1])	/* avoid writing to a well-formatted path */
+		tfsl->stop[1] = '\0';
 }
 static void remove_trailing_slash(token_t *t, token_t *tfsl, token_t *tlcomp)
@@ -435,9 +438,11 @@
  * It works in-place and requires a NULL-terminated input string.
  *
- * @param		Path to be canonified.
+ * @param path		Path to be canonified.
+ * @param lenp		Pointer where the length of the final path will be
+ *			stored. Can be NULL.
  *
  * @return		Canonified path or NULL on failure.
  */
-char *canonify(char *path)
+char *canonify(char *path, size_t *lenp)
 {
 	state_t state;
@@ -451,4 +456,5 @@
 	state = S_INI;
 	t = tfsl;
+	tlcomp = tfsl;
 	while (state != S_ACCEPT && state != S_RESTART && state != S_REJECT) {
 		if (trans[state][t.kind].f)
@@ -464,4 +470,6 @@
 		return NULL;
 	case S_ACCEPT:
+		if (lenp)
+			*lenp = (size_t)((tlcomp.stop - tfsl.start) + 1);
 		return tfsl.start; 
 	default:
Index: uspace/srv/vfs/vfs_ops.c
===================================================================
--- uspace/srv/vfs/vfs_ops.c	(revision 9bb85f3480d8697d332ae4f46dabcd45bc5ab0c5)
+++ uspace/srv/vfs/vfs_ops.c	(revision d6084ef92b6611a19749ebcfb70d5730dc0cb07b)
@@ -76,6 +76,5 @@
 	};
 
-	return vfs_lookup_internal("/", strlen("/"), L_DIRECTORY, result,
-	    &altroot);
+	return vfs_lookup_internal("/", L_DIRECTORY, result, &altroot);
 }
 
@@ -150,5 +149,5 @@
 	/* Allocate buffer for the mount point data being received. */
 	uint8_t *buf;
-	buf = malloc(size);
+	buf = malloc(size + 1);
 	if (!buf) {
 		ipc_answer_0(callid, ENOMEM);
@@ -159,4 +158,5 @@
 	/* Deliver the mount point. */
 	(void) ipc_data_write_finalize(callid, buf, size);
+	buf[size] = '\0';
 
 	/*
@@ -187,6 +187,5 @@
 		/* We already have the root FS. */
 		rwlock_write_lock(&namespace_rwlock);
-		rc = vfs_lookup_internal(buf, size, L_DIRECTORY, &mp_res,
-		    NULL);
+		rc = vfs_lookup_internal(buf, L_DIRECTORY, &mp_res, NULL);
 		if (rc != EOK) {
 			/* The lookup failed for some reason. */
@@ -315,5 +314,5 @@
 	 * directly into the PLB using some kind of a callback.
 	 */
-	char *path = malloc(len);
+	char *path = malloc(len + 1);
 	
 	if (!path) {
@@ -329,4 +328,5 @@
 		return;
 	}
+	path[len] = '\0';
 	
 	/*
@@ -342,5 +342,5 @@
 	/* The path is now populated and we can call vfs_lookup_internal(). */
 	vfs_lookup_res_t lr;
-	rc = vfs_lookup_internal(path, len, lflag, &lr, NULL);
+	rc = vfs_lookup_internal(path, lflag, &lr, NULL);
 	if (rc) {
 		if (lflag & L_CREATE)
@@ -637,5 +637,5 @@
 	 * directly into the PLB using some kind of a callback.
 	 */
-	char *path = malloc(len);
+	char *path = malloc(len + 1);
 	
 	if (!path) {
@@ -651,8 +651,9 @@
 		return;
 	}
+	path[len] = '\0';
 	
 	rwlock_write_lock(&namespace_rwlock);
 	int lflag = L_DIRECTORY | L_CREATE | L_EXCLUSIVE;
-	rc = vfs_lookup_internal(path, len, lflag, NULL, NULL);
+	rc = vfs_lookup_internal(path, lflag, NULL, NULL);
 	rwlock_write_unlock(&namespace_rwlock);
 	free(path);
@@ -679,5 +680,5 @@
 	 * directly into the PLB using some kind of a callback.
 	 */
-	char *path = malloc(len);
+	char *path = malloc(len + 1);
 	
 	if (!path) {
@@ -693,9 +694,10 @@
 		return;
 	}
+	path[len] = '\0';
 	
 	rwlock_write_lock(&namespace_rwlock);
 	lflag &= L_DIRECTORY;	/* sanitize lflag */
 	vfs_lookup_res_t lr;
-	rc = vfs_lookup_internal(path, len, lflag | L_DESTROY, &lr, NULL);
+	rc = vfs_lookup_internal(path, lflag | L_DESTROY, &lr, NULL);
 	free(path);
 	if (rc != EOK) {
