From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 8336 invoked by alias); 13 Mar 2017 20:05:10 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 8320 invoked by uid 89); 13 Mar 2017 20:05:09 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-27.2 required=5.0 tests=BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,RP_MATCHES_RCVD,SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=banging X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 13 Mar 2017 20:05:08 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id A2FE879DE4; Mon, 13 Mar 2017 20:05:08 +0000 (UTC) Received: from [127.0.0.1] (ovpn04.gateway.prod.ext.phx2.redhat.com [10.5.9.4]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v2DK57au026252; Mon, 13 Mar 2017 16:05:08 -0400 Subject: Re: [PATCH 3/3] linux-nat: Exploit /proc//mem for writing To: Andreas Arnez , gdb-patches@sourceware.org References: <1488816060-20776-1-git-send-email-arnez@linux.vnet.ibm.com> <1488816060-20776-4-git-send-email-arnez@linux.vnet.ibm.com> From: Pedro Alves Message-ID: <02db005d-ce53-2ed7-7668-31b721621f54@redhat.com> Date: Mon, 13 Mar 2017 20:05:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.4.0 MIME-Version: 1.0 In-Reply-To: <1488816060-20776-4-git-send-email-arnez@linux.vnet.ibm.com> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-SW-Source: 2017-03/txt/msg00202.txt.bz2 On 03/06/2017 04:00 PM, Andreas Arnez wrote: > So far linux_proc_xfer_partial refused to handle write requests. This is > still based on the assumption that the Linux kernel does not support > writes to /proc//mem. That used to be true, but has changed with > Linux 2.6.39 released in May 2011. Hey, I had not noticed that. Awesome. (There's also process_vm_readv / process_vm_writev.) > This patch lifts this restriction and now exploits /proc//mem for > writing to inferior memory as well, if possible. > > gdb/ChangeLog: > > * linux-nat.c (linux_proc_xfer_partial): Handle write operations > as well. > --- > gdb/linux-nat.c | 32 ++++++++++++++++---------------- > 1 file changed, 16 insertions(+), 16 deletions(-) > > diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c > index c58ed83..73ef2d4 100644 > --- a/gdb/linux-nat.c > +++ b/gdb/linux-nat.c > @@ -3978,10 +3978,9 @@ linux_child_pid_to_exec_file (struct target_ops *self, int pid) > return linux_proc_pid_to_exec_file (pid); > } > > -/* Implement the to_xfer_partial interface for memory reads using the /proc > - filesystem. Because we can use a single read() call for /proc, this > - can be much more efficient than banging away at PTRACE_PEEKTEXT, > - but it doesn't support writes. */ > +/* Implement the to_xfer_partial target method using /proc//mem. > + Because we can use a single read/write call, this can be much more > + efficient than banging away at PTRACE_PEEKTEXT. */ > > static enum target_xfer_status > linux_proc_xfer_partial (struct target_ops *ops, enum target_object object, > @@ -3993,7 +3992,7 @@ linux_proc_xfer_partial (struct target_ops *ops, enum target_object object, > int fd; > char filename[64]; > > - if (object != TARGET_OBJECT_MEMORY || !readbuf) > + if (object != TARGET_OBJECT_MEMORY) > return TARGET_XFER_EOF; > > /* Don't bother for one word. */ > @@ -4004,26 +4003,27 @@ linux_proc_xfer_partial (struct target_ops *ops, enum target_object object, > thread. That requires some juggling, but is even faster. */ > xsnprintf (filename, sizeof filename, "/proc/%d/mem", > ptid_get_pid (inferior_ptid)); > - fd = gdb_open_cloexec (filename, O_RDONLY | O_LARGEFILE, 0); > + fd = gdb_open_cloexec (filename, ((readbuf ? O_RDONLY : O_WRONLY) > + | O_LARGEFILE), 0); > if (fd == -1) > return TARGET_XFER_EOF; > > - /* If pread64 is available, use it. It's faster if the kernel > - supports it (only one syscall), and it's 64-bit safe even on > - 32-bit platforms (for instance, SPARC debugging a SPARC64 > - application). */ > + /* Use pread64/pwrite64 if available, since they save a syscall and can > + handle 64-bit offsets even on 32-bit platforms (for instance, SPARC > + debugging a SPARC64 application). */ > #ifdef HAVE_PREAD64 > - if (pread64 (fd, readbuf, len, offset) != len) > + ret = (readbuf ? pread64 (fd, readbuf, len, offset) > + : pwrite64 (fd, writebuf, len, offset)); > #else > - if (lseek (fd, offset, SEEK_SET) == -1 || read (fd, readbuf, len) != len) > + ret = lseek (fd, offset, SEEK_SET); > + if (ret != -1) > + ret = (readbuf ? read (fd, readbuf, len) > + : write (fd, writebuf, len)); > #endif > - ret = 0; > - else > - ret = len; > > close (fd); > > - if (ret == 0) > + if (ret == -1 || ret == 0) > return TARGET_XFER_EOF; Are we sure we can't see partial reads/writes here? I.e., seems like we lose the "read/pread64 (fd, readbuf, len) != len" checks? Thanks, Pedro Alves