From patchwork Tue Oct 18 13:21:34 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Riku Voipio X-Patchwork-Id: 78037 Delivered-To: patch@linaro.org Received: by 10.140.97.247 with SMTP id m110csp884568qge; Tue, 18 Oct 2016 06:25:47 -0700 (PDT) X-Received: by 10.55.24.77 with SMTP id j74mr477254qkh.226.1476797147134; Tue, 18 Oct 2016 06:25:47 -0700 (PDT) Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id r21si20999529qta.62.2016.10.18.06.25.47 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 18 Oct 2016 06:25:47 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:41509 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bwUOo-0008MJ-Fn for patch@linaro.org; Tue, 18 Oct 2016 09:25:46 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53817) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bwULJ-0006J7-1x for qemu-devel@nongnu.org; Tue, 18 Oct 2016 09:22:13 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bwULD-0000eT-GN for qemu-devel@nongnu.org; Tue, 18 Oct 2016 09:22:09 -0400 Received: from mail-lf0-x234.google.com ([2a00:1450:4010:c07::234]:35799) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1bwULD-0000dv-2U for qemu-devel@nongnu.org; Tue, 18 Oct 2016 09:22:03 -0400 Received: by mail-lf0-x234.google.com with SMTP id l131so25235123lfl.2 for ; Tue, 18 Oct 2016 06:22:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=7Yrl+OIMXNNfKE92iWPCgwayAUyA2X4TYx3NBt12JbI=; b=LJVDFaIep1TJIXQFxTL+hgco4ZPOSnD+WbdCE29Lc8Rv8EOgBiP7ogOlKM3lj9sm9n uiwoHTbg+AgpMGntd6FqtDDxQfucaycrKwMpnZaaCvafwSmqYSvm56HAAgUJBgP8ySrX NXU6+TEIof6Yf+2PT022oiGHsPihLGwfFw3MQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=7Yrl+OIMXNNfKE92iWPCgwayAUyA2X4TYx3NBt12JbI=; b=V7Ej1gAZbY5vAjH3Yb02+Cm/2bZ8JBkh+r20HVNu2h433preX7wRz9SG2afsqLR1qk CZzMlauxj5SENhAosyib5z9rrO+w+sbHBY/NOlKp0m2g2xPJs2qelW2TwSSU1byOmpxX ozNf5AStWOC22jjIGNH4FKK1Z8S47+cWHsV0fTQFg40Xhth24ryf37XMRn5ZuGjUZvlu yDhWEhi9ZjR4lHQTeaBkrCiYRWvGX417+c0dp1MVbCScCzYXKs5pEzH/Q1ybzZDbqis8 ubGSnSQh/a5s+kjF3SnMn1dyVoXGLrDGKu3BxpuBZEcqYp4CmZxmPveEMmzeccd0zTMI 5wSQ== X-Gm-Message-State: AA6/9RkV7+ShnUlmv90S8cK/gNlJykNNQndNmHVxwH4fHrZmR08JeK5bVwgnXw6TY1XfygL0 X-Received: by 10.25.163.17 with SMTP id m17mr511172lfe.161.1476796919466; Tue, 18 Oct 2016 06:21:59 -0700 (PDT) Received: from beaming.home (91-157-170-157.elisa-laajakaista.fi. [91.157.170.157]) by smtp.gmail.com with ESMTPSA id 201sm9535359ljf.48.2016.10.18.06.21.58 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 18 Oct 2016 06:21:58 -0700 (PDT) From: riku.voipio@linaro.org To: qemu-devel@nongnu.org Date: Tue, 18 Oct 2016 16:21:34 +0300 Message-Id: <53553bf4a8ec613f0425f472f371bef040f5e2db.1476796525.git.riku.voipio@linaro.org> X-Mailer: git-send-email 2.1.4 In-Reply-To: References: X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2a00:1450:4010:c07::234 Subject: [Qemu-devel] [PULL v2 06/22] linux-user: Fix syslog() syscall support X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Peter Maydell , Aleksandar Markovic Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Aleksandar Markovic There are currently several problems related to syslog() support. For example, if the second argument "bufp" of target syslog() syscall is NULL, the current implementation always returns error code EFAULT. However, NULL is a perfectly valid value for the second argument for many use cases of this syscall. This is, for example, visible from this excerpt of man page for syslog(2): > EINVAL Bad arguments (e.g., bad type; or for type 2, 3, or 4, buf is > NULL, or len is less than zero; or for type 8, the level is > outside the range 1 to 8). Moreover, the argument "bufp" is ignored for all cases of values of the first argument, except 2, 3 and 4. This means that for such cases (the first argument is not 2, 3 or 4), there is no need to pass "buf" between host and target, and it can be set to NULL while calling host's syslog(), without loss of emulation accuracy. Note also that if "bufp" is NULL and the first argument is 2, 3 or 4, the correct returned error code is EINVAL, not EFAULT. All these details are reflected in this patch. "#ifdef TARGET_NR_syslog" is also proprerly inserted when needed. Support for Qemu's "-strace" switch for syslog() syscall is included too. LTP tests syslog11 and syslog12 pass with this patch (while fail without it), on any platform. Changes to original patch by Riku Voipio: fixed error paths in TARGET_SYSLOG_ACTION_READ_ALL to match http://lxr.free-electrons.com/source/kernel/printk/printk.c?v=4.7#L1335 Should fix also the build error in: https://lists.gnu.org/archive/html/qemu-devel/2016-10/msg03721.html Signed-off-by: Aleksandar Markovic Signed-off-by: Riku Voipio --- linux-user/strace.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++ linux-user/strace.list | 2 +- linux-user/syscall.c | 50 ++++++++++++++++++++++++++++---- linux-user/syscall_defs.h | 25 ++++++++++++++++ 4 files changed, 142 insertions(+), 7 deletions(-) -- 2.1.4 diff --git a/linux-user/strace.c b/linux-user/strace.c index a0e45b5..679f840 100644 --- a/linux-user/strace.c +++ b/linux-user/strace.c @@ -1827,6 +1827,78 @@ print_rt_sigprocmask(const struct syscallname *name, } #endif +#ifdef TARGET_NR_syslog +static void +print_syslog_action(abi_ulong arg, int last) +{ + const char *type; + + switch (arg) { + case TARGET_SYSLOG_ACTION_CLOSE: { + type = "SYSLOG_ACTION_CLOSE"; + break; + } + case TARGET_SYSLOG_ACTION_OPEN: { + type = "SYSLOG_ACTION_OPEN"; + break; + } + case TARGET_SYSLOG_ACTION_READ: { + type = "SYSLOG_ACTION_READ"; + break; + } + case TARGET_SYSLOG_ACTION_READ_ALL: { + type = "SYSLOG_ACTION_READ_ALL"; + break; + } + case TARGET_SYSLOG_ACTION_READ_CLEAR: { + type = "SYSLOG_ACTION_READ_CLEAR"; + break; + } + case TARGET_SYSLOG_ACTION_CLEAR: { + type = "SYSLOG_ACTION_CLEAR"; + break; + } + case TARGET_SYSLOG_ACTION_CONSOLE_OFF: { + type = "SYSLOG_ACTION_CONSOLE_OFF"; + break; + } + case TARGET_SYSLOG_ACTION_CONSOLE_ON: { + type = "SYSLOG_ACTION_CONSOLE_ON"; + break; + } + case TARGET_SYSLOG_ACTION_CONSOLE_LEVEL: { + type = "SYSLOG_ACTION_CONSOLE_LEVEL"; + break; + } + case TARGET_SYSLOG_ACTION_SIZE_UNREAD: { + type = "SYSLOG_ACTION_SIZE_UNREAD"; + break; + } + case TARGET_SYSLOG_ACTION_SIZE_BUFFER: { + type = "SYSLOG_ACTION_SIZE_BUFFER"; + break; + } + default: { + print_raw_param("%ld", arg, last); + return; + } + } + gemu_log("%s%s", type, get_comma(last)); +} + +static void +print_syslog(const struct syscallname *name, + abi_long arg0, abi_long arg1, abi_long arg2, + abi_long arg3, abi_long arg4, abi_long arg5) +{ + print_syscall_prologue(name); + print_syslog_action(arg0, 0); + print_pointer(arg1, 0); + print_raw_param("%d", arg2, 1); + print_syscall_epilogue(name); +} +#endif + #ifdef TARGET_NR_mknod static void print_mknod(const struct syscallname *name, diff --git a/linux-user/strace.list b/linux-user/strace.list index f6dd044..2c7ad2b 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -1486,7 +1486,7 @@ { TARGET_NR_sys_kexec_load, "sys_kexec_load" , NULL, NULL, NULL }, #endif #ifdef TARGET_NR_syslog -{ TARGET_NR_syslog, "syslog" , NULL, NULL, NULL }, +{ TARGET_NR_syslog, "syslog" , NULL, print_syslog, NULL }, #endif #ifdef TARGET_NR_sysmips { TARGET_NR_sysmips, "sysmips" , NULL, NULL, NULL }, diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 05b4c41..3396d4b 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -9339,14 +9339,52 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5); break; #endif - +#if defined(TARGET_NR_syslog) case TARGET_NR_syslog: - if (!(p = lock_user_string(arg2))) - goto efault; - ret = get_errno(sys_syslog((int)arg1, p, (int)arg3)); - unlock_user(p, arg2, 0); - break; + { + int len = arg2; + switch (arg1) { + case TARGET_SYSLOG_ACTION_CLOSE: /* Close log */ + case TARGET_SYSLOG_ACTION_OPEN: /* Open log */ + case TARGET_SYSLOG_ACTION_CLEAR: /* Clear ring buffer */ + case TARGET_SYSLOG_ACTION_CONSOLE_OFF: /* Disable logging */ + case TARGET_SYSLOG_ACTION_CONSOLE_ON: /* Enable logging */ + case TARGET_SYSLOG_ACTION_CONSOLE_LEVEL: /* Set messages level */ + case TARGET_SYSLOG_ACTION_SIZE_UNREAD: /* Number of chars */ + case TARGET_SYSLOG_ACTION_SIZE_BUFFER: /* Size of the buffer */ + { + ret = get_errno(sys_syslog((int)arg1, NULL, (int)arg3)); + } + break; + case TARGET_SYSLOG_ACTION_READ: /* Read from log */ + case TARGET_SYSLOG_ACTION_READ_CLEAR: /* Read/clear msgs */ + case TARGET_SYSLOG_ACTION_READ_ALL: /* Read last messages */ + { + ret = -TARGET_EINVAL; + if (len < 0) { + goto fail; + } + ret = 0; + if (len == 0) { + break; + } + p = lock_user(VERIFY_WRITE, arg2, arg3, 0); + if (!p) { + ret = -TARGET_EFAULT; + goto fail; + } + ret = get_errno(sys_syslog((int)arg1, p, (int)arg3)); + unlock_user(p, arg2, arg3); + } + break; + default: + ret = -EINVAL; + break; + } + } + break; +#endif case TARGET_NR_setitimer: { struct itimerval value, ovalue, *pvalue; diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index adb7153..61270ef 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -2688,4 +2688,29 @@ struct target_user_cap_data { uint32_t inheritable; }; +/* from kernel's include/linux/syslog.h */ + +/* Close the log. Currently a NOP. */ +#define TARGET_SYSLOG_ACTION_CLOSE 0 +/* Open the log. Currently a NOP. */ +#define TARGET_SYSLOG_ACTION_OPEN 1 +/* Read from the log. */ +#define TARGET_SYSLOG_ACTION_READ 2 +/* Read all messages remaining in the ring buffer. */ +#define TARGET_SYSLOG_ACTION_READ_ALL 3 +/* Read and clear all messages remaining in the ring buffer */ +#define TARGET_SYSLOG_ACTION_READ_CLEAR 4 +/* Clear ring buffer. */ +#define TARGET_SYSLOG_ACTION_CLEAR 5 +/* Disable printk's to console */ +#define TARGET_SYSLOG_ACTION_CONSOLE_OFF 6 +/* Enable printk's to console */ +#define TARGET_SYSLOG_ACTION_CONSOLE_ON 7 +/* Set level of messages printed to console */ +#define TARGET_SYSLOG_ACTION_CONSOLE_LEVEL 8 +/* Return number of unread characters in the log buffer */ +#define TARGET_SYSLOG_ACTION_SIZE_UNREAD 9 +/* Return size of the log buffer */ +#define TARGET_SYSLOG_ACTION_SIZE_BUFFER 10 + #endif