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

[MiNT] patch:MiNT:KM_FREE



Hello

I've added the possibility to free a kernel-module to MiNT. Drawback is
that the caller only has path/name it passed to identify the module, and
MiNT may use another spelling for it. It would be better to have a unique
id to pass to the kernel for KM_FREE.

A kernel-module may only be loaded once


---------------------------------------------------------
add the possibility to free a kernel-module.
---------------------------------------------------------



  name="KM_FREE.patch"
  Content-Transfer-Encoding: 7bit
  Content-Disposition: inline;
  filename="KM_FREE.patch"

--- orig/module.c	2009-04-26 12:59:27.406250000 +0200
+++ module.c	2009-12-13 17:53:32.718750000 +0100
@@ -725,6 +725,7 @@
 //		sys_c_conin();
 // 		run = (long _cdecl(*)(struct kentry *, const char *))km->b->p_tbase;
 		run = (long _cdecl(*)(struct kentry *, const struct kernel_module *))km->b->p_tbase;
+		km->caller = curproc;
 		err = (*run)(&kentry, km); //km->path);
 	}
 	else
@@ -808,20 +809,73 @@
 module_ioctl(FILEPTR *f, int mode, void *buf)
 {
 	long r = ENOSYS;
+	char *p1, *p2;
+	struct kernel_module *km;
 	
 	DEBUG(("module_ioctl [%i]: (%x, (%c %i), %lx)",
 		f->fc.aux, mode, (char)(mode >> 8), (mode & 0xff), buf));
-	
+
+	if( !buf )
+		return EINVAL;
+
+	/* only root may */
+	if( !suser (curproc->p_cred->ucr) )
+		return EPERM;
+
+	/* stored name may have path or not */
+	p1 = strrchr( buf, '/');
+	p2 = strrchr( buf, '\\');
+	if( p2 > p1 )
+		p1 = p2;
+	if( !p1 )
+		p1 = buf;
+	else
+		p1++;
+
 	switch (mode)
 	{
 		case KM_RUN:
 		{
-			r = run_km(buf);
+			/* check if module already loaded */
+			for( km = loaded_modules; km; km = km->next )
+			{
+				DEBUG(("module_ioctl: run_km: looking(%s,%s)", km->name, p1));
+				if( km->class == MODCLASS_KM && !(strcmp( p1, km->name ) && strcmp( buf, km->name )) )
+				{
+					DEBUG(("module_ioctl: module_ioctl:KM_RUN:(%s) already loaded",p1));
+					r = EACCES;	/* ELOCKED? */
+					break;
+				}
+			}
+			if( !km )	/* not found -> run */
+				r = run_km(buf);
+			break;
+		}
+
+		case KM_FREE:
+		{
+			/* check if module loaded */
+			for( km = loaded_modules; km; km = km->next )
+			{
+				DEBUG(("module_ioctl: free_km: looking(%s) cur:%lx caller:%lx", km->name, curproc, km->caller));
+				if( km->class == MODCLASS_KM && km->caller == curproc && !strcmp( buf, km->name ) )
+				{
+					DEBUG(("module_ioctl: free_km(%s)",km->name));
+					free_km( km );
+					r = 0;
+					break;
+				}
+				if( !km )
+				{
+					r = ENOENT;
+					DEBUG(("module_ioctl: free_km(%s) not found",buf));
+				}
+			}
 			break;
 		}
 	}
 	
-	DEBUG (("module_ioctl: return %li", r));
+	DEBUG (("module_ioctl(%d): return %li", mode&0xff, r));
 	return r;
 }
 
--- orig/mint/module.h	2009-12-13 11:44:11.218750000 +0100
+++ mint/module.h	2009-12-13 11:32:36.328125000 +0100
@@ -57,6 +57,7 @@
 	struct kernel_module *next;
 	struct kernel_module *prev;
 	struct basepage *b;
+	struct proc *caller;
 	short class;
 	short subclass;
 	unsigned long flags;
--- orig/mint/ioctl.h	2006-11-14 13:54:20.000000000 +0100
+++ mint/ioctl.h	2009-11-07 11:03:26.687500000 +0100
@@ -104,6 +104,7 @@
  */
 
 # define KM_RUN		(('K'<< 8) | 1)		/* 1.16 */
+# define KM_FREE		(('K'<< 8) | 2)		/* 1.17.1 */
 
 
 /*