tags 547902 + patch quit Hi, please see http://bugs.debian.org/547902
Here's a patch from Christian Hohnstaedt <chohnsta...@innominate.com> Thanks, Gerrit. --- Testparameter: for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19; do dd if=/proc/sys/net/ipv4/tcp_wmem bs=$i 2>/dev/null; done for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19; do dd if=/proc/sys/net/ipv4/tcp_wmem skip=$i bs=1 2>/dev/null |wc -c ; done diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 9270125..038df14 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -2117,17 +2117,16 @@ static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table, #define TMPBUFLEN 21 int *i, vleft, first=1, neg, val; unsigned long lval; - size_t left, len; + size_t left, len, off; char buf[TMPBUFLEN], *p; char __user *s = buffer; - if (!tbl_data || !table->maxlen || !*lenp || - (*ppos && !write)) { + if (!tbl_data || !table->maxlen || !*lenp) { *lenp = 0; return 0; } - + off = 0; i = (int *) tbl_data; vleft = table->maxlen / sizeof(*i); left = *lenp; @@ -2176,25 +2175,31 @@ static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table, if (conv(&neg, &lval, i, 1, data)) break; } else { + loff_t diff; p = buf; - if (!first) - *p++ = '\t'; - if (conv(&neg, &lval, i, 0, data)) break; - sprintf(p, "%s%lu", neg ? "-" : "", lval); - len = strlen(buf); - if (len > left) - len = left; - if(copy_to_user(s, buf, len)) - return -EFAULT; - left -= len; - s += len; + len = sprintf(p, "%s%s%lu", first ? "" : "\t", + neg ? "-" : "", lval); + diff = *ppos - off; + off += len; + if (diff > 0 && diff < len) { + p += diff; + len -= diff; + } + if (off > *ppos) { + if (len > left) + len = left; + if(copy_to_user(s, p, len)) + return -EFAULT; + left -= len; + s += len; + } } } - if (!write && !first && left) { + if (!write && !first && left && off >= *ppos) { if(put_user('\n', s)) return -EFAULT; left--, s++; -- To UNSUBSCRIBE, email to debian-kernel-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org