NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
kern/58163: dead branches in dtv_demux_close
>Number: 58163
>Category: kern
>Synopsis: dead branches in dtv_demux_close
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Wed Apr 17 17:05:00 +0000 2024
>Originator: Taylor R Campbell
>Release: current
>Organization:
The NetDTV Foundation
>Environment:
>Description:
dtv_demux_close, a struct fileops::fo_close function, has a branch for the event of dtv_demux_stop failure:
341 /* If the demux is still running, stop it */
342 if (demux->dd_running) {
343 error = dtv_demux_stop(demux);
344 if (error)
345 return error;
346 }
This early return skips over releasing resources:
353 mutex_destroy(&demux->dd_lock);
354 cv_destroy(&demux->dd_section_cv);
355 kmem_free(demux, sizeof(*demux));
356
357 /* Update the global device open count */
358 dtv_common_close(sc);
https://nxr.netbsd.org/xref/src/sys/dev/dtv/dtv_demux.c?r=1.11#341
This would be a bug if dtv_demux_stop could fail, because .fo_close is final; there will never be a second call to .fo_close, so any failure here is necessarily a memory leak.
But dtv_demux_stop only fails if dtv_device_stop_transfer fails, and every struct dtv_hw_if::stop_transfer function unconditionally returns zero:
https://nxr.netbsd.org/xref/src/sys/dev/pci/coram.c?r=1.20#716
https://nxr.netbsd.org/xref/src/sys/dev/pci/cxdtv.c?r=1.22#637
https://nxr.netbsd.org/xref/src/sys/dev/usb/auvitek_dtv.c?r=1.10#262
https://nxr.netbsd.org/xref/src/sys/dev/usb/emdtv_dtv.c?r=1.17#343
Rather than maintain these buggy dead branches, .stop_transfer should just be made to return void and all this logic be made unconditional.
>How-To-Repeat:
code inspection
>Fix:
1. make struct dtv_hw_if::stop_transfer return void
2. prune dead branches
3. review this code for MP-safety while here, access to dd_running looks dodgy -- maybe dtv_demux_close should just call dtv_demux_stop unconditionally
Home |
Main Index |
Thread Index |
Old Index