kld modules remain loaded if MOD_LOAD handler returns an error
Garrett Cooper
gcooper at FreeBSD.org
Fri Aug 20 21:26:28 UTC 2010
On Fri, Aug 20, 2010 at 10:13 AM, Ryan Stone <rysto32 at gmail.com> wrote:
> Consider the following modules:
>
> /* first.c */
> static int *test;
>
> int
> test_function(void)
> {
> return *test;
> }
>
> static int
> first_modevent(struct module *m, int what, void *arg)
> {
> int err = 0;
>
> switch (what) {
> case MOD_LOAD: /* kldload */
> test = malloc(sizeof(int), M_TEMP, M_NOWAIT | M_ZERO);
> if (!test)
> err = ENOMEM;
> break;
> case MOD_UNLOAD: /* kldunload */
> break;
> default:
> err = EINVAL;
> break;
> }
> return(err);
> }
>
> static moduledata_t first_mod = {
> "first",
> first_modevent,
> NULL
> };
>
> DECLARE_MODULE(first, first_mod, SI_SUB_KLD, SI_ORDER_ANY);
> MODULE_VERSION(first, 1);
>
>
> /* second.c */
> static int
> second_modevent(struct module *m, int what, void *arg)
> {
> int err = 0;
>
> switch (what) {
> case MOD_LOAD: /* kldload */
> test_function();
> break;
> case MOD_UNLOAD: /* kldunload */
> break;
> default:
> err = EINVAL;
> break;
> }
> return(err);
> }
>
> static moduledata_t second_mod = {
> "second",
> second_modevent,
> NULL
> };
>
> DECLARE_MODULE(second, second_mod, SI_SUB_KLD, SI_ORDER_ANY);
> MODULE_DEPEND(second, first, 1, 1, 1);
>
>
> Consider the case where malloc fails in first_modevent.
> first_modevent will return ENOMEM, but the module will remain loaded.
> Now when the second module goes and loads, it calls into the first
> module, which is not initialized properly, and promptly crashes when
> test_function() dereferences a null pointer.
>
> It seems to me that a module should be unloaded if it returns an error
> from its MOD_LOAD handler. However, that's easier said than done.
> The MOD_LOAD handler is called from a SYSINIT, and there's no
> immediately obvious way to pass information about the failure from the
> SYSINIT to the kernel linker. Anybody have any thoughts on this?
I saw similar issues as well with another driver on 6.3 and 7.1.
Looking over kern_kldload and kldload in sys/kern/kern_linker.c, it
doesn't appear that there's an issue with error catching, but I didn't
attempt to trace down the call stack further than that.
-Garrett
More information about the freebsd-hackers
mailing list