6077536 2001-02-10 22:18 +0100 /36 rader/ Aleksander Kamil Modzelewski <noir@VORTEX.EFEKT.PL>
Sänt av: joel@lysator.liu.se
Importerad: 2001-02-11 01:11 av Brevbäraren (som är implementerad i) Python
Extern mottagare: BUGTRAQ@SECURITYFOCUS.COM
Externa svar till: noir@VORTEX.EFEKT.PL
Mottagare: Bugtraq (import) <15351>
Kommentar till text 6077058 av Florian Weimer <Florian.Weimer@RUS.UNI-STUTTGART.DE>
Ärende: Re: Linux kernel sysctl() vulnerability
------------------------------------------------------------
From: Aleksander Kamil Modzelewski <noir@VORTEX.EFEKT.PL>
To: BUGTRAQ@SECURITYFOCUS.COM
Message-ID: <20010210221831.A20664@vortex.efekt.pl>
On Sat, Feb 10, 2001 at 10:28:01AM +0100, Florian Weimer wrote:
> > There exists a Linux system call sysctl() which is used to query and
> > modify runtime system settings. Unprivileged users are permitted to query
> > the value of many of these settings.
> It appears that all current Linux kernel version (2.2.x and 2.4.x) are
> vulnerable. Right?
But not in Alan Cox'es version.
In 2.4.1-ac4:
/* The generic string strategy routine: */
int sysctl_string(ctl_table *table, int *name, int nlen,
void *oldval, size_t *oldlenp,
void *newval, size_t newlen, void **context)
{
size_t l, len;
Another thing is, that t shows, that someone already noticed the
problem :/
Greets
Aleksander Kamil Modzelewski
ps. This is my first posting. Hope I did not make a fall-start :)
pps. OK, I did, but this is a long story :)
--
/==]n0iR[==++++.__ /\
| noir@efekt.pl `\ BOFH excuse #89: Electromagnetic energy loss `|
+ BOFH #1 of #radom `\ |
|\ UIN: #89507110 `\ |
\--\~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/'
(6077536) ------------------------------------------
6077539 2001-02-10 14:43 -0800 /14 rader/ Greg KH <greg@WIREX.COM>
Sänt av: joel@lysator.liu.se
Importerad: 2001-02-11 01:14 av Brevbäraren (som är implementerad i) Python
Extern mottagare: BUGTRAQ@SECURITYFOCUS.COM
Externa svar till: greg@WIREX.COM
Mottagare: Bugtraq (import) <15352>
Kommentar till text 6077058 av Florian Weimer <Florian.Weimer@RUS.UNI-STUTTGART.DE>
Ärende: Re: Linux kernel sysctl() vulnerability
------------------------------------------------------------
On Sat, Feb 10, 2001 at 10:28:01AM +0100, Florian Weimer wrote:
>
> The following trivial patch should fix this issue.
Here's the patch that Alan accepted and put into 2.2.18-pre9 to fix
this problem.
greg k-h
--
greg@(kroah|wirex).com
http://immunix.org/~greg
(6077539) --------------------------------(Ombruten)
Bilaga (text/plain) i text 6077540
6077540 2001-02-10 14:43 -0800 /226 rader/ Greg KH <greg@WIREX.COM>
Importerad: 2001-02-11 01:14 av Brevbäraren (som är implementerad i) Python
Extern mottagare: BUGTRAQ@SECURITYFOCUS.COM
Externa svar till: greg@WIREX.COM
Mottagare: Bugtraq (import) <15353>
Bilaga (text/plain) till text 6077539
Ärende: Bilaga till: Re: Linux kernel sysctl() vulnerability
------------------------------------------------------------
diff -Naur -X /home/greg/linux/dontdiff
linux-2.2.18/include/linux/sysctl.h
linux-2.2.18-greg/include/linux/sysctl.h
--- linux-2.2.18/include/linux/sysctl.h Sun Dec 10 16:49:44 2000
+++ linux-2.2.18-greg/include/linux/sysctl.h Fri Jan 26 10:28:40 2001
@@ -30,7 +30,7 @@
struct __sysctl_args {
int *name;
- int nlen;
+ unsigned nlen;
void *oldval;
size_t *oldlenp;
void *newval;
@@ -465,7 +465,7 @@
typedef struct ctl_table ctl_table;
-typedef int ctl_handler (ctl_table *table, int *name, int nlen,
+typedef int ctl_handler (ctl_table *table, int *name, unsigned nlen,
void *oldval, size_t *oldlenp,
void *newval, size_t newlen,
void **context);
@@ -484,12 +484,12 @@
extern int proc_dointvec_jiffies(ctl_table *, int, struct file *,
void *, size_t *);
-extern int do_sysctl (int *name, int nlen,
+extern int do_sysctl (int *name, unsigned nlen,
void *oldval, size_t *oldlenp,
void *newval, size_t newlen);
extern int do_sysctl_strategy (ctl_table *table,
- int *name, int nlen,
+ int *name, unsigned nlen,
void *oldval, size_t *oldlenp,
void *newval, size_t newlen, void ** context);
diff -Naur -X /home/greg/linux/dontdiff linux-2.2.18/kernel/sysctl.c
linux-2.2.18-greg/kernel/sysctl.c
--- linux-2.2.18/kernel/sysctl.c Sun Dec 10 16:49:44 2000
+++ linux-2.2.18-greg/kernel/sysctl.c Fri Jan 26 10:31:38 2001
@@ -77,7 +77,7 @@
extern int pgt_cache_water[];
-static int parse_table(int *, int, void *, size_t *, void *, size_t,
+static int parse_table(int *, unsigned, void *, size_t *, void *, size_t,
ctl_table *, void **);
static int proc_doutsstring(ctl_table *table, int write, struct file *filp,
void *buffer, size_t *lenp);
@@ -320,7 +320,7 @@
}
-int do_sysctl (int *name, int nlen,
+int do_sysctl (int *name, unsigned nlen,
void *oldval, size_t *oldlenp,
void *newval, size_t newlen)
{
@@ -330,10 +330,12 @@
if (nlen == 0 || nlen >= CTL_MAXNAME)
return -ENOTDIR;
-
- if (oldval)
- {
- int old_len;
+
+ if ((ssize_t)newlen < 0)
+ return -EINVAL;
+
+ if (oldval) {
+ size_t old_len;
if (!oldlenp)
return -EFAULT;
if(get_user(old_len, oldlenp))
@@ -387,7 +389,7 @@
return test_perm(table->mode, op);
}
-static int parse_table(int *name, int nlen,
+static int parse_table(int *name, unsigned nlen,
void *oldval, size_t *oldlenp,
void *newval, size_t newlen,
ctl_table *table, void **context)
@@ -430,11 +432,12 @@
/* Perform the actual read/write of a sysctl table entry. */
int do_sysctl_strategy (ctl_table *table,
- int *name, int nlen,
+ int *name, unsigned nlen,
void *oldval, size_t *oldlenp,
void *newval, size_t newlen, void **context)
{
- int op = 0, rc, len;
+ int op = 0, rc;
+ size_t len;
if (oldval)
op |= 004;
@@ -458,6 +461,8 @@
if (oldval && oldlenp) {
get_user(len, oldlenp);
if (len) {
+ if (len < 0)
+ return -EINVAL;
if (len > table->maxlen)
len = table->maxlen;
if(copy_to_user(oldval, table->data, len))
@@ -642,7 +647,7 @@
int proc_dostring(ctl_table *table, int write, struct file *filp,
void *buffer, size_t *lenp)
{
- int len;
+ size_t len;
char *p, c;
if (!table->data || !table->maxlen || !*lenp ||
@@ -710,7 +715,8 @@
static int do_proc_dointvec(ctl_table *table, int write, struct file *filp,
void *buffer, size_t *lenp, int conv, int op)
{
- int *i, vleft, first=1, len, left, neg, val;
+ int *i, neg, val;
+ size_t len, left, vleft, first=1;
#define TMPBUFLEN 20
char buf[TMPBUFLEN], *p;
@@ -832,7 +838,8 @@
int proc_dointvec_minmax(ctl_table *table, int write, struct file *filp,
void *buffer, size_t *lenp)
{
- int *i, *min, *max, vleft, first=1, len, left, neg, val;
+ int *i, *min, *max, neg, val;
+ size_t len, left, vleft, first=1;
#define TMPBUFLEN 20
char buf[TMPBUFLEN], *p;
@@ -974,11 +981,12 @@
*/
/* The generic string strategy routine: */
-int sysctl_string(ctl_table *table, int *name, int nlen,
+int sysctl_string(ctl_table *table, int *name, unsigned nlen,
void *oldval, size_t *oldlenp,
void *newval, size_t newlen, void **context)
{
- int l, len;
+ unsigned l;
+ size_t len;
if (!table->data || !table->maxlen)
return -ENOTDIR;
@@ -1017,11 +1025,12 @@
* are between the minimum and maximum values given in the arrays
* table->extra1 and table->extra2, respectively.
*/
-int sysctl_intvec(ctl_table *table, int *name, int nlen,
+int sysctl_intvec(ctl_table *table, int *name, unsigned nlen,
void *oldval, size_t *oldlenp,
void *newval, size_t newlen, void **context)
{
- int i, length, *vec, *min, *max;
+ int *vec, *min, *max;
+ size_t i, length;
if (newval && newlen) {
if (newlen % sizeof(int) != 0)
@@ -1051,7 +1060,7 @@
}
/* Strategy function to convert jiffies to seconds */
-int sysctl_jiffies(ctl_table *table, int *name, int nlen,
+int sysctl_jiffies(ctl_table *table, int *name, unsigned nlen,
void *oldval, size_t *oldlenp,
void *newval, size_t newlen, void **context)
{
@@ -1159,21 +1168,21 @@
return -ENOSYS;
}
-int sysctl_string(ctl_table *table, int *name, int nlen,
+int sysctl_string(ctl_table *table, int *name, unsigned nlen,
void *oldval, size_t *oldlenp,
void *newval, size_t newlen, void **context)
{
return -ENOSYS;
}
-int sysctl_intvec(ctl_table *table, int *name, int nlen,
+int sysctl_intvec(ctl_table *table, int *name, unsigned nlen,
void *oldval, size_t *oldlenp,
void *newval, size_t newlen, void **context)
{
return -ENOSYS;
}
-int sysctl_jiffies(ctl_table *table, int *name, int nlen,
+int sysctl_jiffies(ctl_table *table, int *name, unsigned nlen,
void *oldval, size_t *oldlenp,
void *newval, size_t newlen, void **context)
{
diff -Naur -X /home/greg/linux/dontdiff linux-2.2.18/net/ipv4/route.c linux-2.2.18-greg/net/ipv4/route.c
--- linux-2.2.18/net/ipv4/route.c Sun Dec 10 16:49:44 2000
+++ linux-2.2.18-greg/net/ipv4/route.c Fri Jan 26 10:28:40 2001
@@ -1927,7 +1927,7 @@
return -EINVAL;
}
-static int ipv4_sysctl_rtcache_flush_strategy(ctl_table *table, int
*name, int nlen,
+static int ipv4_sysctl_rtcache_flush_strategy(ctl_table *table, int *name, unsigned nlen,
void *oldval, size_t *oldlenp,
void *newval, size_t newlen,
void **context)
diff -Naur -X /home/greg/linux/dontdiff linux-2.2.18/net/ipv4/sysctl_net_ipv4.c linux-2.2.18-greg/net/ipv4/sysctl_net_ipv4.c
--- linux-2.2.18/net/ipv4/sysctl_net_ipv4.c Sun Dec 10 16:49:44
2000
+++ linux-2.2.18-greg/net/ipv4/sysctl_net_ipv4.c Fri Jan 26 10:28:40 2001
@@ -87,7 +87,7 @@
return ret;
}
-static int ipv4_sysctl_forward_strategy(ctl_table *table, int *name,
int nlen,
+static int ipv4_sysctl_forward_strategy(ctl_table *table, int *name, unsigned nlen,
void *oldval, size_t *oldlenp,
void *newval, size_t newlen,
void **context)
(6077540) --------------------------------(Ombruten)