[PATCH 2/2] sysfs: handle failure path correctly for readdir()

Subsystems: driver core, kobjects, debugfs and sysfs, filesystems (vfs and infrastructure), the rest

STALE4944d REVIEWED: 1 (0M)

1 review trailer.

2 messages, 2 authors, 2013-03-20 · open the first message on its own page

[PATCH 2/2] sysfs: handle failure path correctly for readdir()

From: Ming Lei <hidden>
Date: 2013-03-20 15:26:55

In case of 'if (filp->f_pos ==  0 or 1)' of sysfs_readdir(),
the failure from filldir() isn't handled, and the reference counter
of the sysfs_dirent object pointed by filp->private_data will be
released without clearing filp->private_data, so use after free
bug will be triggered later.

This patch returns immeadiately under the situation for fixing the bug,
and it is reasonable to return from readdir() when filldir() fails.

Reported-by: Dave Jones <redacted>
Tested-by: Sasha Levin <redacted>
Cc: <redacted>
Signed-off-by: Ming Lei <redacted>
---
 fs/sysfs/dir.c |    4 ++++
 1 file changed, 4 insertions(+)
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index c9e1660..e145126 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -1020,6 +1020,8 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
 		ino = parent_sd->s_ino;
 		if (filldir(dirent, ".", 1, filp->f_pos, ino, DT_DIR) == 0)
 			filp->f_pos++;
+		else
+			return 0;
 	}
 	if (filp->f_pos == 1) {
 		if (parent_sd->s_parent)
@@ -1028,6 +1030,8 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
 			ino = parent_sd->s_ino;
 		if (filldir(dirent, "..", 2, filp->f_pos, ino, DT_DIR) == 0)
 			filp->f_pos++;
+		else
+			return 0;
 	}
 	mutex_lock(&sysfs_mutex);
 	for (pos = sysfs_dir_pos(ns, parent_sd, filp->f_pos, pos);
-- 
1.7.9.5

Re: [PATCH 2/2] sysfs: handle failure path correctly for readdir()

From: Shuah Khan <hidden>
Date: 2013-03-20 16:26:48

On Wed, Mar 20, 2013 at 9:25 AM, Ming Lei [off-list ref] wrote:
quoted hunk
In case of 'if (filp->f_pos ==  0 or 1)' of sysfs_readdir(),
the failure from filldir() isn't handled, and the reference counter
of the sysfs_dirent object pointed by filp->private_data will be
released without clearing filp->private_data, so use after free
bug will be triggered later.

This patch returns immeadiately under the situation for fixing the bug,
and it is reasonable to return from readdir() when filldir() fails.

Reported-by: Dave Jones <redacted>
Tested-by: Sasha Levin <redacted>
Cc: <redacted>
Signed-off-by: Ming Lei <redacted>
---
 fs/sysfs/dir.c |    4 ++++
 1 file changed, 4 insertions(+)
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index c9e1660..e145126 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -1020,6 +1020,8 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
                ino = parent_sd->s_ino;
                if (filldir(dirent, ".", 1, filp->f_pos, ino, DT_DIR) == 0)
                        filp->f_pos++;
+               else
+                       return 0;
        }
        if (filp->f_pos == 1) {
                if (parent_sd->s_parent)
@@ -1028,6 +1030,8 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
                        ino = parent_sd->s_ino;
                if (filldir(dirent, "..", 2, filp->f_pos, ino, DT_DIR) == 0)
                        filp->f_pos++;
+               else
+                       return 0;
        }
Looks good to me. This is just an observation. readdir callers are
checking against NULL as opposed 0. Not a problem really probably
since NULL is defined as 0.

-- Shuah
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help