From patchwork Wed Aug 13 19:04:48 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Musta X-Patchwork-Id: 379727 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id DB3551400B2 for ; Thu, 14 Aug 2014 05:11:55 +1000 (EST) Received: from localhost ([::1]:49720 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XHdxh-0006k3-Ox for incoming@patchwork.ozlabs.org; Wed, 13 Aug 2014 15:11:53 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55279) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XHdsP-0006GE-N2 for qemu-devel@nongnu.org; Wed, 13 Aug 2014 15:06:31 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XHdsK-0004ZB-4A for qemu-devel@nongnu.org; Wed, 13 Aug 2014 15:06:25 -0400 Received: from mail-ob0-x235.google.com ([2607:f8b0:4003:c01::235]:40064) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XHdsJ-0004Z0-Vq; Wed, 13 Aug 2014 15:06:20 -0400 Received: by mail-ob0-f181.google.com with SMTP id va2so148623obc.40 for ; Wed, 13 Aug 2014 12:06:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=DcM9v3MSYfHsY2BBd4m51Sl9bfN1m0uEJBfpk9OrTuQ=; b=TJiOX7T93REq/3gOBmObKE/GXKtAFW93gqCvQEAyHsmvyM2NKhdBSY3DnplKIn/6TF g3UveFRyKV4pQIKUjsBS5lcEim1T/QPrTMjuo9tGQdJg4IScXL2LBGov23MnNwGqCE8n TYmMc2ODtLM7w7j8jtb9VZ36axV6BQf5mUSZx6t6HAQMYzxgBQ5Ub50telSQU1Gl1A9T Tf2VeigdTjA663qZEg/AK6cCzBUCWNZk1/5o5IquLDCa3WHxaM204sa7286W1JzMrZAu Nef7G+yeJUCyxQgrRJaVDSvrakXvk2+yvoEDQhFFw3TVGTn7PPUYUcZvEvgax+Sa3Uqn RGxA== X-Received: by 10.182.246.39 with SMTP id xt7mr6854179obc.63.1407956779500; Wed, 13 Aug 2014 12:06:19 -0700 (PDT) Received: from tmusta-sc.rchland.ibm.com (rchp4.rochester.ibm.com. [129.42.161.36]) by mx.google.com with ESMTPSA id ej4sm3032727obb.28.2014.08.13.12.06.14 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 13 Aug 2014 12:06:18 -0700 (PDT) From: Tom Musta To: qemu-devel@nongnu.org, qemu-ppc@nongnu.org Date: Wed, 13 Aug 2014 14:04:48 -0500 Message-Id: <1407956688-16006-14-git-send-email-tommusta@gmail.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1407956688-16006-1-git-send-email-tommusta@gmail.com> References: <1407956688-16006-1-git-send-email-tommusta@gmail.com> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2607:f8b0:4003:c01::235 Cc: Tom Musta , riku.voipio@linaro.org, agraf@suse.de Subject: [Qemu-devel] [V3 PATCH 13/13] linux-user: writev Partial Writes X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Although not technically not required by POSIX, the writev system call will typically write out its buffers individually. That is, if the first buffer is written successfully, but the second buffer pointer is invalid, then the first chuck will be written and its size is returned. Signed-off-by: Tom Musta Reviewed-by: Peter Maydell --- V2: Use bool instead of int for "bad_address" per Peter Maydell's review. linux-user/syscall.c | 16 ++++++++++++++-- 1 files changed, 14 insertions(+), 2 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index edc48e1..fb54f0e 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -1798,6 +1798,7 @@ static struct iovec *lock_iovec(int type, abi_ulong target_addr, abi_ulong total_len, max_len; int i; int err = 0; + bool bad_address = false; if (count == 0) { errno = 0; @@ -1838,9 +1839,20 @@ static struct iovec *lock_iovec(int type, abi_ulong target_addr, vec[i].iov_base = 0; } else { vec[i].iov_base = lock_user(type, base, len, copy); + /* If the first buffer pointer is bad, this is a fault. But + * subsequent bad buffers will result in a partial write; this + * is realized by filling the vector with null pointers and + * zero lengths. */ if (!vec[i].iov_base) { - err = EFAULT; - goto fail; + if (i == 0) { + err = EFAULT; + goto fail; + } else { + bad_address = true; + } + } + if (bad_address) { + len = 0; } if (len > max_len - total_len) { len = max_len - total_len;