From patchwork Thu Feb 13 12:21:08 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Laurent Vivier X-Patchwork-Id: 1237451 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=vivier.eu Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48JFz02H9cz9sNg for ; Thu, 13 Feb 2020 23:23:08 +1100 (AEDT) Received: from localhost ([::1]:51338 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j2DWM-0008Jp-8L for incoming@patchwork.ozlabs.org; Thu, 13 Feb 2020 07:23:06 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:39198) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j2DUm-0006e5-09 for qemu-devel@nongnu.org; Thu, 13 Feb 2020 07:21:29 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1j2DUk-0003RQ-OO for qemu-devel@nongnu.org; Thu, 13 Feb 2020 07:21:27 -0500 Received: from mout.kundenserver.de ([212.227.126.134]:33905) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1j2DUk-0003Pr-FJ for qemu-devel@nongnu.org; Thu, 13 Feb 2020 07:21:26 -0500 Received: from localhost.localdomain ([78.238.229.36]) by mrelayeu.kundenserver.de (mreue009 [212.227.15.167]) with ESMTPSA (Nemesis) id 1MmDAW-1jkJjd48RM-00iDZO; Thu, 13 Feb 2020 13:21:14 +0100 From: Laurent Vivier To: qemu-devel@nongnu.org Subject: [PULL 5/5] linux-user: implement TARGET_SO_PEERSEC Date: Thu, 13 Feb 2020 13:21:08 +0100 Message-Id: <20200213122108.965455-6-laurent@vivier.eu> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200213122108.965455-1-laurent@vivier.eu> References: <20200213122108.965455-1-laurent@vivier.eu> MIME-Version: 1.0 X-Provags-ID: V03:K1:pXdY38UTIdcbZNZR88eBsXzg58bbI5HYUMzcwVSUd7ASq4azCuG 7wK2FkvwqbCTlVA9qTPcECDpFoCm0aJoCbWlClrGq8sHilrsnESxZhN19va4WrS0bNVK9Yc Vpu7fqpqH24Lrbc2q79+ryU1XGo01pcd0whueVtTmxCpypu9gC4gUb9SDXQI5jaa7xcmRRr bZT8xaLjAsPeoLiGgOC3A== X-UI-Out-Filterresults: notjunk:1; V03:K0:iJgSuFHQbf4=:DMRKxnf85KIDcqlFlFkITr QA1q4lwoHgzvyGfBUi223bRs4815vC61J9qJLRz/1i7ZXozixt0RkGBOzO8lX/OaRHZB7ZJAk YXugjmH1f5o5bheLdxlGwHeqnbVXVRO2Tge3tA+UqSrdzJkpwqFrj3nZuDKutaps0OOXawcE/ 4hUZQO2kfh+coH10nQJZMMPZajIfBF02mJWpJQ8eVd56fcvhkoCf2RTHiSpZA7o6ZsZIPw83T r++h228FCAzLVrDDSDe/1Ttg6Hpxgqm/sEmqJWgDlFVIz0dEbT5BO/rIT2ZEpZM/j7Tx9Rkyd ZZzpfd9DdataEjFFh62WOkfri8GKmqeECvGvBPWvTnQ+ZNws1u1k5O77khJYRkK8+EMkWB5m3 4pXqnqhdIXiqUUvjYijKKCbFbZGn4yOHVc7vMSp1/JjH7la+ZvXzPe0lijC3QKvSfJP6SrtO0 5A+H4yy9KyjNV58T+vdU/kJcMVVKA6JXObSXhz08hx83ujDGuFLC3cNvdOU0mloOc+GO9KOQG Vs3PeCrjfX63pBXDrluWfBWrT82qW21NWDjfl45zT8hovKkraK7uRNRO2lrtB4zlGB4Rv9RaG IPWhdYqbNUsrXZ1tpexwbGgAC3eDpncCEB9pB5Taa+yvKVCY63x6Rtgp/LFvyXKf2tkd77g6p ncto1TkSpHp6/g+C4R5rzAEf4viwnZ19urwA8iOBMUpiV7AftkEYDAXRS8QYZV7XGRv9h140E AahogyMdl+Qv+i+55TQqvW/z0kV7pStvElnRho4HR/XGsSvi0QK+mFWxlkSFGoh+GzvsCI7/G JDTyG829HYGDU3XsWqeSUYYdSuH+NKQARdIBmByYXGZhXB5KDjjy955yV/nZGe/x5RfGJr5 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 212.227.126.134 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Riku Voipio , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?b?w6k=?= , Laurent Vivier , =?utf-8?q?Matthias_L=C3=BCscher?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" "The purpose of this option is to allow an application to obtain the security credentials of a Unix stream socket peer. It is analogous to SO_PEERCRED (which provides authentication using standard Unix credentials of pid, uid and gid), and extends this concept to other security models." -- https://lwn.net/Articles/62370/ Until now it was passed to the kernel with an "int" argument and fails when it was supported by the host because the parameter is like a filename: it is always a \0-terminated string with no embedded \0 characters, but is not guaranteed to be ASCII or UTF-8. I've tested the option with the following program: /* * cc -o getpeercon getpeercon.c */ #include #include #include #include #include int main(void) { int fd; struct sockaddr_in server, addr; int ret; socklen_t len; char buf[256]; fd = socket(PF_INET, SOCK_STREAM, 0); if (fd == -1) { perror("socket"); return 1; } server.sin_family = AF_INET; inet_aton("127.0.0.1", &server.sin_addr); server.sin_port = htons(40390); connect(fd, (struct sockaddr*)&server, sizeof(server)); len = sizeof(buf); ret = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, buf, &len); if (ret == -1) { perror("getsockopt"); return 1; } printf("%d %s\n", len, buf); return 0; } On host: $ ./getpeercon 33 system_u:object_r:unlabeled_t:s0 With qemu-aarch64/bionic without the patch: $ ./getpeercon getsockopt: Numerical result out of range With the patch: $ ./getpeercon 33 system_u:object_r:unlabeled_t:s0 Bug: https://bugs.launchpad.net/qemu/+bug/1823790 Reported-by: Matthias Lüscher Tested-by: Matthias Lüscher Signed-off-by: Laurent Vivier Reviewed-by: Philippe Mathieu-Daudé Tested-by: Philippe Mathieu-Daudé Message-Id: <20200204211901.1731821-1-laurent@vivier.eu> --- linux-user/syscall.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index d60142f0691c..c930577686da 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -2344,6 +2344,28 @@ static abi_long do_getsockopt(int sockfd, int level, int optname, } break; } + case TARGET_SO_PEERSEC: { + char *name; + + if (get_user_u32(len, optlen)) { + return -TARGET_EFAULT; + } + if (len < 0) { + return -TARGET_EINVAL; + } + name = lock_user(VERIFY_WRITE, optval_addr, len, 0); + if (!name) { + return -TARGET_EFAULT; + } + lv = len; + ret = get_errno(getsockopt(sockfd, level, SO_PEERSEC, + name, &lv)); + if (put_user_u32(lv, optlen)) { + ret = -TARGET_EFAULT; + } + unlock_user(name, optval_addr, lv); + break; + } case TARGET_SO_LINGER: { struct linger lg;