mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 10:31:46 +09:00
media: rockchip: vpss: prevent NULL dereference in ofl_open
Add NULL check for ofl->hw before accessing dev_lock mutex to avoid
kernel panic caused by translation fault at virtual address 0x27d8.
The crash occurs when opening V4L2 device if the hardware structure
(ofl->hw) is not properly initialized. This adds defensive checks to:
1. Validate ofl and ofl->hw pointers before mutex operations
2. Return -ENODEV if hw structure is unavailable
3. Prevent use-after-unlock in error paths
Fixes system stability issues with v4l_id process (PID 229) when
handling uninitialized hardware states. Detail issues can repo as below:
[ 6.811649] Unable to handle kernel paging request at virtual address 00000000000027d8
[ 6.812363] Mem abort info:
[ 6.812621] ESR = 0x0000000096000005
[ 6.812958] EC = 0x25: DABT (current EL), IL = 32 bits
[ 6.813438] SET = 0, FnV = 0
[ 6.813718] EA = 0, S1PTW = 0
[ 6.813999] FSC = 0x05: level 1 translation fault
[ 6.814429] Data abort info:
[ 6.814685] ISV = 0, ISS = 0x00000005
[ 6.815021] CM = 0, WnR = 0
[ 6.815360] user pgtable: 4k pages, 39-bit VAs, pgdp=0000000043594000
[ 6.815941] [00000000000027d8] pgd=0000000000000000, p4d=0000000000000000, pud=0000000000000000
[ 6.816746] Internal error: Oops: 0000000096000005 [#1] SMP
[ 6.817245] Modules linked in:
[ 6.817530] CPU: 0 PID: 229 Comm: v4l_id Tainted: G W 6.1.118 #16
[ 6.818193] Hardware name: Rockchip RV1126B EVB1 V10 Board (DT)
[ 6.818715] pstate: 00000005 (nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[ 6.819332] pc : mutex_unlock+0xc/0x40
[ 6.819686] lr : ofl_open+0x5c/0xc8
[ 6.820010] sp : ffffffc009673ad0
[ 6.820312] x29: ffffffc009673ad0 x28: ffffff8001f65400 x27: 0000000000000000
[ 6.820956] x26: 0000000000000004 x25: 0000000000000000 x24: ffffffc008cae360
[ 6.821598] x23: ffffff800290e200 x22: 00000000000027d8 x21: ffffff8002030108
[ 6.822233] x20: ffffff800290e200 x19: 0000000000000000 x18: 0000000000000000
[ 6.822865] x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
[ 6.823508] x14: ffffff8001820025 x13: 0000000000000007 x12: ffffff8001425480
[ 6.824155] x11: 0000000000000002 x10: 00000007305dcf59 x9 : 0000000000000000
[ 6.824787] x8 : ffffff80020328b8 x7 : 0000000000000000 x6 : 000000000000056c
[ 6.825430] x5 : ffffffc008c23fb0 x4 : 0000000000000000 x3 : 0000000000000000
[ 6.826072] x2 : 0000000000000000 x1 : ffffff8001f65400 x0 : 00000000000027d8
[ 6.826715] Call trace:
[ 6.826940] mutex_unlock+0xc/0x40
[ 6.827254] v4l2_open+0x98/0xec
[ 6.827550] chrdev_open+0x158/0x164
[ 6.827875] do_dentry_open+0x2d4/0x350
[ 6.828231] vfs_open+0x28/0x30
[ 6.828520] path_openat+0x760/0x870
[ 6.828854] do_filp_open+0x38/0x88
Change-Id: I48b2e39f2e9a79efee7e63348e9dfc02889a02a1
Signed-off-by: Caesar Wang <wxt@rock-chips.com>
This commit is contained in:
@@ -2548,6 +2548,11 @@ static int ofl_open(struct file *file)
|
||||
struct rkvpss_offline_dev *ofl = video_drvdata(file);
|
||||
int ret;
|
||||
|
||||
if (!ofl || !ofl->hw) {
|
||||
ret = -ENODEV;
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = v4l2_fh_open(file);
|
||||
if (ret)
|
||||
goto end;
|
||||
@@ -2555,13 +2560,18 @@ static int ofl_open(struct file *file)
|
||||
mutex_lock(&ofl->hw->dev_lock);
|
||||
ret = pm_runtime_get_sync(ofl->hw->dev);
|
||||
mutex_unlock(&ofl->hw->dev_lock);
|
||||
if (ret < 0)
|
||||
|
||||
if (ret < 0) {
|
||||
v4l2_fh_release(file);
|
||||
else
|
||||
ret = rkvpss_ofl_add_file_id(ofl, (void *)file);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = rkvpss_ofl_add_file_id(ofl, (void *)file);
|
||||
end:
|
||||
v4l2_dbg(1, rkvpss_debug, &ofl->v4l2_dev,
|
||||
"%s file:%p ret:%d\n", __func__, file, ret);
|
||||
if (ofl) {
|
||||
v4l2_dbg(1, rkvpss_debug, &ofl->v4l2_dev,
|
||||
"%s file:%p ret:%d\n", __func__, file, ret);
|
||||
}
|
||||
return (ret > 0) ? 0 : ret;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user