Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit de9e007d authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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: default avatarLinus Torvalds <torvalds@osdl.org>
parent 35f349ee
Loading
Loading
Loading
Loading
+15 −10
Original line number Diff line number Diff line
@@ -2192,27 +2192,32 @@ int sysctl_string(ctl_table *table, int __user *name, int nlen,
		  void __user *oldval, size_t __user *oldlenp,
		  void __user *newval, size_t newlen, void **context)
{
	size_t l, len;
	
	if (!table->data || !table->maxlen) 
		return -ENOTDIR;
	
	if (oldval && oldlenp) {
		if (get_user(len, oldlenp))
		size_t bufsize;
		if (get_user(bufsize, oldlenp))
			return -EFAULT;
		if (len) {
			l = strlen(table->data)+1;
			if (len > l) len = l;
			if (len >= table->maxlen)
		if (bufsize) {
			size_t len = strlen(table->data), copied;

			/* This shouldn't trigger for a well-formed sysctl */
			if (len > table->maxlen)
				len = table->maxlen;
			if(copy_to_user(oldval, table->data, len))

			/* Copy up to a max of bufsize-1 bytes of the string */
			copied = (len >= bufsize) ? bufsize - 1 : len;

			if (copy_to_user(oldval, table->data, copied) ||
			    put_user(0, (char __user *)(oldval + copied)))
				return -EFAULT;
			if (put_user(len, oldlenp))
				return -EFAULT;
		}
	}
	if (newval && newlen) {
		len = newlen;
		size_t len = newlen;
		if (len > table->maxlen)
			len = table->maxlen;
		if(copy_from_user(table->data, newval, len))