From nobody Tue May 14 01:02:50 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) client-ip=170.10.133.124; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-124.mimecast.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1647445241; cv=none; d=zohomail.com; s=zohoarc; b=Hk/qtvmn5iQVXAuVdY2N7a96dLyymg9ls3DAe/LX0HVcbD6w6BqfLgL7FhMC6TPrkSlRSSodnTeSxAquouEPR0fxFCLFcV+ZjshCz0Jo3elxAC78czMpQsaEYX6BGyqLMEFf08CLZBOGM8wPxVcHus4/ifIMiYLdk1SSUpHXGLQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1647445241; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=H7ba0LR2fxkLtXx/64NRFPDaFB7oSD4tyuOM2PeEuWA=; b=cQ9w6MU5sQt5jhmUxwzKYSt+kQTfZUqwJAsI1G6Al6jn+rBV7d/3pPQRLXdMfoyCTGsww46WF4o6ZRfuQfFz3I+76rR7cEBQDttI6uUYwfn8pJeK93sSVhnz2SW8SWAkCncmFf6j86psA5sapXVb6GNR3/Dq/yut6p6NqNwtpY0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by mx.zohomail.com with SMTPS id 1647445240995712.5007483925453; Wed, 16 Mar 2022 08:40:40 -0700 (PDT) Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-588-69P2_f8JMlm3dGQh9VZ63w-1; Wed, 16 Mar 2022 11:40:34 -0400 Received: from smtp.corp.redhat.com (int-mx10.intmail.prod.int.rdu2.redhat.com [10.11.54.10]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id C3757804199; Wed, 16 Mar 2022 15:40:19 +0000 (UTC) Received: from mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com [10.30.29.100]) by smtp.corp.redhat.com (Postfix) with ESMTP id A715C401E7D; Wed, 16 Mar 2022 15:40:19 +0000 (UTC) Received: from mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (localhost [IPv6:::1]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id 6FB8B1949763; Wed, 16 Mar 2022 15:40:19 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.rdu2.redhat.com [10.11.54.2]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id B38CA1949761 for ; Wed, 16 Mar 2022 15:39:38 +0000 (UTC) Received: by smtp.corp.redhat.com (Postfix) id A600540E80E2; Wed, 16 Mar 2022 15:39:38 +0000 (UTC) Received: from maggie.redhat.com (unknown [10.43.2.152]) by smtp.corp.redhat.com (Postfix) with ESMTP id 4DB3540E80F0 for ; Wed, 16 Mar 2022 15:39:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1647445239; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=H7ba0LR2fxkLtXx/64NRFPDaFB7oSD4tyuOM2PeEuWA=; b=Xq2WaBg5bb4rlyoLnsmkAg0+6zMI/txtlNwZ0V6nIyt1/4JsBFeQPES3Xhov4uYa6u9kdB 39FRk/ClC2ljP+4zd6g1ueWEvo6Abkc1rosANXfjnJnGeA980deJwA6nJjriUOlabCmu+C vj/oBaF7azTbkeJxS9GYtREqBj9UWnE= X-MC-Unique: 69P2_f8JMlm3dGQh9VZ63w-1 X-Original-To: libvir-list@listman.corp.redhat.com From: Michal Privoznik To: libvir-list@redhat.com Subject: [PATCH 1/2] qemu_process: Be nicer to killing QEMU when probing caps Date: Wed, 16 Mar 2022 16:39:35 +0100 Message-Id: <554fc12ddca04ca694d72bbe95c42d534b7bc432.1647445043.git.mprivozn@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.11.54.2 X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libvir-list-bounces@redhat.com Sender: "libvir-list" X-Scanned-By: MIMEDefang 2.85 on 10.11.54.10 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=libvir-list-bounces@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1647445241463100001 Content-Type: text/plain; charset="utf-8" The qemuProcessQMPStop() function is intended to kill this dummy QEMU process we started only for querying capabilities. Nevertheless, it may be not plain QEMU binary we executed, but in fact it may be a memcheck tool (e.g. valgrind) that executes QEMU later. By switching to virProcessKillPainfully() we allow this wrapper tool to exit gracefully. Another up side is that virProcessKillPainfully() reports an error so no need for us to VIR_ERROR() ourselves. Signed-off-by: Michal Privoznik Reviewed-by: Martin Kletzander --- src/qemu/qemu_process.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index b19a6218d0..2e149699b0 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -9132,11 +9132,7 @@ qemuProcessQMPStop(qemuProcessQMP *proc) =20 if (proc->pid !=3D 0) { VIR_DEBUG("Killing QMP caps process %lld", (long long)proc->pid); - if (virProcessKill(proc->pid, SIGKILL) < 0 && errno !=3D ESRCH) - VIR_ERROR(_("Failed to kill process %lld: %s"), - (long long)proc->pid, - g_strerror(errno)); - + virProcessKillPainfully(proc->pid, true); proc->pid =3D 0; } =20 --=20 2.34.1 From nobody Tue May 14 01:02:50 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 170.10.129.124 as permitted sender) client-ip=170.10.129.124; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-124.mimecast.com; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of redhat.com designates 170.10.129.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1647445258; cv=none; d=zohomail.com; s=zohoarc; b=Tpcfr5nlW3CZKAhovUSJ4nx+t6v8obg5FP9bU8Ftc3Kn05CoQikfeQ17UjJ+c9qv9RPWFemWjiJpfRFgp8VxWhGA45bbZreRy3c8shEE3zf5eh9L0Mwzwl0HWKfpjlpqWSX+Uc/Lc/Yydq4+9PKCvnCoxuog0nAHGb6k8hmy7Bk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1647445258; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=xZv25Glf1HjnSI5HYxwgz0Bk/h64DCjQbFcqHzX9Ysk=; b=SC3GQPejFbGrJ4jKXPnusvES/jm2F7pnSOjnl+H0OrsNmO9GxASLV1KnaUouew2Zf/4YDuua1T1V/RNnAfA+Frhm8k1F3V3jdatLRKkrjwKckaW1tpdT/N7gbjb+HZ8Cv0MUJ8YZ1jPs3Jer3hicFe5UuSJz2sgBixZ6uaAr1+w= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of redhat.com designates 170.10.129.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by mx.zohomail.com with SMTPS id 1647445258635512.5721083964144; Wed, 16 Mar 2022 08:40:58 -0700 (PDT) Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-553-ObfVN67iOc--FvlLX-e1DQ-1; Wed, 16 Mar 2022 11:40:54 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 5104D188144E; Wed, 16 Mar 2022 15:40:28 +0000 (UTC) Received: from mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com [10.30.29.100]) by smtp.corp.redhat.com (Postfix) with ESMTP id 081AC2028CE7; Wed, 16 Mar 2022 15:40:28 +0000 (UTC) Received: from mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (localhost [IPv6:::1]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id C81BB1949763; Wed, 16 Mar 2022 15:40:27 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.rdu2.redhat.com [10.11.54.2]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id 55C6C1949761 for ; Wed, 16 Mar 2022 15:39:39 +0000 (UTC) Received: by smtp.corp.redhat.com (Postfix) id 42FD240E80E6; Wed, 16 Mar 2022 15:39:39 +0000 (UTC) Received: from maggie.redhat.com (unknown [10.43.2.152]) by smtp.corp.redhat.com (Postfix) with ESMTP id DEB6E40E80E5 for ; Wed, 16 Mar 2022 15:39:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1647445259; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=xZv25Glf1HjnSI5HYxwgz0Bk/h64DCjQbFcqHzX9Ysk=; b=ANUjvNjaj482X2mVh4piinLpws7X9OwiR1yJBwI3ihyrqRcPMGBsGvSMMsKy0b/AwIWXVo NNjqOQWOI1yxEFphJznM5y2r7JKVfBuT56/DTlFdDNGENl7/9rLh33qVGI+s+2XQ8i5oFj CTzwKOp0ccua/vvimQNPbNowgddybFk= X-MC-Unique: ObfVN67iOc--FvlLX-e1DQ-1 X-Original-To: libvir-list@listman.corp.redhat.com From: Michal Privoznik To: libvir-list@redhat.com Subject: [PATCH 2/2] qemu_process: Start QEMU for caps probing more robustly Date: Wed, 16 Mar 2022 16:39:36 +0100 Message-Id: In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.11.54.2 X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libvir-list-bounces@redhat.com Sender: "libvir-list" X-Scanned-By: MIMEDefang 2.78 on 10.11.54.4 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=libvir-list-bounces@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: fail (Signature date is -1 seconds in the future.) X-ZM-MESSAGEID: 1647445288389100001 Content-Type: text/plain; charset="utf-8" When probing QEMU capabilities, we look at whatever was specified in the domain XML and execute it with couple of arguments (-daemonize being one of them) Then, we use virCommandSetErrorBuffer() to read stderr of the child process hoping to read possible error message just before the process daemonized itself. Well, this works as long as the emulator binary behaves. If the binary is evil and basically does the following: #!/bin/bash sleep 1h then virCommandRun() called from qemuProcessQMPLaunch() doesn't return for whole hour (because it's stuck in reading stderr of the child process). This behavior of ours is very suboptimal. The solution is to not rely on the binary behaving correctly on -daemonize argument but to daemonize the process ourselves (via virCommandDaemonize()) and then wait for the monitor to show up with a timeout. This in turn means, that we can no longer use virCommandSetErrorBuffer() but we can do the equivalent with virCommandSetErrorFD() and a bit of code. Sure, this doesn't shield us from malicious binaries 100% but helps preventing depletion of worker threads. Signed-off-by: Michal Privoznik Reviewed-by: Martin Kletzander --- src/qemu/qemu_process.c | 58 +++++++++++++++++++++++++++++------------ src/qemu/qemu_process.h | 1 - 2 files changed, 42 insertions(+), 17 deletions(-) diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 2e149699b0..d038f7e2ae 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -9166,7 +9166,6 @@ qemuProcessQMPFree(qemuProcessQMP *proc) g_free(proc->monpath); g_free(proc->monarg); g_free(proc->pidfile); - g_free(proc->stdErr); g_free(proc); } =20 @@ -9285,7 +9284,9 @@ static int qemuProcessQMPLaunch(qemuProcessQMP *proc) { const char *machine; - int status =3D 0; + VIR_AUTOCLOSE errfd =3D -1; + virTimeBackOffVar timebackoff; + const unsigned long long timeout =3D 30 * 1000; /* ms */ int rc; =20 if (proc->forceTCG) @@ -9310,9 +9311,7 @@ qemuProcessQMPLaunch(qemuProcessQMP *proc) "-nographic", "-machine", machine, "-qmp", proc->monarg, - "-pidfile", proc->pidfile, - "-daemonize", - NULL); + NULL); virCommandAddEnvPassCommon(proc->cmd); virCommandClearCaps(proc->cmd); =20 @@ -9326,26 +9325,53 @@ qemuProcessQMPLaunch(qemuProcessQMP *proc) virCommandSetGID(proc->cmd, proc->runGid); virCommandSetUID(proc->cmd, proc->runUid); =20 - virCommandSetErrorBuffer(proc->cmd, &(proc->stdErr)); + virCommandSetPidFile(proc->cmd, proc->pidfile); + virCommandSetErrorFD(proc->cmd, &errfd); + virCommandDaemonize(proc->cmd); =20 - if (virCommandRun(proc->cmd, &status) < 0) + if (virCommandRun(proc->cmd, NULL) < 0) return -1; =20 - if (status !=3D 0) { - VIR_DEBUG("QEMU %s exited with status %d", proc->binary, status); - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Failed to start QEMU binary %s for probing: %s"), - proc->binary, - proc->stdErr ? proc->stdErr : _("unknown error")); - return -1; - } - if ((rc =3D virPidFileReadPath(proc->pidfile, &proc->pid)) < 0) { virReportSystemError(-rc, _("Failed to read pidfile %s"), proc->pi= dfile); return -1; } =20 + if (virTimeBackOffStart(&timebackoff, 1, timeout) < 0) + goto error; + while (virTimeBackOffWait(&timebackoff)) { + char errbuf[1024] =3D { 0 }; + + if (virFileExists(proc->monpath)) + break; + + if (virProcessKill(proc->pid, 0) =3D=3D 0) + continue; + + ignore_value(saferead(errfd, errbuf, sizeof(errbuf) - 1)); + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Failed to start QEMU binary %s for probing: %s"), + proc->binary, + errbuf[0] ? errbuf : _("unknown error")); + goto error; + } + + if (!virFileExists(proc->monpath)) { + virReportError(VIR_ERR_OPERATION_TIMEOUT, "%s", + _("QEMU monitor did not show up")); + goto error; + } + return 0; + + error: + virCommandAbort(proc->cmd); + if (proc->pid >=3D 0) + virProcessKillPainfully(proc->pid, true); + if (proc->pidfile) + unlink(proc->pidfile); + + return -1; } =20 =20 diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h index 289cd74eb7..f73722846b 100644 --- a/src/qemu/qemu_process.h +++ b/src/qemu/qemu_process.h @@ -221,7 +221,6 @@ struct _qemuProcessQMP { char *libDir; uid_t runUid; gid_t runGid; - char *stdErr; char *monarg; char *monpath; char *pidfile; --=20 2.34.1