From owner-freebsd-hackers@FreeBSD.ORG Fri Aug 20 17:38:00 2010 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 6F30B1065674 for ; Fri, 20 Aug 2010 17:38:00 +0000 (UTC) (envelope-from rysto32@gmail.com) Received: from mail-ew0-f54.google.com (mail-ew0-f54.google.com [209.85.215.54]) by mx1.freebsd.org (Postfix) with ESMTP id DA0948FC0A for ; Fri, 20 Aug 2010 17:37:59 +0000 (UTC) Received: by ewy26 with SMTP id 26so2652285ewy.13 for ; Fri, 20 Aug 2010 10:37:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:received:date:message-id :subject:from:to:content-type; bh=J9NqztsmOROd5jv+ttneTx4Ie2Kjx+UiK4oNy4Kpzhc=; b=eddzBX2RodxtkEBkc8qLDzzmzahhS13iCdtFM/4QbdkrEJ41LxBa+hGFBkEcTAD3+i shiMZoKBRRDnRtof/AjPVYpCCk6B7Gnj+Y0RmsbPivJZVdmSeg0dxwGlb1Z5OQhQcnEc DnC1mHYfpuULOR/dB9O5co71JkNfVpO8CaCmE= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:date:message-id:subject:from:to:content-type; b=Q36dvmQX6qybOnymweOIp888PdxdA7oTEjzGBSABGmY15c5y8bVm04Fbfb5587jlro vKzzNj3lg+tuv6r/AjXsEs/tLK/xLJG/I6pC+SkXVfjpUW8h013XyRwlWLzbPXiyR+C8 We1DrnJ7nBbNZggOEpFks5XHK/phMPi8ki0sM= MIME-Version: 1.0 Received: by 10.213.32.206 with SMTP id e14mr1557722ebd.97.1282324433326; Fri, 20 Aug 2010 10:13:53 -0700 (PDT) Received: by 10.213.17.66 with HTTP; Fri, 20 Aug 2010 10:13:53 -0700 (PDT) Date: Fri, 20 Aug 2010 13:13:53 -0400 Message-ID: From: Ryan Stone To: freebsd-hackers@freebsd.org Content-Type: text/plain; charset=ISO-8859-1 Subject: kld modules remain loaded if MOD_LOAD handler returns an error X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 20 Aug 2010 17:38:00 -0000 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?