lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <Pine.LNX.4.64.0612271601430.4473@woody.osdl.org>
Date:	Wed, 27 Dec 2006 16:16:12 -0800 (PST)
From:	Linus Torvalds <torvalds@...l.org>
To:	David Miller <davem@...emloft.net>
cc:	ranma@...edrich.de, gordonfarquharson@...il.com, tbm@...ius.com,
	a.p.zijlstra@...llo.nl, andrei.popa@...eo.ro,
	Andrew Morton <akpm@...l.org>, hugh@...itas.com,
	nickpiggin@...oo.com.au, arjan@...radead.org,
	Linux Kernel Mailing List <linux-kernel@...r.kernel.org>
Subject: Re: [PATCH] mm: fix page_mkclean_one


On Tue, 26 Dec 2006, David Miller wrote:
> 
> I've seen it on sparc64, UP kernel, no preempt.

Ok, I still don't have a clue, but I think I at least have a new 
test-case.

It can probably be improved upon, but this would _seem_ to trigger the 
problem. Can people check?

You'd want to make sure you get page-put activity, by making TARGETSIZE be 
big enough to cause memory pressure (and rather than making it bigger, you 
might want to make your memory smaller instead, to make it run more 
quickly. Either using "mem=128M" or big compiles or something...).

If it finds corruption, you'll see something like

	Writing chunk 183858/183859 (99%)
	Chunk ..
	Chunk 120887 corrupted
	Chunk 122372 corrupted
	Chunk ...
	Checking chunk 183858/183859 (99%)

otherwise it will just say

	Writing chunk 183858/183859 (99%)
	Checking chunk 183858/183859 (99%)

and exit.

I didn't spend a lot of time verifying this, but I _was_ able to cause 
those "Chunk xxx corrupted" messages with this. There's probably a more 
efficient better way to do it, but this is better than trying to use 
rtorrent, and also makes any worries about what rtorrent does go away.

Of course, maybe it's this test-program that is buggy now, although it 
looks trivial enough that I don't think it is.

I think my earlier stress-tester may not have triggered this, because it 
just did all its writing in a linear order, so any LRU logic will happen 
to write back old pages that we are no longer touching. The randomization 
(and using a chunksize that isn't a multiple of a page-size) makes sure 
that we're actually going to have lots of rewriting going on.

I think the test-case could probably be improved by having a munmap() and 
page-cache flush in between the writing and the checking, to see whether 
that shows the corruption easier (and possibly without having to start 
paging in order to throw the pages out, which would simplify testing a 
lot). But I haven't tested. I decided to post this asap, now that I've 
recreated the corruption with something else, and something that is 
possibly easier to analyze..

		Linus

----
#include <sys/mman.h>
#include <sys/fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <time.h>

#define TARGETSIZE (256 << 20)
#define CHUNKSIZE (1460)
#define NRCHUNKS (TARGETSIZE / CHUNKSIZE)
#define SIZE (NRCHUNKS * CHUNKSIZE)

static void fillmem(void *start, int nr)
{
	memset(start, nr, CHUNKSIZE);
}

static void checkmem(void *start, int nr)
{
	unsigned char c = nr, *p = start;
	int i;
	for (i = 0; i < CHUNKSIZE; i++) {
		if (*p++ != c) {
			printf("Chunk %d corrupted               \n", nr);
			return;
		}
	}
}

int main(int argc, char **argv)
{
	char *mapping;
	int fd, i;
	static int chunkorder[NRCHUNKS];

	/*
	 * Make some random ordering of writing the chunks to the
	 * memory map..
	 *
	 * Start with fully ordered..
	 */
	for (i = 0; i < NRCHUNKS; i++)
		chunkorder[i] = i;

	/* ..and then mix it up randomly */
	srandom(time(NULL));
	for (i = 0; i < NRCHUNKS; i++) {
		int index = (unsigned int) random() % NRCHUNKS;
		int nr = chunkorder[index];
		chunkorder[index] = chunkorder[i];
		chunkorder[i] = nr;
	}

	fd = open("mapfile", O_RDWR | O_TRUNC | O_CREAT, 0666);
	if (fd < 0)
		return -1;
	if (ftruncate(fd, SIZE) < 0)
		return -1;
	mapping = mmap(NULL, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
	if (-1 == (int)(long)mapping)
		return -1;

	for (i = 0; i < NRCHUNKS; i++) {
		int chunk = chunkorder[i];
		printf("Writing chunk %d/%d (%d%%)     \r", i, NRCHUNKS, 100*i/NRCHUNKS);
		fillmem(mapping + chunk * CHUNKSIZE, chunk);
	}
	printf("\n");
	for (i = 0; i < NRCHUNKS; i++) {
		int chunk = i;
		printf("Checking chunk %d/%d (%d%%)     \r", i, NRCHUNKS, 100*i/NRCHUNKS);
		checkmem(mapping + chunk * CHUNKSIZE, chunk);
	}
	printf("\n");
	
	return 0;
}
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