Re: [patch 2/4] jffs2: fix unbalanced locking

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Li / Andrew,

On Wed, Feb 12, 2014 at 12:44:55PM -0800, Andrew Morton wrote:
> From: Li Zefan <lizefan@xxxxxxxxxx>
> Subject: jffs2: fix unbalanced locking
> 
> This was found by our internal debugging feature on runtime, but this bug
> won't lead to deadlock, as the structure that this lock is embedded in is
> freed on error.

Well, one of its callers frees it without unlocking it, but you're
forgetting about one of its other callers, and in doing so, you are
introducing a potential double-unlock instead!

Look at
  jffs2_iget()
  |_ mutex_lock(&f->sem)
  |_ jffs2_do_read_inode()
  |  |_ jffs2_do_read_inode_internal()
  |_ mutex_unlock(&f->sem)

jffs2_iget() already has the proper locking for f->sem, but with your
patch, you're turning this into a double-unlock in the error case.

So unless I'm mistaken, I'll give a NAK to this patch. It's one of those
patches generated by automated testing that has no practical value, but
rather has the potential to cause more bugs.

BTW, the right way to handle lock balancing is to handle the unlocking
at the same level where you do the locking. So I guess you're looking
for the following patch instead, which is really not very useful because
(as Li noted) the lock is freed immediately afterward anyway:

diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c
index 386303dca382..d28e6eafce05 100644
--- a/fs/jffs2/readinode.c
+++ b/fs/jffs2/readinode.c
@@ -1400,8 +1400,8 @@ int jffs2_do_crccheck_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *i
 	f->inocache = ic;
 
 	ret = jffs2_do_read_inode_internal(c, f, &n);
+	mutex_unlock(&f->sem);
 	if (!ret) {
-		mutex_unlock(&f->sem);
 		jffs2_do_clear_inode(c, f);
 	}
 	jffs2_xattr_do_crccheck_inode(c, ic);

> Signed-off-by: Li Zefan <lizefan@xxxxxxxxxx>
> Cc: David Woodhouse <dwmw2@xxxxxxxxxxxxx>
> Cc: Brian Norris <computersforpeace@xxxxxxxxx>
> Cc: Artem Bityutskiy <artem.bityutskiy@xxxxxxxxxxxxxxx>
> Cc: <stable@xxxxxxxxxxxxxxx>
> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
> ---
> 
>  fs/jffs2/readinode.c |    3 +++
>  1 file changed, 3 insertions(+)
> 
> diff -puN fs/jffs2/readinode.c~jffs2-fix-unbalanced-locking fs/jffs2/readinode.c
> --- a/fs/jffs2/readinode.c~jffs2-fix-unbalanced-locking
> +++ a/fs/jffs2/readinode.c
> @@ -1143,6 +1143,7 @@ static int jffs2_do_read_inode_internal(
>  		JFFS2_ERROR("cannot read nodes for ino %u, returned error is %d\n", f->inocache->ino, ret);
>  		if (f->inocache->state == INO_STATE_READING)
>  			jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT);
> +		mutex_unlock(&f->sem);
>  		return ret;
>  	}
>  
> @@ -1159,6 +1160,7 @@ static int jffs2_do_read_inode_internal(
>  			jffs2_free_tmp_dnode_info(rii.mdata_tn);
>  			rii.mdata_tn = NULL;
>  		}
> +		mutex_unlock(&f->sem);
>  		return ret;
>  	}
>  
> @@ -1183,6 +1185,7 @@ static int jffs2_do_read_inode_internal(
>  			if (!rii.fds) {
>  				if (f->inocache->state == INO_STATE_READING)
>  					jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT);
> +				mutex_unlock(&f->sem);
>  				return -EIO;
>  			}
>  			JFFS2_NOTICE("but it has children so we fake some modes for it\n");
> _

Brian
--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]