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-next>] [day] [month] [year] [list]
Message-ID: <20140325150017.GA2336@tucsk.piliscsaba.szeredi.hu>
Date:	Tue, 25 Mar 2014 16:00:17 +0100
From:	Miklos Szeredi <miklos@...redi.hu>
To:	viro@...IV.linux.org.uk, torvalds@...ux-foundation.org,
	mtk.manpages@...il.com, linux-fsdevel@...r.kernel.org,
	linux-kernel@...r.kernel.org, hch@...radead.org,
	akpm@...ux-foundation.org, zab@...hat.com
Subject: splicing pages to the same file

In pipe_to_file() I noticed the "if (buf->page != page)" and started thinking
about this.  What should be the correct behavior?

Currently we just skip pages that are equal, but the results can be pretty
strange.  E.g. see the output of the following with attached test prog.

 seq -f "%07.0f" 0 1023 > /tmp/x
 ./splice_test /tmp/x 800 /tmp/x 1600 4096

Adding memmove() to an "else" branch will result in even more strangeness: by
the time splice moves onto the second page of the destination, the first buffer
was already "corrupted".

We could clone the page in the pipe buffer in this case, but is it worth the
effort?

Or should we just return EINVAL?

Or just leave it and document the strangeness?

Thanks,
Miklos
----

#define _GNU_SOURCE

#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <err.h>

int main(int argc, char *argv[])
{
	const char *in_file, *out_file;
	int in_fd, out_fd;
	off_t in_off, out_off;
	size_t size;
	int pip[2];
	ssize_t res;

	if (argc != 6) {
		errx(1, "usage: %s in_file in_off out_file out_off size",
		     argv[0]);
	}

	in_file = argv[1];
	in_off = strtoull(argv[2], NULL, 0);
	out_file = argv[3];
	out_off = strtoull(argv[4], NULL, 0);
	size = strtoul(argv[5], NULL, 0);

	in_fd = open(in_file, O_RDONLY);
	if (in_fd == -1)
		err(1, "creating %s", in_file);

	out_fd = open(out_file, O_WRONLY);
	if (out_fd == -1)
		err(1, "creating %s", out_file);

	res = pipe(pip);
	if (res == -1)
		err(1, "pipe");

	res = splice(in_fd, &in_off, pip[1], NULL, size, 0);
	if (res == -1)
		err(1, "splice to pipe");
	if ((size_t) res != size)
		errx(1, "short splice to pipe");

	res = splice(pip[0], NULL, out_fd, &out_off, size, 0);
	if (res == -1)
		err(1, "splice from pipe");
	if ((size_t) res != size)
		errx(1, "short splice from pipe");

	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