Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1650762

Re: [PATCH] [iov_iter] use memmove() when copying to/from user page

From Al Viro <viro@ZenIV.linux.org.uk>
Newsgroups linux.kernel
Subject Re: [PATCH] [iov_iter] use memmove() when copying to/from user page
Date 2017-05-25 21:20 +0200
Message-ID <tL6sG-3NA-37@gated-at.bofh.it> (permalink)
References (5 earlier) <tHSme-2zE-21@gated-at.bofh.it> <tHSYX-371-27@gated-at.bofh.it> <tHTrX-3gi-11@gated-at.bofh.it> <tL4qS-2vP-25@gated-at.bofh.it> <tL5Gi-3fL-17@gated-at.bofh.it>
Organization linux.* mail to news gateway

Show all headers | View raw


On Thu, May 25, 2017 at 07:22:01PM +0100, Al Viro wrote:

> It does not make overlapping sendfile() work reliably (while
> creating an impression that it just might, as we'd seen in
> this thread).  It does not do anything to kernel-vs-userland
> aliasing either - copy_from_user() is definitely memcpy()-like,
> not memmove()-like.  Not that memmove() worked in situations
> when source and destination point to the same memory object
> seen at two virtial addresses...

BTW, the last part goes both for kernel and for userland:

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>

void f(char *p, char *q)
{
	memset(p, 0, 4096);
	p[254] = 1;
        memmove(q, p + 127, 256);
        memmove(p, q + 127, 256);
	printf("%d\n", p[0]);
}

main()
{
        static char p[4096];
        int fd = creat("/tmp/foo", 0600);
        unsigned char *p1, *p2;
        int i;

        write(fd, p, 4096);
        close(fd);
        fd = open("/tmp/foo", O_RDWR);
        p1 = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
        p2 = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);

	f(p1, p1);
	f(p1, p2);
	f(p2, p1);
}

should've printed 1 three times, according to C99/SuS.  On
stretch/amd64 (with 2.24-10 glibc) we get
1
1

0
instead.  mmap() is out of scope for C99, of course, but not for SuS.
And SuS treatment of memmove() is:

    [CX] [Option Start] The functionality described on this reference
    page is aligned with the ISO C standard. Any conflict between
    the requirements described here and the ISO C standard is
    unintentional. This volume of POSIX.1-2008 defers to the ISO C
    standard. [Option End]

    The memmove() function shall copy n bytes from the object pointed
    to by s2 into the object pointed to by s1. Copying takes place as if
    the n bytes from the object pointed to by s2 are first copied into a
    temporary array of n bytes that does not overlap the objects pointed
    to by s1 and s2, and then the n bytes from the temporary array are
    copied into the object pointed to by s1.

In case when physical memory areas overlap but addresses do not, results
of memmove(3) are impossible to rely upon on all implementations I've
seen.

Back to linux.kernel | Previous | NextPrevious in thread | Find similar | Unroll thread


Thread

Re: [PATCH] [iov_iter] use memmove() when copying to/from user page Pavel Machek <pavel@ucw.cz> - 2017-05-25 19:10 +0200
  Re: [PATCH] [iov_iter] use memmove() when copying to/from user page Eric Dumazet <edumazet@google.com> - 2017-05-25 19:20 +0200
    Re: [PATCH] [iov_iter] use memmove() when copying to/from user page Pavel Machek <pavel@ucw.cz> - 2017-05-25 23:30 +0200
  Re: [PATCH] [iov_iter] use memmove() when copying to/from user page Al Viro <viro@ZenIV.linux.org.uk> - 2017-05-25 20:30 +0200
    Re: [PATCH] [iov_iter] use memmove() when copying to/from user page Al Viro <viro@ZenIV.linux.org.uk> - 2017-05-25 21:20 +0200

csiph-web