Hi, Static analysis on linux-next wit Coverity has found a potential null pointer dereference in commit:
commit 70732504c53b2d3aae2cebc457515a304672d5bb Author: Yongqiang Sun <yongqiang....@amd.com> Date: Fri Feb 19 14:50:23 2021 -0500 drm/amd/display: Implement dmub trace event The analysis is as follows: 400 enum dmub_status dmub_srv_hw_init(struct dmub_srv *dmub, 401 const struct dmub_srv_hw_params *params) 402 { 403 struct dmub_fb *inst_fb = params->fb[DMUB_WINDOW_0_INST_CONST]; 404 struct dmub_fb *stack_fb = params->fb[DMUB_WINDOW_1_STACK]; 405 struct dmub_fb *data_fb = params->fb[DMUB_WINDOW_2_BSS_DATA]; 406 struct dmub_fb *bios_fb = params->fb[DMUB_WINDOW_3_VBIOS]; 407 struct dmub_fb *mail_fb = params->fb[DMUB_WINDOW_4_MAILBOX]; 408 struct dmub_fb *tracebuff_fb = params->fb[DMUB_WINDOW_5_TRACEBUFF]; 409 struct dmub_fb *fw_state_fb = params->fb[DMUB_WINDOW_6_FW_STATE]; 410 struct dmub_fb *scratch_mem_fb = params->fb[DMUB_WINDOW_7_SCRATCH_MEM]; 411 412 struct dmub_rb_init_params rb_params, outbox0_rb_params; 413 struct dmub_window cw0, cw1, cw2, cw3, cw4, cw5, cw6; 414 struct dmub_region inbox1, outbox1, outbox0; 415 1. Condition !dmub->sw_init, taking false branch. 416 if (!dmub->sw_init) 417 return DMUB_STATUS_INVALID; 418 419 dmub->fb_base = params->fb_base; 420 dmub->fb_offset = params->fb_offset; 421 dmub->psp_version = params->psp_version; 422 2. Condition dmub->hw_funcs.reset, taking true branch. 423 if (dmub->hw_funcs.reset) 424 dmub->hw_funcs.reset(dmub); 425 3. Condition inst_fb, taking true branch. 4. Condition data_fb, taking true branch. 426 if (inst_fb && data_fb) { 427 cw0.offset.quad_part = inst_fb->gpu_addr; 428 cw0.region.base = DMUB_CW0_BASE; 429 cw0.region.top = cw0.region.base + inst_fb->size - 1; 430 431 cw1.offset.quad_part = stack_fb->gpu_addr; 432 cw1.region.base = DMUB_CW1_BASE; 433 cw1.region.top = cw1.region.base + stack_fb->size - 1; 434 5. Condition params->load_inst_const, taking true branch. 6. Condition dmub->hw_funcs.backdoor_load, taking true branch. 435 if (params->load_inst_const && dmub->hw_funcs.backdoor_load) { 436 /** 437 * Read back all the instruction memory so we don't hang the 438 * DMCUB when backdoor loading if the write from x86 hasn't been 439 * flushed yet. This only occurs in backdoor loading. 440 */ 441 dmub_flush_buffer_mem(inst_fb); 442 dmub->hw_funcs.backdoor_load(dmub, &cw0, &cw1); 443 } 444 445 } 446 7. Condition inst_fb, taking true branch. 8. Condition data_fb, taking true branch. 9. Condition bios_fb, taking true branch. 10. Condition mail_fb, taking true branch. 11. Condition tracebuff_fb, taking false branch. 12. var_compare_op: Comparing tracebuff_fb to null implies that tracebuff_fb might be null. 447 if (inst_fb && data_fb && bios_fb && mail_fb && tracebuff_fb && 448 fw_state_fb && scratch_mem_fb) { 449 cw2.offset.quad_part = data_fb->gpu_addr; 450 cw2.region.base = DMUB_CW0_BASE + inst_fb->size; 451 cw2.region.top = cw2.region.base + data_fb->size; 452 453 cw3.offset.quad_part = bios_fb->gpu_addr; 454 cw3.region.base = DMUB_CW3_BASE; 455 cw3.region.top = cw3.region.base + bios_fb->size; 456 457 cw4.offset.quad_part = mail_fb->gpu_addr; 458 cw4.region.base = DMUB_CW4_BASE; 459 cw4.region.top = cw4.region.base + mail_fb->size; 460 461 /** 462 * Doubled the mailbox region to accomodate inbox and outbox. 463 * Note: Currently, currently total mailbox size is 16KB. It is split 464 * equally into 8KB between inbox and outbox. If this config is 465 * changed, then uncached base address configuration of outbox1 466 * has to be updated in funcs->setup_out_mailbox. 467 */ 468 inbox1.base = cw4.region.base; 469 inbox1.top = cw4.region.base + DMUB_RB_SIZE; 470 outbox1.base = inbox1.top; 471 outbox1.top = cw4.region.top; 472 473 cw5.offset.quad_part = tracebuff_fb->gpu_addr; 474 cw5.region.base = DMUB_CW5_BASE; 475 cw5.region.top = cw5.region.base + tracebuff_fb->size; 476 477 outbox0.base = DMUB_REGION5_BASE + TRACE_BUFFER_ENTRY_OFFSET; 478 outbox0.top = outbox0.base + sizeof(struct dmcub_trace_buf_entry) * PERF_TRACE_MAX_ENTRY; 479 480 481 cw6.offset.quad_part = fw_state_fb->gpu_addr; 482 cw6.region.base = DMUB_CW6_BASE; 483 cw6.region.top = cw6.region.base + fw_state_fb->size; 484 485 dmub->fw_state = fw_state_fb->cpu_addr; 486 487 dmub->scratch_mem_fb = *scratch_mem_fb; 488 489 if (dmub->hw_funcs.setup_windows) 490 dmub->hw_funcs.setup_windows(dmub, &cw2, &cw3, &cw4, 491 &cw5, &cw6); 492 493 if (dmub->hw_funcs.setup_outbox0) 494 dmub->hw_funcs.setup_outbox0(dmub, &outbox0); 495 496 if (dmub->hw_funcs.setup_mailbox) 497 dmub->hw_funcs.setup_mailbox(dmub, &inbox1); 498 if (dmub->hw_funcs.setup_out_mailbox) 499 dmub->hw_funcs.setup_out_mailbox(dmub, &outbox1); 500 } 501 13. Condition mail_fb, taking true branch. 502 if (mail_fb) { 503 dmub_memset(&rb_params, 0, sizeof(rb_params)); 504 rb_params.ctx = dmub; 505 rb_params.base_address = mail_fb->cpu_addr; 506 rb_params.capacity = DMUB_RB_SIZE; 507 508 dmub_rb_init(&dmub->inbox1_rb, &rb_params); 509 510 // Initialize outbox1 ring buffer 511 rb_params.ctx = dmub; 512 rb_params.base_address = (void *) ((uint64_t) (mail_fb->cpu_addr) + DMUB_RB_SIZE); 513 rb_params.capacity = DMUB_RB_SIZE; 514 dmub_rb_init(&dmub->outbox1_rb, &rb_params); 515 516 } 517 518 dmub_memset(&outbox0_rb_params, 0, sizeof(outbox0_rb_params)); 519 outbox0_rb_params.ctx = dmub; Dereference after null check (FORWARD_NULL) 14. var_deref_op: Dereferencing null pointer tracebuff_fb. 520 outbox0_rb_params.base_address = (void *)((uint64_t)(tracebuff_fb->cpu_addr) + TRACE_BUFFER_ENTRY_OFFSET); 521 outbox0_rb_params.capacity = sizeof(struct dmcub_trace_buf_entry) * PERF_TRACE_MAX_ENTRY; The check on line 447 implies that tracebuf_fb could possibly be null, however on line 520 tracebuf_fb is being dereferenced, so there is a possibly (perhaps unlikely) null pointer dereference issue here. Colin 522 dmub_rb_init(&dmub->outbox0_rb, &outbox0_rb_params);