public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Vegard Nossum <vegard.nossum@gmail.com>
To: Tom Tucker <tom@opengridcomputing.com>,
	Neil Brown <neilb@suse.de>, Chuck Lever <chuck.lever@oracle.com>,
	Greg Banks <gnb@sgi.com>,
	"J. Bruce Fields" <bfields@citi.umich.edu>
Cc: linux-kernel@vger.kernel.org
Subject: buffer overflow in /proc/sys/sunrpc/transports
Date: Sat, 30 Aug 2008 20:44:22 +0200	[thread overview]
Message-ID: <20080830184422.GA9598@localhost.localdomain> (raw)

Hi,

I noticed that something weird is going on with /proc/sys/sunrpc/transports.
This file is generated in net/sunrpc/sysctl.c, function proc_do_xprt(). When
I "cat" this file, I get the expected output:

    $ cat /proc/sys/sunrpc/transports 
    tcp 1048576
    udp 32768

But I think that it does not check the length of the buffer supplied by
userspace to read(). With my original program, I found that the stack was
being overwritten by the characters above, even when the length given to
read() was just 1. So I have created a test program, see it at the bottom of
this e-mail. Here is its output:

    $ gcc -Wall -std=gnu99 proc-sys-sunrpc-transports.c && ./a.out 
    read(0) returned 0, errno = 0
    read(1) returned -1, errno = 21
    read(2) returned -1, errno = 20
    read(3) returned -1, errno = 19
    read(4) returned -1, errno = 18
    read(5) returned -1, errno = 17
    read(6) returned -1, errno = 16
    read(7) returned -1, errno = 15

...etc. This program just reopens the file and tries to read a different
number of characters each time. Strace can be used to verify that it really
returns these errnos.

With a small change to the program, we can also compare the buffer address
passed to read() and see that the kernel wrote the full file into the buffer
regardless of how many bytes we wanted to get back.

I don't know if this could be used in some malicious way. Maybe if a setuid
root program tried to open a user-supplied file (which could be this one in
/proc), it could crash the program quite easily. But since there is no way
to change the contents of the file... I don't know. Maybe a denial of
service attack where some user can make a daemon open a custom file and
crash? But it relies on the buffer being small enough, and the file is only
38 bytes on my machine. Who would pass a buffer to read that was smaller
than 38 bytes anyway? :-)

This file was introduced in

commit dc9a16e49dbba3dd042e6aec5d9a7929e099a89b
Author: Tom Tucker <tom@opengridcomputing.com>
Date:   Sun Dec 30 21:08:31 2007 -0600

    svc: Add /proc/sys/sunrpc/transport files
    
    Add a file that when read lists the set of registered svc
    transports.
    
    Signed-off-by: Tom Tucker <tom@opengridcomputing.com>
    Acked-by: Neil Brown <neilb@suse.de>
    Reviewed-by: Chuck Lever <chuck.lever@oracle.com>
    Reviewed-by: Greg Banks <gnb@sgi.com>
    Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>

...adding everybody to Cc.

Thanks,


Vegard

--

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int
main(void)
{
	for (int i = 0; i < 20; ++i) {
		int fd = open("/proc/sys/sunrpc/transports", O_RDONLY);
		if (fd == -1)
			exit(EXIT_FAILURE);

		char buf[512];
		memset(buf, 0, sizeof(buf));

		int ret = read(fd, buf, i);
		printf("read(%d) returned %d, errno = %d\n", i, ret, errno);

		close(fd);
	}

	return EXIT_SUCCESS;
}

             reply	other threads:[~2008-08-30 18:44 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-08-30 18:44 Vegard Nossum [this message]
2008-08-30 19:06 ` buffer overflow in /proc/sys/sunrpc/transports Cyrill Gorcunov
2008-08-30 19:15   ` Vegard Nossum
2008-08-30 19:21     ` Cyrill Gorcunov
2008-08-30 19:23       ` Cyrill Gorcunov
2008-08-30 19:34       ` Vegard Nossum
2008-08-30 19:44         ` Cyrill Gorcunov
2008-08-30 19:42   ` Vegard Nossum
2008-08-30 19:45     ` Cyrill Gorcunov
2008-08-30 19:56     ` Cyrill Gorcunov
2008-08-30 19:59       ` Vegard Nossum
2008-08-30 20:04         ` Cyrill Gorcunov
2008-08-30 20:13           ` Vegard Nossum
2008-08-30 20:15             ` Cyrill Gorcunov
2008-08-30 20:29             ` Cyrill Gorcunov
2008-08-30 22:55   ` David Wagner
2008-08-31  8:37     ` Cyrill Gorcunov
2008-08-31 10:30     ` Cyrill Gorcunov
2008-08-31 10:37       ` Cyrill Gorcunov
2008-08-30 20:20 ` David Wagner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20080830184422.GA9598@localhost.localdomain \
    --to=vegard.nossum@gmail.com \
    --cc=bfields@citi.umich.edu \
    --cc=chuck.lever@oracle.com \
    --cc=gnb@sgi.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=neilb@suse.de \
    --cc=tom@opengridcomputing.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox