BarryServer : Git

All the code for all my projects
// BarryServer : Git / Nucleus / commit / c4a1ba4bf904af4c5944b30c698180d41df41911

// Related

Nucleus

Barry Fixed resource leak in VFS c4a1ba4 (3 years, 2 months ago)
diff --git a/drivers/video/bga.c b/drivers/video/bga.c
index 3354d01..061409a 100644
--- a/drivers/video/bga.c
+++ b/drivers/video/bga.c
@@ -10,9 +10,11 @@
 #include <sys/stat.h>
 #include <sys/fb.h>
 #include <fcntl.h>
+#include <errno.h>
 #include <io.h>
 #include <nucleus/driver.h>
-#include <nucleus/panic.h>
+#include <nucleus/kernel.h>
+#include <nucleus/memory.h>
 #include <nucleus/pci.h>
 #include <nucleus/vfs.h>
 
@@ -108,22 +110,33 @@ bga_dev_ioctl(File *file, unsigned long request, uintptr_t argp)
 	FBVarInfo *vinfo;
 	FBFixInfo *finfo;
 
+	if (!argp)
+		return -EFAULT;
+
 	switch (request) {
 	case FBIOGET_VSCREENINFO:
 		vinfo = (void *) argp;
+		if (!verify_access(vinfo, sizeof(FBVarInfo), PROT_WRITE))
+			return -EFAULT;
 		vinfo->xres = bgaDev.width;
 		vinfo->yres = bgaDev.height;
 		vinfo->bpp = bgaDev.bpp;
 		return 0;
 	case FBIOPUT_VSCREENINFO:
 		vinfo = (void *) argp;
+		if (!verify_access(vinfo, sizeof(FBVarInfo), PROT_WRITE))
+			return -EFAULT;
 		bga_set_mode(vinfo->xres, vinfo->yres, vinfo->bpp);
 		return 0;
 	case FBIOGET_FSCREENINFO:
 		finfo = (void *) argp;
+		if (!verify_access(finfo, sizeof(FBFixInfo), PROT_WRITE))
+			return -EFAULT;
 		finfo->fbmem = bgaDev.lfb;
 		finfo->fbmemLen = bgaDev.memSize;
 		return 0;
+	default:
+		return -EINVAL;
 	}
 }
 
diff --git a/include/nucleus/object.h b/include/nucleus/object.h
index b86a86f..139f7ca 100644
--- a/include/nucleus/object.h
+++ b/include/nucleus/object.h
@@ -51,6 +51,7 @@ enum ListMode {
 	LIST_ORDERED,
 };
 
+int check(void *addr);
 void *get(void *addr);
 void put(void *addr);
 void *new(ObjectType *type);
@@ -58,6 +59,7 @@ void *copy(void *addr);
 refcount_t usage(void *addr);
 void lock(void *addr);
 void unlock(void *addr);
+#define swap_ref(v,o) ({ if (o) get(o); if (v) put(v); v = o; })
 
 ObjectList *create_list(ObjectType *type, enum ListMode mode, ...);
 void destroy_list(ObjectList *list);
diff --git a/memory/heap.c b/memory/heap.c
index a61149c..0e0dbed 100644
--- a/memory/heap.c
+++ b/memory/heap.c
@@ -8,7 +8,7 @@
 #include <stdint.h>
 #include <stddef.h>
 #include <string.h>
-#include <nucleus/panic.h>
+#include <nucleus/kernel.h>
 
 #define KHEAP_START 0x200000 /* 2MB */
 #define KHEAP_END   0x800000 /* 2MB */
diff --git a/object/list.c b/object/list.c
index 01f6aef..6745f28 100644
--- a/object/list.c
+++ b/object/list.c
@@ -7,9 +7,9 @@
  */
 
 #include <stdarg.h>
+#include <nucleus/kernel.h>
 #include <nucleus/object.h>
 #include <nucleus/memory.h>
