Skip to contentSkip to conversation

Patch "fat: fix fake_offset handling on error path" has been added to the 3.14-stable tree

PATCH [email protected] 1 participant 1 message Feb 12, 2016

Subsystems (2)
lore
Share & tools
lore

[email protected]

author maintainer Applied
#0 lore raw

This is a note to let you know that I've just added the patch titled

fat: fix fake_offset handling on error path

to the 3.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
fat-fix-fake_offset-handling-on-error-path.patch
and it can be found in the queue-3.14 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

Quoted 1 line

From 928a477102c4fc6739883415b66987207e3502f4 Mon Sep 17 00:00:00 2001

From: OGAWA Hirofumi <[email protected]>
Date: Fri, 20 Nov 2015 15:57:15 -0800
Subject: fat: fix fake_offset handling on error path

From: OGAWA Hirofumi <[email protected]>

commit 928a477102c4fc6739883415b66987207e3502f4 upstream.

For the root directory, . and .. are faked (using dir_emit_dots()) and ctx->pos is reset from 2 to 0.

A corrupted root directory could cause fat_get_entry() to fail, but ->iterate() (fat_readdir()) reports progress to the VFS (with ctx->pos rewound to 0), so any following calls to ->iterate() continue to return the same entries again and again.

The result is that userspace will never see the end of the directory, causing e.g. 'ls' to hang in a getdents() loop.

---
 fs/fat/dir.c |   16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)
fs/fat/dir.c +11 -5
@@ -614,9 +614,9 @@ parse_record:
 		int status = fat_parse_long(inode, &cpos, &bh, &de,
 					    &unicode, &nr_slots);
 		if (status < 0) {
-			ctx->pos = cpos;
+			bh = NULL;
 			ret = status;
-			goto out;
+			goto end_of_dir;
 		} else if (status == PARSE_INVALID)
 			goto record_end;
 		else if (status == PARSE_NOT_LONGNAME)
@@ -658,8 +658,9 @@ parse_record:
 	fill_len = short_len;
 
 start_filldir:
-	if (!fake_offset)
-		ctx->pos = cpos - (nr_slots + 1) * sizeof(struct msdos_dir_entry);
+	ctx->pos = cpos - (nr_slots + 1) * sizeof(struct msdos_dir_entry);
+	if (fake_offset && ctx->pos < 2)
+		ctx->pos = 2;
 
 	if (!memcmp(de->name, MSDOS_DOT, MSDOS_NAME)) {
 		if (!dir_emit_dot(file, ctx))
@@ -685,14 +686,19 @@ record_end:
 	fake_offset = 0;
 	ctx->pos = cpos;
 	goto get_new;
+
 end_of_dir:
-	ctx->pos = cpos;
+	if (fake_offset && cpos < 2)
+		ctx->pos = 2;
+	else
+		ctx->pos = cpos;
 fill_failed:
 	brelse(bh);
 	if (unicode)
 		__putname(unicode);
 out:
 	mutex_unlock(&sbi->s_lock);
+
 	return ret;
 }
 

Patches currently in stable-queue which might be from [email protected] are

queue-3.14/fat-fix-fake_offset-handling-on-error-path.patch