lkml.org 
[lkml]   [2010]   [Jan]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subjectdisablenetwork (v5): Remove a TOCTTOU race by passing flags by value.
When network_flags is passed by pointer to memory shared among several tasks,
one of those tasks could change the pointed-to value after it was checked by
security_prctl() and before it was used by prctl_set_network().

Also, since no cleanup is needed in prctl_set_network(), simplify its
return-value conventions.

Signed-off-by: Michael Stone <michael@laptop.org>
---
include/linux/prctl_network.h | 2 +-
kernel/sys.c | 24 ++++++------------------
2 files changed, 7 insertions(+), 19 deletions(-)

diff --git a/include/linux/prctl_network.h b/include/linux/prctl_network.h
index d18f8cb..2c03292 100644
--- a/include/linux/prctl_network.h
+++ b/include/linux/prctl_network.h
@@ -2,6 +2,6 @@
#define _LINUX_PRCTL_NETWORK_H

extern long prctl_get_network(unsigned long*);
-extern long prctl_set_network(unsigned long*);
+extern long prctl_set_network(unsigned long);

#endif /* _LINUX_PRCTL_NETWORK_H */
diff --git a/kernel/sys.c b/kernel/sys.c
index b48f021..1fadf10 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1580,7 +1580,7 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
error = PR_MCE_KILL_DEFAULT;
break;
case PR_SET_NETWORK:
- error = prctl_set_network((unsigned long*)arg2);
+ error = prctl_set_network(arg2);
break;
case PR_GET_NETWORK:
error = prctl_get_network((unsigned long*)arg2);
@@ -1599,29 +1599,17 @@ long prctl_get_network(unsigned long* user)
return put_user(current->network, user);
}

-long prctl_set_network(unsigned long* user)
+long prctl_set_network(unsigned long network_flags)
{
- unsigned long network_flags;
- long ret;
-
- ret = -EFAULT;
- if (copy_from_user(&network_flags, user, sizeof(network_flags)))
- goto out;
-
- ret = -EINVAL;
if (network_flags & ~PR_NETWORK_ALL_FLAGS)
- goto out;
+ return -EINVAL;

/* only dropping access is permitted */
- ret = -EPERM;
- if (current->network & ~network_flags)
- goto out;
+ if (current->network & ~network_flags)
+ return -EPERM;

current->network = network_flags;
- ret = 0;
-
-out:
- return ret;
+ return 0;
}

#else
--
1.6.6.rc2

\
 
 \ /
  Last update: 2010-01-15 09:13    [W:0.478 / U:0.308 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site