tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Unreleased vnode in linux_sys_uselib()



Hi,
there seems to be a vnode issue in compat/linux/common/linux_uselib.c:

115	if (LINUX_N_MACHTYPE(&hdr) != LINUX_MID_MACHINE)
116		return ENOEXEC;

Here 'vp' is not released. Patch:

Index: linux_uselib.c
===================================================================
RCS file: /cvsroot/src/sys/compat/linux/common/linux_uselib.c,v
retrieving revision 1.30
diff -u -r1.30 linux_uselib.c
--- linux_uselib.c	28 Aug 2009 01:39:03 -0000	1.30
+++ linux_uselib.c	18 Oct 2014 10:48:53 -0000
@@ -103,17 +103,18 @@
 	if ((error = vn_rdwr(UIO_READ, vp, (void *) &hdr, LINUX_AOUT_HDR_SIZE,
 			     0, UIO_SYSSPACE, IO_NODELOCKED, l->l_cred,
 			     &rem, NULL))) {
-		vrele(vp);
-		return error;
+		goto out;
 	}
 
 	if (rem != 0) {
-		vrele(vp);
-		return ENOEXEC;
+		error = ENOEXEC;
+		goto out;
 	}
 
-	if (LINUX_N_MACHTYPE(&hdr) != LINUX_MID_MACHINE)
-		return ENOEXEC;
+	if (LINUX_N_MACHTYPE(&hdr) != LINUX_MID_MACHINE) {
+		error = ENOEXEC;
+		goto out;
+	}
 
 	magic = LINUX_N_MAGIC(&hdr);
 	taddr = hdr.a_entry & (~(PAGE_SIZE - 1));
@@ -123,7 +124,7 @@
 
 	error = vn_marktext(vp);
 	if (error)
-		return (error);
+		goto out;
 
 	vcset.evs_cnt = 0;
 	vcset.evs_used = 0;
@@ -150,7 +151,7 @@
 
 	kill_vmcmds(&vcset);
 
+out:
 	vrele(vp);
-
 	return error;
 }


And I'm wondering: what is the impact of such bugs? njoly@ tested a
small sample I sent him and apparently there doesn't seem to be any
glaring issue.

He also suggested to reject non-regular files, which makes sense since
this function aims at loading libraries:

Index: linux_uselib.c
===================================================================
RCS file: /cvsroot/src/sys/compat/linux/common/linux_uselib.c,v
retrieving revision 1.30
diff -u -p -r1.30 linux_uselib.c
--- linux_uselib.c      28 Aug 2009 01:39:03 -0000      1.30
+++ linux_uselib.c      18 Oct 2014 09:26:10 -0000
@@ -100,6 +100,11 @@ linux_sys_uselib(struct lwp *l,const st
        if (error != 0)
                return error;
 
+       if (vp->v_type != VREG) {
+               vrele(vp);
+               return EINVAL;
+       }
+
        if ((error = vn_rdwr(UIO_READ,vp,(void *) &hdr,LINUX_AOUT_HDR_SIZE,
                             0,UIO_SYSSPACE,IO_NODELOCKED,l->l_cred,
                             &rem,NULL))) {

Found by my code scanner, with the help of njoly@.

I would like one or two okayz before committing both.


Home | Main Index | Thread Index | Old Index