From: Jiri Olsa <jolsa@redhat.com>
To: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Andi Kleen <andi@firstfloor.org>,
Kees Cook <keescook@chromium.org>, Jiri Olsa <jolsa@kernel.org>,
lkml <linux-kernel@vger.kernel.org>,
Ingo Molnar <mingo@kernel.org>,
Adrian Hunter <adrian.hunter@intel.com>,
KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Subject: Re: [PATCH] fs/proc/kcore.c: Omit kernel text area for hardened usercopy feature
Date: Wed, 7 Sep 2016 23:24:47 +0200 [thread overview]
Message-ID: <20160907212447.GA31138@krava> (raw)
In-Reply-To: <20160907192559.GB2422@krava>
On Wed, Sep 07, 2016 at 09:25:59PM +0200, Jiri Olsa wrote:
> On Wed, Sep 07, 2016 at 09:58:01AM -0700, Linus Torvalds wrote:
> > On Wed, Sep 7, 2016 at 9:38 AM, Andi Kleen <andi@firstfloor.org> wrote:
> > >>
> > >> - n = copy_to_user(buffer, (char *)start, tsz);
> > >> + buf = kzalloc(tsz, GFP_KERNEL);
> > >
> > > You have to add some limit and a loop, otherwise a user can eat all kernel memory,
> > > or copies > KMALLOC_MAX wouldn't work. Probably only get a single page.
> >
> > 'start' and 'tsz' is already chunked to be aligned pages (well, as
> > aligned as they can be: the beginning and end obviously won't be).
> > Above the loop:
> >
> > if ((tsz = (PAGE_SIZE - (start & ~PAGE_MASK))) > buflen)
> > tsz = buflen;
> >
> > and then inside the loop:
> >
> > tsz = (buflen > PAGE_SIZE ? PAGE_SIZE : buflen);
> >
> > so it's already limited to one page.
> >
> > That said, it *might* be worth moving the temporary allocation to the
> > top, or even to move it to open_kcore(). It used to be a special case
> > for just the vmalloc region, now it's always done.
> >
> > So instead of having two different copies of the same special case for
> > the two different cases, why not try to unify them and just have one
> > common (page-sized) buffer allocation?
I'll give this more testing, but it looks ok so far,
also maybe it should be split into 2 parts:
- adding the common buffer
- ktext using bounce buffer
jirka
diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c
index a939f5ed7f89..7405b3894183 100644
--- a/fs/proc/kcore.c
+++ b/fs/proc/kcore.c
@@ -430,6 +430,7 @@ static void elf_kcore_store_hdr(char *bufp, int nphdr, int dataoff)
static ssize_t
read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos)
{
+ char *buf = file->private_data;
ssize_t acc = 0;
size_t size, tsz;
size_t elf_buflen;
@@ -500,23 +501,20 @@ read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos)
if (clear_user(buffer, tsz))
return -EFAULT;
} else if (is_vmalloc_or_module_addr((void *)start)) {
- char * elf_buf;
-
- elf_buf = kzalloc(tsz, GFP_KERNEL);
- if (!elf_buf)
- return -ENOMEM;
- vread(elf_buf, (char *)start, tsz);
+ vread(buf, (char *)start, tsz);
/* we have to zero-fill user buffer even if no read */
- if (copy_to_user(buffer, elf_buf, tsz)) {
- kfree(elf_buf);
+ if (copy_to_user(buffer, buf, tsz))
return -EFAULT;
- }
- kfree(elf_buf);
} else {
if (kern_addr_valid(start)) {
unsigned long n;
- n = copy_to_user(buffer, (char *)start, tsz);
+ /*
+ * Using bounce buffer to bypass the
+ *hardened user copy kernel text checks.
+ */
+ memcpy(buf, (char *) start, tsz);
+ n = copy_to_user(buffer, buf, tsz);
/*
* We cannot distinguish between fault on source
* and fault on destination. When this happens
@@ -549,6 +547,11 @@ static int open_kcore(struct inode *inode, struct file *filp)
{
if (!capable(CAP_SYS_RAWIO))
return -EPERM;
+
+ filp->private_data = (void *) __get_free_pages(GFP_KERNEL, 0);
+ if (!filp->private_data)
+ return -ENOMEM;
+
if (kcore_need_update)
kcore_update_ram();
if (i_size_read(inode) != proc_root_kcore->size) {
@@ -556,13 +559,20 @@ static int open_kcore(struct inode *inode, struct file *filp)
i_size_write(inode, proc_root_kcore->size);
inode_unlock(inode);
}
+
return 0;
}
+static int release_kcore(struct inode *inode, struct file *file)
+{
+ free_pages((unsigned long) file->private_data, 0);
+ return 0;
+}
static const struct file_operations proc_kcore_operations = {
.read = read_kcore,
.open = open_kcore,
+ .release = release_kcore,
.llseek = default_llseek,
};
next prev parent reply other threads:[~2016-09-07 21:24 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-09-02 12:25 [PATCH] fs/proc/kcore.c: Omit kernel text area for hardened usercopy feature Jiri Olsa
2016-09-02 15:17 ` Andi Kleen
2016-09-02 16:15 ` Jiri Olsa
2016-09-05 8:47 ` Jiri Olsa
2016-09-05 16:27 ` Andi Kleen
2016-09-06 17:56 ` Kees Cook
2016-09-06 18:34 ` Linus Torvalds
2016-09-06 19:41 ` Andi Kleen
2016-09-06 19:48 ` Linus Torvalds
2016-09-07 17:17 ` Kees Cook
2016-09-07 17:24 ` Linus Torvalds
2016-09-07 7:32 ` Jiri Olsa
2016-09-07 16:38 ` Andi Kleen
2016-09-07 16:58 ` Linus Torvalds
2016-09-07 19:25 ` Jiri Olsa
2016-09-07 21:24 ` Jiri Olsa [this message]
2016-09-07 22:52 ` Linus Torvalds
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=20160907212447.GA31138@krava \
--to=jolsa@redhat.com \
--cc=adrian.hunter@intel.com \
--cc=andi@firstfloor.org \
--cc=jolsa@kernel.org \
--cc=kamezawa.hiroyu@jp.fujitsu.com \
--cc=keescook@chromium.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@kernel.org \
--cc=torvalds@linux-foundation.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).