commit a6982d0edd0caeb2a7a0f3465c0adf85a902102a Author: Stephen Brennan stephen.s.brennan@oracle.com Date: Mon Sep 14 16:03:32 2020 -0700 oracleasm: Access d_bdev before dropping inode d_bdev is stored alongside the inode. If we hold the last reference to disk_inode, then iput() will clear the d_bdev field and cause a page fault when it is dereferenced. Further, the iput() could result in a blkdev_put(), after which our accesses to bdev could be further corrupted. To avoid all this, delay the iput() until all access to d, disk_inode, and bdev are complete. Ora bug: 31901945 Signed-off-by: Stephen Brennan stephen.s.brennan@oracle.com Reviewed-by: Junxiao Bi junxiao.bi@oracle.com Signed-off-by: Somasundaram Krishnasamy somasundaram.krishnasamy@oracle.com diff --git a/drivers/block/oracleasm/driver.c b/drivers/block/oracleasm/driver.c index 2bcad19af0d8..02882105f799 100644 --- a/drivers/block/oracleasm/driver.c +++ b/drivers/block/oracleasm/driver.c @@ -2380,7 +2380,6 @@ static ssize_t asmfs_svc_query_handle(struct file *file, char *buf, size_t size) } d = ASMDISK_I(disk_inode); - iput(disk_inode); bdev = d->d_bdev; qh_info->qh_max_sectors = compute_max_sectors(bdev); @@ -2395,6 +2394,15 @@ static ssize_t asmfs_svc_query_handle(struct file *file, char *buf, size_t size) trace_queryhandle(bdev, qh_info); ret = 0; + /* + * Dropping the reference to disk_inode could result in d and + * disk_inode being evicted and freed. This will further drop the + * reference to bdev, which could be the last one. Thus, we must + * delay the iput() until all accesses to disk_inode, d, and bdev + * are complete. + */ + iput(disk_inode); + out: qh_info->qh_abi.ai_status = ret; return size;