DragonFlyBSD Kernel Audit
DF-0599 / fix.diff
← back to finding ↓ download raw
--- a/sys/netproto/smb/smb_conn.c
+++ b/sys/netproto/smb/smb_conn.c
@@ -552,7 +552,15 @@
 {
 	struct smb_vc *vcp = CPTOVC(cp);
 
-	smb_vc_disconnect(vcp);
+	/*
+	 * vc_iod is NULL when smb_vc_create() failed before smb_iod_create()
+	 * succeeded (e.g. an unregistered local charset made iconv_open()
+	 * return ENOENT).  There is then no iod to disconnect from; calling
+	 * smb_vc_disconnect()/smb_iod_request() on a NULL iod NULL-derefs
+	 * inside SMB_IOD_EVLOCK() and panics.  (DF-0599)
+	 */
+	if (vcp->vc_iod != NULL)
+		smb_vc_disconnect(vcp);
 }
 
 void

--- a/sys/netproto/smb/smb_iod.c
+++ b/sys/netproto/smb/smb_iod.c
@@ -705,6 +705,7 @@
 	    RFNOWAIT, "smbiod%d", iod->iod_id);
 	if (error) {
 		SMBERROR("can't start smbiod: %d", error);
+		vcp->vc_iod = NULL;	/* avoid UAF via smb_vc_gone() (DF-0599) */
 		kfree(iod, M_SMBIOD);
 		return error;
 	}