All of lore.kernel.org
 help / color / mirror / Atom feed
* procfs does not return error code when file name is already in use
@ 2012-10-26  9:57 Дмитрий Леонтьев
  2012-10-26 10:06 ` Jiri Kosina
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Дмитрий Леонтьев @ 2012-10-26  9:57 UTC (permalink / raw)
  To: linux-kernel; +Cc: trivial, dleontie

I'm working a kernel module, and one of my tasks is to disallow a
process to open my character device(/dev/xxx) more than once. I tried
to solve this problem by creating /proc/apu directory, and creating a
/proc/xxx/{pid} file for when process opens /dev/xxx. This file will
act as per-process mutex, and provide a way to control resource usage.

Then, I investigated,if procfs acts as I expect from it, and found
that procfs checks file names for uniqueness, but does not return an
error when I add two files with same name. Instead, it posts silly
messages to kernel log, and adds new entry as if nothing happened.
This is a vulnerability:

Let we have 2 modules A and B trying to create file /proc/foo on load,
and removing it on unload. Load A, Load B, unload B. at step 3 B
removed /proc/foo owned by A, and /proc/foo created by B remains
accessible from userspace.

My patch fixes this behaviour: proc_register will return -EEXIST when
file name is in use, and refuse to add a duplicate.

----start of patch for fs/proc/generic.c---------------------------------------
--- generic.c.orig	2012-10-25 22:20:05.196606263 +0400
+++ generic.c	2012-10-25 22:13:49.556955392 +0400
@@ -554,45 +554,51 @@ static const struct inode_operations pro

 static int proc_register(struct proc_dir_entry * dir, struct
proc_dir_entry * dp)
 {
+	int errorcode=-EAGAIN;
 	unsigned int i;
 	struct proc_dir_entry *tmp;
 	
 	i = get_inode_number();
-	if (i == 0)
-		return -EAGAIN;
-	dp->low_ino = i;
-
-	if (S_ISDIR(dp->mode)) {
-		if (dp->proc_iops == NULL) {
-			dp->proc_fops = &proc_dir_operations;
-			dp->proc_iops = &proc_dir_inode_operations;
+	if (i != 0)
+	{
+		errorcode=0;
+
+		dp->low_ino = i;
+
+		if (S_ISDIR(dp->mode)) {
+			if (dp->proc_iops == NULL) {
+				dp->proc_fops = &proc_dir_operations;
+				dp->proc_iops = &proc_dir_inode_operations;
+			}
+			dir->nlink++;
+		} else if (S_ISLNK(dp->mode)) {
+			if (dp->proc_iops == NULL)
+				dp->proc_iops = &proc_link_inode_operations;
+		} else if (S_ISREG(dp->mode)) {
+			if (dp->proc_fops == NULL)
+				dp->proc_fops = &proc_file_operations;
+			if (dp->proc_iops == NULL)
+				dp->proc_iops = &proc_file_inode_operations;
 		}
-		dir->nlink++;
-	} else if (S_ISLNK(dp->mode)) {
-		if (dp->proc_iops == NULL)
-			dp->proc_iops = &proc_link_inode_operations;
-	} else if (S_ISREG(dp->mode)) {
-		if (dp->proc_fops == NULL)
-			dp->proc_fops = &proc_file_operations;
-		if (dp->proc_iops == NULL)
-			dp->proc_iops = &proc_file_inode_operations;
-	}

-	spin_lock(&proc_subdir_lock);
+		spin_lock(&proc_subdir_lock);

-	for (tmp = dir->subdir; tmp; tmp = tmp->next)
-		if (strcmp(tmp->name, dp->name) == 0) {
-			WARN(1, KERN_WARNING "proc_dir_entry '%s/%s' already registered\n",
-				dir->name, dp->name);
-			break;
+		for (tmp = dir->subdir; tmp; tmp = tmp->next)
+		{
+			if (strcmp(tmp->name, dp->name) == 0) {
+				errorcode=-EEXIST;
+				break;
+			}
 		}
-
-	dp->next = dir->subdir;
-	dp->parent = dir;
-	dir->subdir = dp;
-	spin_unlock(&proc_subdir_lock);
-
-	return 0;
+		if(!errorcode)
+		{
+			dp->next = dir->subdir;
+			dp->parent = dir;
+			dir->subdir = dp;
+		}
+		spin_unlock(&proc_subdir_lock);
+	}
+	return errorcode;
 }

 static struct proc_dir_entry *__proc_create(struct proc_dir_entry **parent,
----end of patch---------------------------------------

Regards
Dmitry

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2012-10-26 12:22 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-10-26  9:57 procfs does not return error code when file name is already in use Дмитрий Леонтьев
2012-10-26 10:06 ` Jiri Kosina
2012-10-26 12:05   ` Thadeu Lima de Souza Cascardo
2012-10-26 11:03 ` Al Viro
2012-10-26 12:22 ` Thadeu Lima de Souza Cascardo

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.