Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

sysctl: make sure to terminate strings with a NUL

This is a slightly more complete fix for the previous minimal sysctl
string fix. It always terminates the returned string with a NUL, even
if the full result wouldn't fit in the user-supplied buffer.

The returned length is the full untruncated length, so that you can
tell when truncation has occurred.

Signed-off-by: Linus Torvalds <torvalds@osdl.org>

+15 -10
+15 -10
kernel/sysctl.c
··· 2192 2192 void __user *oldval, size_t __user *oldlenp, 2193 2193 void __user *newval, size_t newlen, void **context) 2194 2194 { 2195 - size_t l, len; 2196 - 2197 2195 if (!table->data || !table->maxlen) 2198 2196 return -ENOTDIR; 2199 2197 2200 2198 if (oldval && oldlenp) { 2201 - if (get_user(len, oldlenp)) 2199 + size_t bufsize; 2200 + if (get_user(bufsize, oldlenp)) 2202 2201 return -EFAULT; 2203 - if (len) { 2204 - l = strlen(table->data)+1; 2205 - if (len > l) len = l; 2206 - if (len >= table->maxlen) 2202 + if (bufsize) { 2203 + size_t len = strlen(table->data), copied; 2204 + 2205 + /* This shouldn't trigger for a well-formed sysctl */ 2206 + if (len > table->maxlen) 2207 2207 len = table->maxlen; 2208 - if(copy_to_user(oldval, table->data, len)) 2208 + 2209 + /* Copy up to a max of bufsize-1 bytes of the string */ 2210 + copied = (len >= bufsize) ? bufsize - 1 : len; 2211 + 2212 + if (copy_to_user(oldval, table->data, copied) || 2213 + put_user(0, (char __user *)(oldval + copied))) 2209 2214 return -EFAULT; 2210 - if(put_user(len, oldlenp)) 2215 + if (put_user(len, oldlenp)) 2211 2216 return -EFAULT; 2212 2217 } 2213 2218 } 2214 2219 if (newval && newlen) { 2215 - len = newlen; 2220 + size_t len = newlen; 2216 2221 if (len > table->maxlen) 2217 2222 len = table->maxlen; 2218 2223 if(copy_from_user(table->data, newval, len))