libmount: fix mtab update for "none" source, fix leak

tab_parse.c:mnt_parse_mountinfo_line parses "none" in src as NULL,

tab_update.c:fprintf_mtab_fs sets m1 to NULL instead of "none" and
returns -ENOMEM
tab_update.c:update_table says "write entry failed: Success", as errno
hasn't been set, and gotos to leave, leaving mtab not updated.

Addresses-debian-bug: 634871
Reported-by: Tomas Janousek <tomi@nomi.cz>
Signed-off-by: Karel Zak <kzak@redhat.com>
diff --git a/shlibs/mount/src/fs.c b/shlibs/mount/src/fs.c
index 91d8d22..d5bd167 100644
--- a/shlibs/mount/src/fs.c
+++ b/shlibs/mount/src/fs.c
@@ -297,10 +297,11 @@
 
 	assert(fs);
 
-	if (source && !strcmp(source, "none"))
+	if (source && !strcmp(source, "none")) {
+		free(source);
 		source = NULL;
-
-	if (source && strchr(source, '=')) {
+	}
+	else if (source && strchr(source, '=')) {
 		if (blkid_parse_tag_string(source, &t, &v) != 0)
 			return -1;
 	}
diff --git a/shlibs/mount/src/tab_update.c b/shlibs/mount/src/tab_update.c
index 7617df8..3666d76 100644
--- a/shlibs/mount/src/tab_update.c
+++ b/shlibs/mount/src/tab_update.c
@@ -480,20 +480,21 @@
 static int fprintf_mtab_fs(FILE *f, struct libmnt_fs *fs)
 {
 	char *o;
+	const char *src, *fstype;
 	char *m1, *m2, *m3, *m4;
 	int rc;
 
 	assert(fs);
 	assert(f);
 
+	src = mnt_fs_get_source(fs);
+	fstype = mnt_fs_get_fstype(fs);
 	o = mnt_fs_strdup_options(fs);
-	if (!o)
-		return -ENOMEM;
 
-	m1 = mangle(mnt_fs_get_source(fs));
+	m1 = src ? mangle(src) : "none";
 	m2 = mangle(mnt_fs_get_target(fs));
-	m3 = mangle(mnt_fs_get_fstype(fs));
-	m4 = mangle(o);
+	m3 = fstype ? mangle(fstype) : "none";
+	m4 = o ? mangle(o) : "rw";
 
 	if (m1 && m2 && m3 && m4) {
 		rc = fprintf(f, "%s %s %s %s %d %d\n",
@@ -505,11 +506,15 @@
 	} else
 		rc = -ENOMEM;
 
-	free(o);
-	free(m1);
+	if (src)
+		free(m1);
 	free(m2);
-	free(m3);
-	free(m4);
+	if (fstype)
+		free(m3);
+	if (o) {
+		free(m4);
+		free(o);
+	}
 
 	return rc;
 }
diff --git a/tests/ts/libmount/update b/tests/ts/libmount/update
index db03693..0223fcf 100755
--- a/tests/ts/libmount/update
+++ b/tests/ts/libmount/update
@@ -34,6 +34,7 @@
 $TESTPROG --add /dev/sdb1 /mnt/bar ext3 "gg=G,ffff=f,ro,noatime"
 $TESTPROG --add /dev/sda2 /mnt/bar ext3 "rw,noatime"
 $TESTPROG --add /dev/sda1 /mnt/gogo ext3 "rw,noatime,nosuid"
+$TESTPROG --add none /proc proc "defaults"
 cp $LIBMOUNT_MTAB $TS_OUTPUT	# save the mtab aside
 ts_finalize_subtest		# checks the mtab