-#include <nucleus/panic.h>
 
 /* Structure for a List Entry */
 struct ListEntry {
@@ -144,7 +144,8 @@ remove(ObjectList *list, void *addr)
 		entry->next->prev = entry->prev;
 
 	/* Release resources */
-	put(obj);
+	if (__builtin_expect(!!(obj->usage), 1))
+		put(obj);
 	list->entries--;
 	kfree(entry);
 	release(&list->lock);
diff --git a/object/manager.c b/object/manager.c
index a274408..7e6da04 100644
--- a/object/manager.c
+++ b/object/manager.c
@@ -6,14 +6,22 @@
  * controls their instantiation and deletion.
  */
 
-#include <nucleus/object.h>
+#include <nucleus/kernel.h>
 #include <nucleus/memory.h>
-#include <nucleus/panic.h>
+#include <nucleus/object.h>
 
 void init_lock(Spinlock *lock);
 void acquire(Spinlock *lock);
 void release(Spinlock *lock);
 
+/* Check the magic of an object */
+int
+check(void *addr)
+{
+	Object *obj = addr;
+	return (obj && obj->magic == OBJECT_MAGIC);
+}
+
 /* Obtain a reference to an object */
 void *
 get(void *addr)
@@ -37,6 +45,7 @@ put(void *addr)
 	if (obj->type->delete)
 		obj->type->delete(obj);
 	remove(obj->type->objects, obj);
+	obj->magic = 0;
 	if (obj->type->free)
 		obj->type->free(obj);
 	else
diff --git a/vfs/inode.c b/vfs/inode.c
index 8197127..903efd1 100644
--- a/vfs/inode.c
+++ b/vfs/inode.c
@@ -134,8 +134,10 @@ inode_lookup(Inode *inode, const char *name)
 
 	/* The file doesn't exist */
 	if (!child) {
-		if (entry)
+		if (entry) {
 			remove(inode->dirEntries, entry);
+			put(entry);
+		}
 		entry = NULL;
 		goto end;
 	}
diff --git a/vfs/open.c b/vfs/open.c
index cac1512..cbc4bac 100644
--- a/vfs/open.c
+++ b/vfs/open.c
@@ -25,16 +25,16 @@ lookup(const char *path, ObjectList *newcustody)
 	char buf[PATH_MAX], *p = buf;
 	strncpy(buf, path, PATH_MAX);
 	Inode *inode;
-	DirEntry *entry;
+	DirEntry *entry = NULL;
 	ObjectList *custody;
 
 	/* Resolve to absolute/relative root */
 	if (*p == '/') {
-		inode = current->fs->root;
+		inode = get(current->fs->root);
 		while (*++p == '/');
 		custody = create_list(&dirEntryType, LIST_NORMAL);
 	} else {
-		inode = current->fs->cwd;
+		inode = get(current->fs->cwd);
 		custody = copy_list(current->fs->cwdPath);
 	}
 
@@ -53,22 +53,21 @@ lookup(const char *path, ObjectList *newcustody)
 			if (inode != current->fs->root) {
 				entry = pop_from_end(custody);
 				if (!entry)
-					inode = current->fs->root;
+					swap_ref(inode, current->fs->root);
 				else
 					put(entry);
 			}
 		} else {
 			entry = inode_lookup(inode, prev);
 			if (!entry) {
-				inode = NULL;
+				swap_ref(inode, NULL);
 				goto end;
 			}
 			add(custody, entry);
 			put(entry);
 		}
-
 		if (entry)
-			inode = entry->inode;
+			swap_ref(inode, entry->inode);
 
 		while (*++curr == '/');
 		prev = curr;
@@ -77,14 +76,14 @@ lookup(const char *path, ObjectList *newcustody)
 	/* Base name */
 	if (!strcmp(prev, ".") || !strcmp(prev, "")) {
 		if (!S_ISDIR(inode->mode)) {
-			inode = NULL;
-			entry = NULL;
+			swap_ref(inode, NULL);
+			swap_ref(entry, NULL);
 		}
 	} else if (!strcmp(prev, "..")) {
 		if (inode != current->fs->root) {
 			entry = pop_from_end(custody);
 			if (!entry)
-				inode = current->fs->root;
+				swap_ref(inode, current->fs->root);
 			else
 				put(entry);
 		}
@@ -98,11 +97,8 @@ lookup(const char *path, ObjectList *newcustody)
 		add(custody, entry);
 		put(entry);
 	}
-	if (entry) {
-		inode = entry->inode;
-		if (inode)
-			get(inode);
-	}
+	if (entry)
+		swap_ref(inode, entry->inode);
 
 	/* Copy path */
 	if (newcustody)