[PATCH 4.4 56/63] staging: android: ashmem: Fix lockdep issue during llseek

2018-03-16 Thread Greg Kroah-Hartman
4.4-stable review patch.  If anyone has any objections, please let me know.

--

From: Joel Fernandes 

commit cb57469c9573f6018cd1302953dd45d6e05aba7b upstream.

ashmem_mutex create a chain of dependencies like so:

(1)
mmap syscall ->
  mmap_sem ->  (acquired)
  ashmem_mmap
  ashmem_mutex (try to acquire)
  (block)

(2)
llseek syscall ->
  ashmem_llseek ->
  ashmem_mutex ->  (acquired)
  inode_lock ->
  inode->i_rwsem (try to acquire)
  (block)

(3)
getdents ->
  iterate_dir ->
  inode_lock ->
  inode->i_rwsem   (acquired)
  copy_to_user ->
  mmap_sem (try to acquire)

There is a lock ordering created between mmap_sem and inode->i_rwsem
causing a lockdep splat [2] during a syzcaller test, this patch fixes
the issue by unlocking the mutex earlier. Functionally that's Ok since
we don't need to protect vfs_llseek.

[1] https://patchwork.kernel.org/patch/10185031/
[2] https://lkml.org/lkml/2018/1/10/48

Acked-by: Todd Kjos 
Cc: Arve Hjonnevag 
Cc: sta...@vger.kernel.org
Reported-by: syzbot+8ec30bb7bf1a981a2...@syzkaller.appspotmail.com
Signed-off-by: Joel Fernandes 
Acked-by: Greg Hackmann 
Signed-off-by: Greg Kroah-Hartman 

---
 drivers/staging/android/ashmem.c |   15 +++
 1 file changed, 7 insertions(+), 8 deletions(-)

--- a/drivers/staging/android/ashmem.c
+++ b/drivers/staging/android/ashmem.c
@@ -330,24 +330,23 @@ static loff_t ashmem_llseek(struct file
mutex_lock(_mutex);
 
if (asma->size == 0) {
-   ret = -EINVAL;
-   goto out;
+   mutex_unlock(_mutex);
+   return -EINVAL;
}
 
if (!asma->file) {
-   ret = -EBADF;
-   goto out;
+   mutex_unlock(_mutex);
+   return -EBADF;
}
 
+   mutex_unlock(_mutex);
+
ret = vfs_llseek(asma->file, offset, origin);
if (ret < 0)
-   goto out;
+   return ret;
 
/** Copy f_pos from backing file, since f_ops->llseek() sets it */
file->f_pos = asma->file->f_pos;
-
-out:
-   mutex_unlock(_mutex);
return ret;
 }
 




[PATCH 4.4 56/63] staging: android: ashmem: Fix lockdep issue during llseek

2018-03-16 Thread Greg Kroah-Hartman
4.4-stable review patch.  If anyone has any objections, please let me know.

--

From: Joel Fernandes 

commit cb57469c9573f6018cd1302953dd45d6e05aba7b upstream.

ashmem_mutex create a chain of dependencies like so:

(1)
mmap syscall ->
  mmap_sem ->  (acquired)
  ashmem_mmap
  ashmem_mutex (try to acquire)
  (block)

(2)
llseek syscall ->
  ashmem_llseek ->
  ashmem_mutex ->  (acquired)
  inode_lock ->
  inode->i_rwsem (try to acquire)
  (block)

(3)
getdents ->
  iterate_dir ->
  inode_lock ->
  inode->i_rwsem   (acquired)
  copy_to_user ->
  mmap_sem (try to acquire)

There is a lock ordering created between mmap_sem and inode->i_rwsem
causing a lockdep splat [2] during a syzcaller test, this patch fixes
the issue by unlocking the mutex earlier. Functionally that's Ok since
we don't need to protect vfs_llseek.

[1] https://patchwork.kernel.org/patch/10185031/
[2] https://lkml.org/lkml/2018/1/10/48

Acked-by: Todd Kjos 
Cc: Arve Hjonnevag 
Cc: sta...@vger.kernel.org
Reported-by: syzbot+8ec30bb7bf1a981a2...@syzkaller.appspotmail.com
Signed-off-by: Joel Fernandes 
Acked-by: Greg Hackmann 
Signed-off-by: Greg Kroah-Hartman 

---
 drivers/staging/android/ashmem.c |   15 +++
 1 file changed, 7 insertions(+), 8 deletions(-)

--- a/drivers/staging/android/ashmem.c
+++ b/drivers/staging/android/ashmem.c
@@ -330,24 +330,23 @@ static loff_t ashmem_llseek(struct file
mutex_lock(_mutex);
 
if (asma->size == 0) {
-   ret = -EINVAL;
-   goto out;
+   mutex_unlock(_mutex);
+   return -EINVAL;
}
 
if (!asma->file) {
-   ret = -EBADF;
-   goto out;
+   mutex_unlock(_mutex);
+   return -EBADF;
}
 
+   mutex_unlock(_mutex);
+
ret = vfs_llseek(asma->file, offset, origin);
if (ret < 0)
-   goto out;
+   return ret;
 
/** Copy f_pos from backing file, since f_ops->llseek() sets it */
file->f_pos = asma->file->f_pos;
-
-out:
-   mutex_unlock(_mutex);
return ret;
 }