From 28f8eb4141847a095067d90a862250b8572372e9 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: May 09 2023 05:27:39 +0000 Subject: import tigervnc-1.12.0-13.el9_2 --- diff --git a/SOURCES/tigervnc-add-new-keycodes-for-unknown-keysyms.patch b/SOURCES/tigervnc-add-new-keycodes-for-unknown-keysyms.patch new file mode 100644 index 0000000..d4fd2b3 --- /dev/null +++ b/SOURCES/tigervnc-add-new-keycodes-for-unknown-keysyms.patch @@ -0,0 +1,199 @@ +From ccbd491fa48f1c43daeb1a6c5ee91a1a8fa3db88 Mon Sep 17 00:00:00 2001 +From: Jan Grulich +Date: Tue, 9 Aug 2022 14:31:07 +0200 +Subject: [PATCH] x0vncserver: add new keysym in case we don't find a matching + keycode + +We might often fail to find a matching X11 keycode when the client has +a different keyboard layout and end up with no key event. To avoid a +failure we add it as a new keysym/keycode pair so the next time a keysym +from the client that is unknown to the server is send, we will find a +match and proceed with key event. This is same behavior used in Xvnc or +x11vnc, although Xvnc has more advanced mapping from keysym to keycode. +--- + unix/x0vncserver/XDesktop.cxx | 121 +++++++++++++++++++++++++++++++++- + unix/x0vncserver/XDesktop.h | 4 ++ + 2 files changed, 122 insertions(+), 3 deletions(-) + +diff --git a/unix/x0vncserver/XDesktop.cxx b/unix/x0vncserver/XDesktop.cxx +index f2046e43e..933998f05 100644 +--- a/unix/x0vncserver/XDesktop.cxx ++++ b/unix/x0vncserver/XDesktop.cxx +@@ -31,6 +31,7 @@ + #include + + #include ++#include + #ifdef HAVE_XTEST + #include + #endif +@@ -50,6 +51,7 @@ void vncSetGlueContext(Display *dpy, void *res); + #include + #include + ++using namespace std; + using namespace rfb; + + extern const unsigned short code_map_qnum_to_xorgevdev[]; +@@ -264,6 +266,9 @@ void XDesktop::start(VNCServer* vs) { + void XDesktop::stop() { + running = false; + ++ // Delete added keycodes ++ deleteAddedKeysyms(dpy); ++ + #ifdef HAVE_XDAMAGE + if (haveDamage) + XDamageDestroy(dpy, damage); +@@ -383,6 +388,118 @@ KeyCode XDesktop::XkbKeysymToKeycode(Display* dpy, KeySym keysym) { + } + #endif + ++KeyCode XDesktop::addKeysym(Display* dpy, KeySym keysym) ++{ ++ int types[1]; ++ unsigned int key; ++ XkbDescPtr xkb; ++ XkbMapChangesRec changes; ++ KeySym *syms; ++ KeySym upper, lower; ++ ++ xkb = XkbGetMap(dpy, XkbAllComponentsMask, XkbUseCoreKbd); ++ ++ if (!xkb) ++ return 0; ++ ++ for (key = xkb->max_key_code; key >= xkb->min_key_code; key--) { ++ if (XkbKeyNumGroups(xkb, key) == 0) ++ break; ++ } ++ ++ if (key < xkb->min_key_code) ++ return 0; ++ ++ memset(&changes, 0, sizeof(changes)); ++ ++ XConvertCase(keysym, &lower, &upper); ++ ++ if (upper == lower) ++ types[XkbGroup1Index] = XkbOneLevelIndex; ++ else ++ types[XkbGroup1Index] = XkbAlphabeticIndex; ++ ++ XkbChangeTypesOfKey(xkb, key, 1, XkbGroup1Mask, types, &changes); ++ ++ syms = XkbKeySymsPtr(xkb,key); ++ if (upper == lower) ++ syms[0] = keysym; ++ else { ++ syms[0] = lower; ++ syms[1] = upper; ++ } ++ ++ changes.changed |= XkbKeySymsMask; ++ changes.first_key_sym = key; ++ changes.num_key_syms = 1; ++ ++ if (XkbChangeMap(dpy, xkb, &changes)) { ++ vlog.info("Added unknown keysym %s to keycode %d", XKeysymToString(keysym), key); ++ addedKeysyms[keysym] = key; ++ return key; ++ } ++ ++ return 0; ++} ++ ++void XDesktop::deleteAddedKeysyms(Display* dpy) { ++ XkbDescPtr xkb; ++ xkb = XkbGetMap(dpy, XkbAllComponentsMask, XkbUseCoreKbd); ++ ++ if (!xkb) ++ return; ++ ++ XkbMapChangesRec changes; ++ memset(&changes, 0, sizeof(changes)); ++ ++ KeyCode lowestKeyCode = xkb->max_key_code; ++ KeyCode highestKeyCode = xkb->min_key_code; ++ std::map::iterator it; ++ for (it = addedKeysyms.begin(); it != addedKeysyms.end(); it++) { ++ if (XkbKeyNumGroups(xkb, it->second) != 0) { ++ // Check if we are removing keysym we added ourself ++ if (XkbKeysymToKeycode(dpy, it->first) != it->second) ++ continue; ++ ++ XkbChangeTypesOfKey(xkb, it->second, 0, XkbGroup1Mask, NULL, &changes); ++ ++ if (it->second < lowestKeyCode) ++ lowestKeyCode = it->second; ++ ++ if (it->second > highestKeyCode) ++ highestKeyCode = it->second; ++ } ++ } ++ ++ changes.changed |= XkbKeySymsMask; ++ changes.first_key_sym = lowestKeyCode; ++ changes.num_key_syms = highestKeyCode - lowestKeyCode + 1; ++ XkbChangeMap(dpy, xkb, &changes); ++ ++ addedKeysyms.clear(); ++} ++ ++KeyCode XDesktop::keysymToKeycode(Display* dpy, KeySym keysym) { ++ int keycode = 0; ++ ++ // XKeysymToKeycode() doesn't respect state, so we have to use ++ // something slightly more complex ++ keycode = XkbKeysymToKeycode(dpy, keysym); ++ ++ if (keycode != 0) ++ return keycode; ++ ++ // TODO: try to further guess keycode with all possible mods as Xvnc does ++ ++ keycode = addKeysym(dpy, keysym); ++ ++ if (keycode == 0) ++ vlog.error("Failure adding new keysym 0x%lx", keysym); ++ ++ return keycode; ++} ++ ++ + void XDesktop::keyEvent(rdr::U32 keysym, rdr::U32 xtcode, bool down) { + #ifdef HAVE_XTEST + int keycode = 0; +@@ -398,9 +515,7 @@ void XDesktop::keyEvent(rdr::U32 keysym, rdr::U32 xtcode, bool down) { + if (pressedKeys.find(keysym) != pressedKeys.end()) + keycode = pressedKeys[keysym]; + else { +- // XKeysymToKeycode() doesn't respect state, so we have to use +- // something slightly more complex +- keycode = XkbKeysymToKeycode(dpy, keysym); ++ keycode = keysymToKeycode(dpy, keysym); + } + } + +diff --git a/unix/x0vncserver/XDesktop.h b/unix/x0vncserver/XDesktop.h +index 840d43316..6ebcd9f8a 100644 +--- a/unix/x0vncserver/XDesktop.h ++++ b/unix/x0vncserver/XDesktop.h +@@ -55,6 +55,9 @@ class XDesktop : public rfb::SDesktop, + const char* userName); + virtual void pointerEvent(const rfb::Point& pos, int buttonMask); + KeyCode XkbKeysymToKeycode(Display* dpy, KeySym keysym); ++ KeyCode addKeysym(Display* dpy, KeySym keysym); ++ void deleteAddedKeysyms(Display* dpy); ++ KeyCode keysymToKeycode(Display* dpy, KeySym keysym); + virtual void keyEvent(rdr::U32 keysym, rdr::U32 xtcode, bool down); + virtual void clientCutText(const char* str); + virtual unsigned int setScreenLayout(int fb_width, int fb_height, +@@ -78,6 +81,7 @@ class XDesktop : public rfb::SDesktop, + bool haveXtest; + bool haveDamage; + int maxButtons; ++ std::map addedKeysyms; + std::map pressedKeys; + bool running; + #ifdef HAVE_XDAMAGE diff --git a/SOURCES/tigervnc-fix-ghost-cursor-in-zaphod-mode.patch b/SOURCES/tigervnc-fix-ghost-cursor-in-zaphod-mode.patch new file mode 100644 index 0000000..8e45eb6 --- /dev/null +++ b/SOURCES/tigervnc-fix-ghost-cursor-in-zaphod-mode.patch @@ -0,0 +1,117 @@ +From f783d5c8b567199178b6690f347e060a69d2aa36 Mon Sep 17 00:00:00 2001 +From: Jan Grulich +Date: Thu, 11 Aug 2022 13:15:29 +0200 +Subject: [PATCH] x0vncserver: update/display cursor only on correct screen in + zaphod mode + +We have to check whether we update cursor position/shape only in case +the cursor is on our display, otherwise in zaphod mode, ie. when having +two instances of x0vncserver on screens :0.0 and :0.1 we would be having +the cursor duplicated and actually not funcional (aka ghost cursor) as +it would be actually not present. We also additionally watch EnterNotify +and LeaveNotify events in order to show/hide cursor accordingly. + +Change made with help from Olivier Fourdan +--- + unix/x0vncserver/XDesktop.cxx | 60 +++++++++++++++++++++++++++++++---- + 1 file changed, 53 insertions(+), 7 deletions(-) + +diff --git a/unix/x0vncserver/XDesktop.cxx b/unix/x0vncserver/XDesktop.cxx +index f2046e43e..f07fd78bf 100644 +--- a/unix/x0vncserver/XDesktop.cxx ++++ b/unix/x0vncserver/XDesktop.cxx +@@ -192,7 +192,8 @@ XDesktop::XDesktop(Display* dpy_, Geometry *geometry_) + RRScreenChangeNotifyMask | RRCrtcChangeNotifyMask); + /* Override TXWindow::init input mask */ + XSelectInput(dpy, DefaultRootWindow(dpy), +- PropertyChangeMask | StructureNotifyMask | ExposureMask); ++ PropertyChangeMask | StructureNotifyMask | ++ ExposureMask | EnterWindowMask | LeaveWindowMask); + } else { + #endif + vlog.info("RANDR extension not present"); +@@ -217,11 +218,13 @@ void XDesktop::poll() { + Window root, child; + int x, y, wx, wy; + unsigned int mask; +- XQueryPointer(dpy, DefaultRootWindow(dpy), &root, &child, +- &x, &y, &wx, &wy, &mask); +- x -= geometry->offsetLeft(); +- y -= geometry->offsetTop(); +- server->setCursorPos(rfb::Point(x, y), false); ++ ++ if (XQueryPointer(dpy, DefaultRootWindow(dpy), &root, &child, ++ &x, &y, &wx, &wy, &mask)) { ++ x -= geometry->offsetLeft(); ++ y -= geometry->offsetTop(); ++ server->setCursorPos(rfb::Point(x, y), false); ++ } + } + } + +@@ -253,7 +256,14 @@ void XDesktop::start(VNCServer* vs) { + #endif + + #ifdef HAVE_XFIXES +- setCursor(); ++ Window root, child; ++ int x, y, wx, wy; ++ unsigned int mask; ++ // Check whether the cursor is initially on our screen ++ if (XQueryPointer(dpy, DefaultRootWindow(dpy), &root, &child, ++ &x, &y, &wx, &wy, &mask)) ++ setCursor(); ++ + #endif + + server->setLEDState(ledState); +@@ -701,6 +711,15 @@ bool XDesktop::handleGlobalEvent(XEvent* ev) { + if (cev->subtype != XFixesDisplayCursorNotify) + return false; + ++ Window root, child; ++ int x, y, wx, wy; ++ unsigned int mask; ++ ++ // Check whether the cursor is initially on our screen ++ if (!XQueryPointer(dpy, DefaultRootWindow(dpy), &root, &child, ++ &x, &y, &wx, &wy, &mask)) ++ return false; ++ + return setCursor(); + #endif + #ifdef HAVE_XRANDR +@@ -753,6 +772,33 @@ bool XDesktop::handleGlobalEvent(XEvent* ev) { + + return true; + #endif ++#ifdef HAVE_XFIXES ++ } else if (ev->type == EnterNotify) { ++ XCrossingEvent* cev; ++ ++ if (!running) ++ return true; ++ ++ cev = (XCrossingEvent*)ev; ++ ++ if (cev->window != cev->root) ++ return false; ++ ++ return setCursor(); ++ } else if (ev->type == LeaveNotify) { ++ XCrossingEvent* cev; ++ ++ if (!running) ++ return true; ++ ++ cev = (XCrossingEvent*)ev; ++ ++ if (cev->window == cev->root) ++ return false; ++ ++ server->setCursor(0, 0, Point(), NULL); ++ return true; ++#endif + } + + return false; diff --git a/SOURCES/tigervnc-sanity-check-when-cleaning-up-keymap-changes.patch b/SOURCES/tigervnc-sanity-check-when-cleaning-up-keymap-changes.patch new file mode 100644 index 0000000..012a741 --- /dev/null +++ b/SOURCES/tigervnc-sanity-check-when-cleaning-up-keymap-changes.patch @@ -0,0 +1,28 @@ +From 774c6bcf33b5c9b94c1ff12895775e77c555decc Mon Sep 17 00:00:00 2001 +From: Pierre Ossman +Date: Thu, 9 Feb 2023 11:30:37 +0100 +Subject: [PATCH] Sanity check when cleaning up keymap changes + +Make sure we don't send a bogus request to the X server in the (common) +case that we don't actually have anything to restore. + +(cherry picked from commit 1e3484f2017f038dd5149cd50741feaf39a680e4) +--- + unix/x0vncserver/XDesktop.cxx | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/unix/x0vncserver/XDesktop.cxx b/unix/x0vncserver/XDesktop.cxx +index d5c6b2db9..f9c810968 100644 +--- a/unix/x0vncserver/XDesktop.cxx ++++ b/unix/x0vncserver/XDesktop.cxx +@@ -481,6 +481,10 @@ void XDesktop::deleteAddedKeysyms(Display* dpy) { + } + } + ++ // Did we actually find something to remove? ++ if (highestKeyCode < lowestKeyCode) ++ return; ++ + changes.changed |= XkbKeySymsMask; + changes.first_key_sym = lowestKeyCode; + changes.num_key_syms = highestKeyCode - lowestKeyCode + 1; diff --git a/SOURCES/tigervnc-selinux-allow-vncsession-create-vnc-directory.patch b/SOURCES/tigervnc-selinux-allow-vncsession-create-vnc-directory.patch new file mode 100644 index 0000000..d6bc61b --- /dev/null +++ b/SOURCES/tigervnc-selinux-allow-vncsession-create-vnc-directory.patch @@ -0,0 +1,31 @@ +From 717d787de8f913070446444e37d552b51f05515e Mon Sep 17 00:00:00 2001 +From: Zdenek Pytela +Date: Mon, 16 Jan 2023 12:35:40 +0100 +Subject: [PATCH] SELinux: Allow vncsession create ~/.vnc directory + +Addresses the following AVC denial: + +type=PROCTITLE msg=audit(01/12/2023 02:58:12.648:696) : proctitle=/usr/sbin/vncsession fedora :1 +type=PATH msg=audit(01/12/2023 02:58:12.648:696) : item=1 name=/home/fedora/.vnc nametype=CREATE cap_fp=none cap_fi=none cap_fe=0 cap_fver=0 cap_frootid=0 +type=PATH msg=audit(01/12/2023 02:58:12.648:696) : item=0 name=/home/fedora/ inode=262145 dev=fc:02 mode=dir,700 ouid=fedora ogid=fedora rdev=00:00 obj=unconfined_u:object_r:user_home_dir_t:s0 nametype=PARENT cap_fp=none cap_fi=none cap_fe=0 cap_fver=0 cap_frootid=0 +type=CWD msg=audit(01/12/2023 02:58:12.648:696) : cwd=/home/fedora +type=SYSCALL msg=audit(01/12/2023 02:58:12.648:696) : arch=x86_64 syscall=mkdir success=no exit=EACCES(Permission denied) a0=0x7fff47d52540 a1=0755 a2=0x0 a3=0x0 items=2 ppid=2869 pid=2880 auid=fedora uid=fedora gid=fedora euid=fedora suid=fedora fsuid=fedora egid=fedora sgid=fedora fsgid=fedora tty=(none) ses=8 comm=vncsession exe=/usr/sbin/vncsession subj=system_u:system_r:vnc_session_t:s0 key=(null) +type=AVC msg=audit(01/12/2023 02:58:12.648:696) : avc: denied { create } for pid=2880 comm=vncsession name=.vnc scontext=system_u:system_r:vnc_session_t:s0 tcontext=system_u:object_r:vnc_home_t:s0 tclass=dir permissive=0 + +Resolves: rhbz#2143704 +--- + unix/vncserver/selinux/vncsession.te | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/unix/vncserver/selinux/vncsession.te b/unix/vncserver/selinux/vncsession.te +index fb966c14b..680be8ea1 100644 +--- a/unix/vncserver/selinux/vncsession.te ++++ b/unix/vncserver/selinux/vncsession.te +@@ -37,6 +37,7 @@ allow vnc_session_t self:fifo_file rw_fifo_file_perms; + allow vnc_session_t vnc_session_var_run_t:file manage_file_perms; + files_pid_filetrans(vnc_session_t, vnc_session_var_run_t, file) + ++create_dirs_pattern(vnc_session_t, vnc_home_t, vnc_home_t) + manage_files_pattern(vnc_session_t, vnc_home_t, vnc_home_t) + manage_fifo_files_pattern(vnc_session_t, vnc_home_t, vnc_home_t) + manage_sock_files_pattern(vnc_session_t, vnc_home_t, vnc_home_t) diff --git a/SOURCES/xorg-x11-server-Xi-fix-potential-use-after-free-in-DeepCopyPointerCl.patch b/SOURCES/xorg-x11-server-Xi-fix-potential-use-after-free-in-DeepCopyPointerCl.patch deleted file mode 100644 index 2389895..0000000 --- a/SOURCES/xorg-x11-server-Xi-fix-potential-use-after-free-in-DeepCopyPointerCl.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 7150ba655c0cc08fa6ded309b81265bb672f2869 Mon Sep 17 00:00:00 2001 -From: Peter Hutterer -Date: Wed, 25 Jan 2023 11:41:40 +1000 -Subject: [PATCH xserver] Xi: fix potential use-after-free in - DeepCopyPointerClasses - -CVE-2023-0494, ZDI-CAN 19596 - -This vulnerability was discovered by: -Jan-Niklas Sohn working with Trend Micro Zero Day Initiative - -Signed-off-by: Peter Hutterer ---- - Xi/exevents.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/Xi/exevents.c b/Xi/exevents.c -index 217baa9561..dcd4efb3bc 100644 ---- a/Xi/exevents.c -+++ b/Xi/exevents.c -@@ -619,8 +619,10 @@ DeepCopyPointerClasses(DeviceIntPtr from, DeviceIntPtr to) - memcpy(to->button->xkb_acts, from->button->xkb_acts, - sizeof(XkbAction)); - } -- else -+ else { - free(to->button->xkb_acts); -+ to->button->xkb_acts = NULL; -+ } - - memcpy(to->button->labels, from->button->labels, - from->button->numButtons * sizeof(Atom)); --- -2.39.0 - diff --git a/SPECS/tigervnc.spec b/SPECS/tigervnc.spec index 404338d..a7e86d3 100644 --- a/SPECS/tigervnc.spec +++ b/SPECS/tigervnc.spec @@ -5,7 +5,7 @@ Name: tigervnc Version: 1.12.0 -Release: 5%{?dist}.2 +Release: 13%{?dist} Summary: A TigerVNC remote display system %global _hardened_build 1 @@ -29,16 +29,20 @@ Patch50: tigervnc-selinux-restore-context-in-case-of-different-policies.p Patch51: tigervnc-fix-typo-in-mirror-monitor-detection.patch Patch52: tigervnc-root-user-selinux-context.patch Patch53: tigervnc-vncsession-restore-script-systemd-service.patch +# https://github.com/TigerVNC/tigervnc/pull/1513 +Patch54: tigervnc-fix-ghost-cursor-in-zaphod-mode.patch +# https://github.com/TigerVNC/tigervnc/pull/1510 +Patch55: tigervnc-add-new-keycodes-for-unknown-keysyms.patch +Patch56: tigervnc-sanity-check-when-cleaning-up-keymap-changes.patch +Patch57: tigervnc-selinux-allow-vncsession-create-vnc-directory.patch # This is tigervnc-%%{version}/unix/xserver116.patch rebased on the latest xorg Patch100: tigervnc-xserver120.patch # 1326867 - [RHEL7.3] GLX applications in an Xvnc session fails to start Patch101: 0001-rpath-hack.patch -# CVE-2023-0494 tigervnc: xorg-x11-server: DeepCopyPointerClasses use-after-free leads to privilege elevation -Patch110: xorg-x11-server-Xi-fix-potential-use-after-free-in-DeepCopyPointerCl.patch # CVE-2023-1393 tigervnc: xorg-x11-server: X.Org Server Overlay Window Use-After-Free Local Privilege Escalation Vulnerability -Patch111: xorg-x11-server-composite-Fix-use-after-free-of-the-COW.patch +Patch110: xorg-x11-server-composite-Fix-use-after-free-of-the-COW.patch BuildRequires: make BuildRequires: gcc-c++ @@ -163,8 +167,7 @@ for all in `find . -type f -perm -001`; do done %patch100 -p1 -b .xserver120-rebased %patch101 -p1 -b .rpath -%patch110 -p1 -b .Xi-fix-potential-use-after-free-in-DeepCopyPointerCl.patch -%patch111 -p1 -b .composite-Fix-use-after-free-of-the-COW +%patch110 -p1 -b .composite-Fix-use-after-free-of-the-COW popd %patch1 -p1 -b .use-gnome-as-default-session @@ -174,6 +177,10 @@ popd %patch51 -p1 -b .fix-typo-in-mirror-monitor-detection %patch52 -p1 -b .root-user-selinux-context %patch53 -p1 -b .vncsession-restore-script-systemd-service +%patch54 -p1 -b .fix-ghost-cursor-in-zaphod-mode +%patch55 -p1 -b .add-new-keycodes-for-unknown-keysyms +%patch56 -p1 -b .sanity-check-when-cleaning-up-keymap-changes +%patch57 -p1 -b .selinux-allow-vncsession-create-vnc-directory %build %ifarch sparcv9 sparc64 s390 s390x @@ -352,13 +359,46 @@ fi %ghost %verify(not md5 size mtime) %{_sharedstatedir}/selinux/%{selinuxtype}/active/modules/200/%{modulename} %changelog -*Mon Mar 27 2023 Jan Grulich - 1.12.0-5.2 +*Mon Mar 27 2023 Jan Grulich - 1.12.0-13 - xorg-x11-server: X.Org Server Overlay Window Use-After-Free Local Privilege Escalation Vulnerability - Resolves: bz#2180308 + Resolves: bz#2180309 -* Mon Feb 06 2023 Jan Grulich - 1.12.0-5 +* Tue Feb 21 2023 Jan Grulich - 1.12.0-12 +- SELinux: allow vncsession create .vnc directory + Resolves: bz#2164703 + +* Wed Feb 15 2023 Jan Grulich - 1.12.0-11 +- Add sanity check when cleaning up keymap changes + Resolves: bz#2169965 + +* Mon Feb 06 2023 Jan Grulich - 1.12.0-10 - xorg-x11-server: DeepCopyPointerClasses use-after-free leads to privilege elevation - Resolves: bz#2167060 + Resolves: bz#2167061 + +* Tue Dec 20 2022 Tomas Popela - 1.12.0-9 +- Rebuild for xorg-x11-server CVE-2022-46340 follow up fix + +* Fri Dec 16 2022 Jan Grulich - 1.12.0-8 +- Rebuild for xorg-x11-server CVEs + Resolves: CVE-2022-4283 (bz#2154234) + Resolves: CVE-2022-46340 (bz#2154221) + Resolves: CVE-2022-46341 (bz#2154224) + Resolves: CVE-2022-46342 (bz#2154226) + Resolves: CVE-2022-46343 (bz#2154228) + Resolves: CVE-2022-46344 (bz#2154230) + +* Thu Dec 01 2022 Jan Grulich - 1.12.0-7 +- x0vncserver: add new keysym in case we don't find matching keycode + + actually apply the patch + Resolves: bz#2119017 + +* Thu Dec 01 2022 Jan Grulich - 1.12.0-6 +- x0vncserver: add new keysym in case we don't find matching keycode + Resolves: bz#2119017 + +* Mon Oct 24 2022 Jan Grulich - 1.12.0-5 +- x0vncserver: fix ghost cursor in zaphod mode (better version) + Resolves: bz#2119016 * Tue May 31 2022 Jan Grulich - 1.12.0-4 - Add BR: libXdamage, libXfixes, libXrandr