diff --git a/SOURCES/tigervnc-root-user-selinux-context.patch b/SOURCES/tigervnc-root-user-selinux-context.patch
new file mode 100644
index 0000000..e396b99
--- /dev/null
+++ b/SOURCES/tigervnc-root-user-selinux-context.patch
@@ -0,0 +1,26 @@
+From faf81b4b238e24fe29eb53f885a25367e212dd7b Mon Sep 17 00:00:00 2001
+From: Zdenek Pytela <zpytela@redhat.com>
+Date: Mon, 7 Feb 2022 10:45:41 +0100
+Subject: [PATCH] SELinux: use /root/.vnc in file context specification
+
+Instead of HOME_ROOT/.vnc, /root/.vnc should be used
+for user root's home to specify default file context
+as HOME_ROOT actually means base for home dirs (usually /home).
+---
+ unix/vncserver/selinux/vncsession.fc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/unix/vncserver/selinux/vncsession.fc b/unix/vncserver/selinux/vncsession.fc
+index ae768ba..5c03e46 100644
+--- a/unix/vncserver/selinux/vncsession.fc
++++ b/unix/vncserver/selinux/vncsession.fc
+@@ -18,7 +18,7 @@
+ #
+
+ HOME_DIR/\.vnc(/.*)?      gen_context(system_u:object_r:xdm_home_t,s0)
+-HOME_ROOT/\.vnc(/.*)?      gen_context(system_u:object_r:xdm_home_t,s0)
++/root/\.vnc(/.*)?      gen_context(system_u:object_r:xdm_home_t,s0)
+
+ /usr/sbin/vncsession			--	gen_context(system_u:object_r:vnc_session_exec_t,s0)
+ /usr/libexec/vncsession-start		--	gen_context(system_u:object_r:vnc_session_exec_t,s0)
+
diff --git a/SOURCES/tigervnc-selinux-restore-context-in-case-of-different-policies.patch b/SOURCES/tigervnc-selinux-restore-context-in-case-of-different-policies.patch
new file mode 100644
index 0000000..f362522
--- /dev/null
+++ b/SOURCES/tigervnc-selinux-restore-context-in-case-of-different-policies.patch
@@ -0,0 +1,81 @@
+From d2d52704624ce841f4a392fccd82079d87ff13b6 Mon Sep 17 00:00:00 2001
+From: Jan Grulich <jgrulich@redhat.com>
+Date: Thu, 11 Nov 2021 13:52:41 +0100
+Subject: [PATCH] SELinux: restore SELinux context in case of different
+ policies
+
+---
+ CMakeLists.txt                | 13 +++++++++++++
+ unix/vncserver/CMakeLists.txt |  2 +-
+ unix/vncserver/vncsession.c   | 16 ++++++++++++++++
+ 3 files changed, 30 insertions(+), 1 deletion(-)
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index 7bf9944..85be468 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -276,6 +276,19 @@ if(UNIX AND NOT APPLE)
+   endif()
+ endif()
+
++# Check for SELinux library
++if(UNIX AND NOT APPLE)
++  check_include_files(selinux/selinux.h HAVE_SELINUX_H)
++  if(HAVE_SELINUX_H)
++    set(CMAKE_REQUIRED_LIBRARIES -lselinux)
++    set(CMAKE_REQUIRED_LIBRARIES)
++    set(SELINUX_LIBS selinux)
++    add_definitions("-DHAVE_SELINUX")
++  else()
++    message(WARNING "Could not find SELinux development files")
++  endif()
++endif()
++
+ # Generate config.h and make sure the source finds it
+ configure_file(config.h.in config.h)
+ add_definitions(-DHAVE_CONFIG_H)
+diff --git a/unix/vncserver/CMakeLists.txt b/unix/vncserver/CMakeLists.txt
+index eeb4b7b..bce1c3e 100644
+--- a/unix/vncserver/CMakeLists.txt
++++ b/unix/vncserver/CMakeLists.txt
+@@ -1,5 +1,5 @@
+ add_executable(vncsession vncsession.c)
+-target_link_libraries(vncsession ${PAM_LIBS})
++target_link_libraries(vncsession ${PAM_LIBS} ${SELINUX_LIBS})
+
+ configure_file(vncserver@.service.in vncserver@.service @ONLY)
+ configure_file(vncsession-start.in vncsession-start @ONLY)
+diff --git a/unix/vncserver/vncsession.c b/unix/vncserver/vncsession.c
+index f78c096..141f689 100644
+--- a/unix/vncserver/vncsession.c
++++ b/unix/vncserver/vncsession.c
+@@ -37,6 +37,11 @@
+ #include <sys/types.h>
+ #include <sys/wait.h>
+
++#ifdef HAVE_SELINUX
++#include <selinux/selinux.h>
++#include <selinux/restorecon.h>
++#endif
++
+ extern char **environ;
+
+ // PAM service name
+@@ -359,6 +364,17 @@ redir_stdio(const char *homedir, const char *display)
+             perror("mkdir");
+             _exit(EX_OSERR);
+         }
++
++#ifdef HAVE_SELINUX
++        int result;
++        if (selinux_file_context_verify(logfile, 0) == 0) {
++            result = selinux_restorecon(logfile, SELINUX_RESTORECON_RECURSE);
++
++            if (result < 0) {
++                syslog(LOG_WARNING, "Failure restoring SELinux context for \"%s\": %s", logfile, strerror(errno));
++            }
++        }
++#endif
+     }
+
+     if (gethostname(hostname, sizeof(hostname)) == -1) {
diff --git a/SOURCES/tigervnc-vncsession-restore-script-systemd-service.patch b/SOURCES/tigervnc-vncsession-restore-script-systemd-service.patch
new file mode 100644
index 0000000..e503576
--- /dev/null
+++ b/SOURCES/tigervnc-vncsession-restore-script-systemd-service.patch
@@ -0,0 +1,113 @@
+From 1919a8ab86c99b47ba86dc697abcdf3343b0aafa Mon Sep 17 00:00:00 2001
+From: Jan Grulich <jgrulich@redhat.com>
+Date: Tue, 1 Feb 2022 14:31:05 +0100
+Subject: Add vncsession-restore script to restore SELinux context
+
+The vncsession-restore script is used in the ExecStartPre option
+for systemd service file in order to properly start the session
+in case the policy is updated (e.g. after Tigervnc update).
+
+diff --git a/unix/vncserver/CMakeLists.txt b/unix/vncserver/CMakeLists.txt
+index bce1c3e..44c4e2a 100644
+--- a/unix/vncserver/CMakeLists.txt
++++ b/unix/vncserver/CMakeLists.txt
+@@ -2,6 +2,7 @@ add_executable(vncsession vncsession.c)
+ target_link_libraries(vncsession ${PAM_LIBS} ${SELINUX_LIBS})
+
+ configure_file(vncserver@.service.in vncserver@.service @ONLY)
++configure_file(vncsession-restore.in vncsession-restore @ONLY)
+ configure_file(vncsession-start.in vncsession-start @ONLY)
+ configure_file(vncserver.in vncserver @ONLY)
+
+@@ -17,4 +18,5 @@ install(FILES vncserver.users DESTINATION ${CMAKE_INSTALL_FULL_SYSCONFDIR}/tiger
+ if(INSTALL_SYSTEMD_UNITS)
+   install(FILES ${CMAKE_CURRENT_BINARY_DIR}/vncserver@.service DESTINATION ${CMAKE_INSTALL_FULL_UNITDIR})
+   install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/vncsession-start DESTINATION ${CMAKE_INSTALL_FULL_LIBEXECDIR})
++  install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/vncsession-restore DESTINATION ${CMAKE_INSTALL_FULL_LIBEXECDIR})
+ endif()
+diff --git a/unix/vncserver/vncserver@.service.in b/unix/vncserver/vncserver@.service.in
+index 5624dff..be62c85 100644
+--- a/unix/vncserver/vncserver@.service.in
++++ b/unix/vncserver/vncserver@.service.in
+@@ -35,6 +35,7 @@ After=syslog.target network.target
+
+ [Service]
+ Type=forking
++ExecStartPre=+@CMAKE_INSTALL_FULL_LIBEXECDIR@/vncsession-restore %i
+ ExecStart=@CMAKE_INSTALL_FULL_LIBEXECDIR@/vncsession-start %i
+ PIDFile=/run/vncsession-%i.pid
+ SELinuxContext=system_u:system_r:vnc_session_t:s0
+diff --git a/unix/vncserver/vncsession-restore.in b/unix/vncserver/vncsession-restore.in
+new file mode 100644
+index 00000000..d3abc57d
+--- /dev/null
++++ b/unix/vncserver/vncsession-restore.in
+@@ -0,0 +1,68 @@
++#!/bin/bash
++#
++#  Copyright 2022 Jan Grulich <jgrulich@redhat.com>
++#
++#  This is free software; you can redistribute it and/or modify
++#  it under the terms of the GNU General Public License as published by
++#  the Free Software Foundation; either version 2 of the License, or
++#  (at your option) any later version.
++#
++#  This software is distributed in the hope that it will be useful,
++#  but WITHOUT ANY WARRANTY; without even the implied warranty of
++#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++#  GNU General Public License for more details.
++#
++#  You should have received a copy of the GNU General Public License
++#  along with this software; if not, write to the Free Software
++#  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
++#  USA.
++#
++
++USERSFILE="@CMAKE_INSTALL_FULL_SYSCONFDIR@/tigervnc/vncserver.users"
++
++if [ $# -ne 1 ]; then
++	echo "Syntax:" >&2
++	echo "    $0 <display>" >&2
++	exit 1
++fi
++
++if [ ! -f "${USERSFILE}" ]; then
++	echo "Users file ${USERSFILE} missing" >&2
++	exit 1
++fi
++
++DISPLAY="$1"
++
++USER=`grep "^ *${DISPLAY}=" "${USERSFILE}" 2>/dev/null | head -1 | cut -d = -f 2- | sed 's/ *$//g'`
++
++if [ -z "${USER}" ]; then
++	echo "No user configured for display ${DISPLAY}" >&2
++	exit 1
++fi
++
++USER_HOMEDIR=`getent passwd ${USER} | cut -f6 -d:`
++
++if [ -z "${USER_HOMEDIR}" ]; then
++	echo "Failed to get home directory for ${USER}" >&2
++	exit 1
++fi
++
++if [ ! -d "${USER_HOMEDIR}/.vnc" ]; then
++	exit 0
++fi
++
++MATCHPATHCON=`which matchpathcon`
++
++if [ $? -eq 0 ]; then
++	${MATCHPATHCON} -V "${USER_HOMEDIR}/.vnc" &>/dev/null
++	if [ $? -eq 0 ]; then
++		exit 0
++	fi
++fi
++
++RESTORECON=`which restorecon`
++
++if [ $? -eq 0 ]; then
++	exec "${RESTORECON}" -R "${USER_HOMEDIR}/.vnc" >&2
++	return $?
++fi
diff --git a/SPECS/tigervnc.spec b/SPECS/tigervnc.spec
index f2d3cc2..f878f7d 100644
--- a/SPECS/tigervnc.spec
+++ b/SPECS/tigervnc.spec
@@ -5,7 +5,7 @@
 
 Name:           tigervnc
 Version:        1.11.0
-Release:        20%{?dist}
+Release:        21%{?dist}
 Summary:        A TigerVNC remote display system
 
 %global _hardened_build 1
@@ -36,7 +36,9 @@ Patch57:        tigervnc-correctly-start-vncsession-as-daemon.patch
 Patch58:        tigervnc-selinux-missing-compression-and-correct-location.patch
 Patch59:        tigervnc-selinux-policy-improvements.patch
 Patch60:        tigervnc-argb-runtime-ximage-byteorder-selection.patch
-
+Patch61:        tigervnc-selinux-restore-context-in-case-of-different-policies.patch
+Patch62:        tigervnc-root-user-selinux-context.patch
+Patch63:        tigervnc-vncsession-restore-script-systemd-service.patch
 
 # This is tigervnc-%%{version}/unix/xserver116.patch rebased on the latest xorg
 Patch100:       tigervnc-xserver120.patch
@@ -176,6 +178,9 @@ popd
 %patch58 -p1 -b .selinux-missing-compression-and-correct-location
 %patch59 -p1 -b .selinux-policy-improvements
 %patch60 -p1 -b .argb-runtime-ximage-byteorder-selection
+%patch61 -p1 -b .selinux-restore-context-in-case-of-different-policies
+%patch62 -p1 -b .root-user-selinux-context
+%patch63 -p1 -b .vncsession-restore-script-systemd-service
 
 %build
 %ifarch sparcv9 sparc64 s390 s390x
@@ -185,6 +190,10 @@ export CFLAGS="$RPM_OPT_FLAGS -fpic"
 %endif
 export CXXFLAGS="$CFLAGS -std=c++11"
 
+%define __cmake_builddir %{_target_platform}
+
+mkdir -p %{%__cmake_builddir}
+
 %cmake
 
 %cmake_build
@@ -327,6 +336,7 @@ fi
 %{_sbindir}/vncsession
 %{_libexecdir}/vncserver
 %{_libexecdir}/vncsession-start
+%{_libexecdir}/vncsession-restore
 %{_mandir}/man1/x0vncserver.1*
 %{_mandir}/man8/vncserver.8*
 %{_mandir}/man8/vncsession.8*
@@ -355,6 +365,11 @@ fi
 %ghost %verify(not md5 size mtime) %{_sharedstatedir}/selinux/%{selinuxtype}/active/modules/200/%{modulename}
 
 %changelog
+* Mon Feb 07 2022 Jan Grulich <jgrulich@redhat.com> - 1.11.0-21
+- Added vncsession-restore script for SELinux policy migration
+  Fix SELinux context for root user
+  Resolves: bz#2049506
+
 * Fri Nov 26 2021 Jan Grulich <jgrulich@redhat.com> - 1.11.0-20
 - Rebuild for absence in RHEL 9.0
   Resolves: bz#1985858