ANDROID: sdcardfs: ->iget fixes
authorDaniel Rosenberg <drosen@google.com>
Tue, 18 Apr 2017 19:45:48 +0000 (12:45 -0700)
committerStricted <info@stricted.net>
Thu, 11 Oct 2018 16:03:37 +0000 (18:03 +0200)
Adapted from wrapfs
commit 8c49eaa0sb9c ("Wrapfs: ->iget fixes")

Change where we igrab/iput to ensure we always hold a valid lower_inode.
Return ENOMEM (not EACCES) if iget5_locked returns NULL.

Signed-off-by: Erez Zadok <ezk@cs.sunysb.edu>
Signed-off-by: Daniel Rosenberg <drosen@google.com>
Bug: 35766959

Change-Id: Id8d4e0c0cbc685a0a77685ce73c923e9a3ddc094

fs/sdcardfs/lookup.c

index dcf54a3e644c344313821e0796570e080a471151..3ac40fead4908d7221504e3435b81f3470f86be9 100644 (file)
@@ -91,7 +91,9 @@ struct inode *sdcardfs_iget(struct super_block *sb, struct inode *lower_inode, u
        struct sdcardfs_inode_info *info;
        struct inode_data data;
        struct inode *inode; /* the new inode to return */
-       int err;
+
+       if (!igrab(lower_inode))
+               return ERR_PTR(-ESTALE);
 
        data.id = id;
        data.lower_inode = lower_inode;
@@ -106,22 +108,19 @@ struct inode *sdcardfs_iget(struct super_block *sb, struct inode *lower_inode, u
                             sdcardfs_inode_set, /* inode init function */
                             &data); /* data passed to test+set fxns */
        if (!inode) {
-               err = -EACCES;
                iput(lower_inode);
-               return ERR_PTR(err);
+               return ERR_PTR(-ENOMEM);
        }
-       /* if found a cached inode, then just return it */
-       if (!(inode->i_state & I_NEW))
+       /* if found a cached inode, then just return it (after iput) */
+       if (!(inode->i_state & I_NEW)) {
+               iput(lower_inode);
                return inode;
+       }
 
        /* initialize new inode */
        info = SDCARDFS_I(inode);
 
        inode->i_ino = lower_inode->i_ino;
-       if (!igrab(lower_inode)) {
-               err = -ESTALE;
-               return ERR_PTR(err);
-       }
        sdcardfs_set_lower_inode(inode, lower_inode);
 
        inode->i_version++;