From nobody Mon Feb 9 00:02:17 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1615487857; cv=none; d=zohomail.com; s=zohoarc; b=ZpxxhmfeGncgekAD+ReS7AtpHu1CLOw6u+3Rd3qrbpJek+9hi360PR8+yj1yf+I1HbCuqUAgRZSYtkQW59cupcUumeOzT76DGdIVjZGp2d9QQm8Ar3LnJ+gSysxj8aVbFTytXX0dmpuUDovSl/Sqh/zXqFqWdI6DlEBKMKPMKgU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1615487857; h=Content-Type:Content-Transfer-Encoding:Cc: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=V0zQ9CvOjvz7updepouModGhp7K4FDxVYQ1m23aXDHk=; b=Wilaje7FcppxElxF/WfA4mNlxTDdMrbR7t6LdSvsGZsH12b4KLvdzfEGJAgtcJqJ8a6yIdPunSFJas7a8W9RuHCUtwKRBHlZ75OGzM5J4/pbqDR8hNv08IW0VC1bL8u6KYia+Qukt92czdFutGOj9zHaIFzrVehvKwS4RzqBheU= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 16154878576771013.0227664586648; Thu, 11 Mar 2021 10:37:37 -0800 (PST) Received: from localhost ([::1]:51638 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lKQBj-0007Gl-S0 for importer@patchew.org; Thu, 11 Mar 2021 13:37:35 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:55722) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lKQ4g-0001ih-KV for qemu-devel@nongnu.org; Thu, 11 Mar 2021 13:30:19 -0500 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:20052) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1lKQ4b-0004Zn-NE for qemu-devel@nongnu.org; Thu, 11 Mar 2021 13:30:18 -0500 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-7-c5OT4IerMdKU8vj6VlMF2Q-1; Thu, 11 Mar 2021 13:30:11 -0500 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 2CC8110866A0 for ; Thu, 11 Mar 2021 18:30:10 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-115-85.ams2.redhat.com [10.36.115.85]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1D01318A9E; Thu, 11 Mar 2021 18:30:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1615487413; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=V0zQ9CvOjvz7updepouModGhp7K4FDxVYQ1m23aXDHk=; b=Uno3K8bhxD1pDfRgFwoO/YXy6sef39X5QyiPIfaEe6KQJFacOv03jXFAWXVr9Tpy/e++H4 /nlJe02zYuVZDochvgg9Xecnh9ZEkoutZHNuv0kRIG4btcgHJof9BuZ3gkOKQptILTG1Iz Bi/Ve/7N6IGNRKtCemo1s1tv7Xca2iI= X-MC-Unique: c5OT4IerMdKU8vj6VlMF2Q-1 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: qemu-devel@nongnu.org Subject: [PATCH 2/4] ui: avoid sending framebuffer updates outside client desktop bounds Date: Thu, 11 Mar 2021 18:29:55 +0000 Message-Id: <20210311182957.486939-3-berrange@redhat.com> In-Reply-To: <20210311182957.486939-1-berrange@redhat.com> References: <20210311182957.486939-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=berrange@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=216.205.24.124; envelope-from=berrange@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -29 X-Spam_score: -3.0 X-Spam_bar: --- X-Spam_report: (-3.0 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.25, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action 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: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= , Gerd Hoffmann Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) We plan framebuffer update rects based on the VNC server surface. If the client doesn't support desktop resize, then the client bounds may differ from the server surface bounds. VNC clients may become upset if we then send an update message outside the bounds of the client desktop. This takes the approach of clamping the rectangles from the worker thread immediately before sending them. This may sometimes results in sending a framebuffer update message with zero rectangles. Signed-off-by: Daniel P. Berrang=C3=A9 Reviewed-by: Marc-Andr=C3=A9 Lureau --- ui/trace-events | 5 +++++ ui/vnc-jobs.c | 44 ++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/ui/trace-events b/ui/trace-events index bd8f8a9d18..3838ae2d84 100644 --- a/ui/trace-events +++ b/ui/trace-events @@ -59,6 +59,11 @@ vnc_client_throttle_audio(void *state, void *ioc, size_t= offset) "VNC client thr vnc_client_unthrottle_forced(void *state, void *ioc) "VNC client unthrottl= e forced offset state=3D%p ioc=3D%p" vnc_client_unthrottle_incremental(void *state, void *ioc, size_t offset) "= VNC client unthrottle incremental state=3D%p ioc=3D%p offset=3D%zu" vnc_client_output_limit(void *state, void *ioc, size_t offset, size_t thre= shold) "VNC client output limit state=3D%p ioc=3D%p offset=3D%zu threshold= =3D%zu" +vnc_job_add_rect(void *state, void *job, int x, int y, int w, int h) "VNC = add rect state=3D%p job=3D%p offset=3D%d,%d size=3D%dx%d" +vnc_job_discard_rect(void *state, void *job, int x, int y, int w, int h) "= VNC job discard rect state=3D%p job=3D%p offset=3D%d,%d size=3D%dx%d" +vnc_job_clamp_rect(void *state, void *job, int x, int y, int w, int h) "VN= C job clamp rect state=3D%p job=3D%p offset=3D%d,%d size=3D%dx%d" +vnc_job_clamped_rect(void *state, void *job, int x, int y, int w, int h) "= VNC job clamp rect state=3D%p job=3D%p offset=3D%d,%d size=3D%dx%d" +vnc_job_nrects(void *state, void *job, int nrects) "VNC job state=3D%p job= =3D%p nrects=3D%d" vnc_auth_init(void *display, int websock, int auth, int subauth) "VNC auth= init state=3D%p websock=3D%d auth=3D%d subauth=3D%d" vnc_auth_start(void *state, int method) "VNC client auth start state=3D%p = method=3D%d" vnc_auth_pass(void *state, int method) "VNC client auth passed state=3D%p = method=3D%d" diff --git a/ui/vnc-jobs.c b/ui/vnc-jobs.c index dbbfbefe56..4562bf8928 100644 --- a/ui/vnc-jobs.c +++ b/ui/vnc-jobs.c @@ -32,6 +32,7 @@ #include "qemu/sockets.h" #include "qemu/main-loop.h" #include "block/aio.h" +#include "trace.h" =20 /* * Locking: @@ -94,6 +95,8 @@ int vnc_job_add_rect(VncJob *job, int x, int y, int w, in= t h) { VncRectEntry *entry =3D g_new0(VncRectEntry, 1); =20 + trace_vnc_job_add_rect(job->vs, job, x, y, w, h); + entry->rect.x =3D x; entry->rect.y =3D y; entry->rect.w =3D w; @@ -190,6 +193,8 @@ static void vnc_async_encoding_start(VncState *orig, Vn= cState *local) local->zlib =3D orig->zlib; local->hextile =3D orig->hextile; local->zrle =3D orig->zrle; + local->client_width =3D orig->client_width; + local->client_height =3D orig->client_height; } =20 static void vnc_async_encoding_end(VncState *orig, VncState *local) @@ -202,6 +207,34 @@ static void vnc_async_encoding_end(VncState *orig, Vnc= State *local) orig->lossy_rect =3D local->lossy_rect; } =20 +static bool vnc_worker_clamp_rect(VncState *vs, VncJob *job, VncRect *rect) +{ + trace_vnc_job_clamp_rect(vs, job, rect->x, rect->y, rect->w, rect->h); + + if (rect->x >=3D vs->client_width) { + goto discard; + } + rect->w =3D MIN(vs->client_width - rect->x, rect->w); + if (rect->w =3D=3D 0) { + goto discard; + } + + if (rect->y >=3D vs->client_height) { + goto discard; + } + rect->h =3D MIN(vs->client_height - rect->y, rect->h); + if (rect->h =3D=3D 0) { + goto discard; + } + + trace_vnc_job_clamped_rect(vs, job, rect->x, rect->y, rect->w, rect->h= ); + return true; + + discard: + trace_vnc_job_discard_rect(vs, job, rect->x, rect->y, rect->w, rect->h= ); + return false; +} + static int vnc_worker_thread_loop(VncJobQueue *queue) { VncJob *job; @@ -260,14 +293,17 @@ static int vnc_worker_thread_loop(VncJobQueue *queue) goto disconnected; } =20 - n =3D vnc_send_framebuffer_update(&vs, entry->rect.x, entry->rect.= y, - entry->rect.w, entry->rect.h); + if (vnc_worker_clamp_rect(&vs, job, &entry->rect)) { + n =3D vnc_send_framebuffer_update(&vs, entry->rect.x, entry->r= ect.y, + entry->rect.w, entry->rect.h); =20 - if (n >=3D 0) { - n_rectangles +=3D n; + if (n >=3D 0) { + n_rectangles +=3D n; + } } g_free(entry); } + trace_vnc_job_nrects(&vs, job, n_rectangles); vnc_unlock_display(job->vs->vd); =20 /* Put n_rectangles at the beginning of the message */ --=20 2.29.2