diff -urN portage-3.0.44-orig/bin/dispatch-conf portage-3.0.44/bin/dispatch-conf
--- portage-3.0.44-orig/bin/dispatch-conf	2023-01-16 07:11:19 +0900
+++ portage-3.0.44/bin/dispatch-conf	2023-01-31 08:15:28 +0900
@@ -195,6 +195,7 @@
             config_root,
             config_paths,
             portage.util.shlex_split(portage.settings.get("CONFIG_PROTECT_MASK", "")),
+            portage.util.shlex_split(portage.settings.get("CONFIG_PROTECT_UNMASK", "")),
             case_insensitive=("case-insensitive-fs" in portage.settings.features),
         )
 
diff -urN portage-3.0.44-orig/bin/portageq portage-3.0.44/bin/portageq
--- portage-3.0.44-orig/bin/portageq	2023-01-16 07:11:19 +0900
+++ portage-3.0.44/bin/portageq	2023-01-31 08:15:28 +0900
@@ -411,10 +411,12 @@
         settings = portage.settings
         protect = portage.util.shlex_split(settings.get("CONFIG_PROTECT", ""))
         protect_mask = portage.util.shlex_split(settings.get("CONFIG_PROTECT_MASK", ""))
+        protect_unmask = portage.util.shlex_split(settings.get("CONFIG_PROTECT_UNMASK", ""))
         protect_obj = ConfigProtect(
             root,
             protect,
             protect_mask,
+            protect_unmask,
             case_insensitive=("case-insensitive-fs" in settings.features),
         )
         if protect_obj.isprotected(f):
@@ -450,10 +452,12 @@
         settings = portage.settings
         protect = portage.util.shlex_split(settings.get("CONFIG_PROTECT", ""))
         protect_mask = portage.util.shlex_split(settings.get("CONFIG_PROTECT_MASK", ""))
+        protect_unmask = portage.util.shlex_split(settings.get("CONFIG_PROTECT_UNMASK", ""))
         protect_obj = ConfigProtect(
             root,
             protect,
             protect_mask,
+            protect_unmask,
             case_insensitive=("case-insensitive-fs" in settings.features),
         )
 
diff -urN portage-3.0.44-orig/lib/_emerge/actions.py portage-3.0.44/lib/_emerge/actions.py
--- portage-3.0.44-orig/lib/_emerge/actions.py	2023-01-16 07:11:19 +0900
+++ portage-3.0.44/lib/_emerge/actions.py	2023-01-31 08:15:28 +0900
@@ -2165,6 +2165,7 @@
             "GENTOO_MIRRORS",
             "CONFIG_PROTECT",
             "CONFIG_PROTECT_MASK",
+            "CONFIG_PROTECT_UNMASK",
             "DISTDIR",
             "ENV_UNSET",
             "PKGDIR",
diff -urN portage-3.0.44-orig/lib/_emerge/depgraph.py portage-3.0.44/lib/_emerge/depgraph.py
--- portage-3.0.44-orig/lib/_emerge/depgraph.py	2023-01-16 07:11:19 +0900
+++ portage-3.0.44/lib/_emerge/depgraph.py	2023-01-31 08:15:28 +0900
@@ -10346,6 +10346,7 @@
                     settings["PORTAGE_CONFIGROOT"],
                     shlex_split(settings.get("CONFIG_PROTECT", "")),
                     shlex_split(settings.get("CONFIG_PROTECT_MASK", "")),
+                    shlex_split(settings.get("CONFIG_PROTECT_UNMASK", "")),
                     case_insensitive=("case-insensitive-fs" in settings.features),
                 )
 
diff -urN portage-3.0.44-orig/lib/portage/_global_updates.py portage-3.0.44/lib/portage/_global_updates.py
--- portage-3.0.44-orig/lib/portage/_global_updates.py	2023-01-16 07:11:19 +0900
+++ portage-3.0.44/lib/portage/_global_updates.py	2023-01-31 08:15:28 +0900
@@ -224,6 +224,7 @@
             root,
             shlex_split(mysettings.get("CONFIG_PROTECT", "")),
             shlex_split(mysettings.get("CONFIG_PROTECT_MASK", "")),
+            shlex_split(mysettings.get("CONFIG_PROTECT_UNMASK", "")),
             repo_map,
             match_callback=_config_repo_match,
             case_insensitive="case-insensitive-fs" in mysettings.features,
diff -urN portage-3.0.44-orig/lib/portage/const.py portage-3.0.44/lib/portage/const.py
--- portage-3.0.44-orig/lib/portage/const.py	2023-01-16 07:11:19 +0900
+++ portage-3.0.44/lib/portage/const.py	2023-01-31 08:15:28 +0900
@@ -91,6 +91,7 @@
     "ACCEPT_KEYWORDS",
     "CONFIG_PROTECT",
     "CONFIG_PROTECT_MASK",
+    "CONFIG_PROTECT_UNMASK",
     "ENV_UNSET",
     "FEATURES",
     "IUSE_IMPLICIT",
diff -urN portage-3.0.44-orig/lib/portage/dbapi/bintree.py portage-3.0.44/lib/portage/dbapi/bintree.py
--- portage-3.0.44-orig/lib/portage/dbapi/bintree.py	2023-01-16 07:11:19 +0900
+++ portage-3.0.44/lib/portage/dbapi/bintree.py	2023-01-31 08:15:28 +0900
@@ -542,6 +542,7 @@
             "CBUILD",
             "CONFIG_PROTECT",
             "CONFIG_PROTECT_MASK",
+            "CONFIG_PROTECT_UNMASK",
             "FEATURES",
             "GENTOO_MIRRORS",
             "INSTALL_MASK",
diff -urN portage-3.0.44-orig/lib/portage/dbapi/vartree.py portage-3.0.44/lib/portage/dbapi/vartree.py
--- portage-3.0.44-orig/lib/portage/dbapi/vartree.py	2023-01-16 07:11:19 +0900
+++ portage-3.0.44/lib/portage/dbapi/vartree.py	2023-01-31 08:15:28 +0900
@@ -1876,6 +1876,7 @@
                 self._eroot,
                 portage.util.shlex_split(self.settings.get("CONFIG_PROTECT", "")),
                 portage.util.shlex_split(self.settings.get("CONFIG_PROTECT_MASK", "")),
+                portage.util.shlex_split(self.settings.get("CONFIG_PROTECT_UNMASK", "")),
                 case_insensitive=("case-insensitive-fs" in self.settings.features),
             )
 
@@ -2155,6 +2156,7 @@
                 settings["EROOT"],
                 portage.util.shlex_split(settings.get("CONFIG_PROTECT", "")),
                 portage.util.shlex_split(settings.get("CONFIG_PROTECT_MASK", "")),
+                portage.util.shlex_split(settings.get("CONFIG_PROTECT_UNMASK", "")),
                 case_insensitive=("case-insensitive-fs" in settings.features),
             )
 
diff -urN portage-3.0.44-orig/lib/portage/package/ebuild/_config/special_env_vars.py portage-3.0.44/lib/portage/package/ebuild/_config/special_env_vars.py
--- portage-3.0.44-orig/lib/portage/package/ebuild/_config/special_env_vars.py	2023-01-16 07:11:19 +0900
+++ portage-3.0.44/lib/portage/package/ebuild/_config/special_env_vars.py	2023-01-31 08:15:28 +0900
@@ -275,6 +275,7 @@
         "COLLISION_IGNORE",
         "CONFIG_PROTECT",
         "CONFIG_PROTECT_MASK",
+        "CONFIG_PROTECT_UNMASK",
         "EGENCACHE_DEFAULT_OPTS",
         "EMERGE_DEFAULT_OPTS",
         "EMERGE_LOG_DIR",
@@ -339,6 +340,7 @@
 global_only_vars = frozenset(
     [
         "CONFIG_PROTECT",
+        "CONFIG_PROTECT_UNMASK",
     ]
 )
 
diff -urN portage-3.0.44-orig/lib/portage/package/ebuild/config.py portage-3.0.44/lib/portage/package/ebuild/config.py
--- portage-3.0.44-orig/lib/portage/package/ebuild/config.py	2023-01-16 07:11:19 +0900
+++ portage-3.0.44/lib/portage/package/ebuild/config.py	2023-01-31 08:15:28 +0900
@@ -1208,6 +1208,7 @@
         eroot_only_variables = (
             "CONFIG_PROTECT",
             "CONFIG_PROTECT_MASK",
+            "CONFIG_PROTECT_UNMASK",
             "INFODIR",
             "INFOPATH",
             "MANPATH",
diff -urN portage-3.0.44-orig/lib/portage/update.py portage-3.0.44/lib/portage/update.py
--- portage-3.0.44-orig/lib/portage/update.py	2023-01-16 07:11:19 +0900
+++ portage-3.0.44/lib/portage/update.py	2023-01-31 08:15:28 +0900
@@ -287,6 +287,7 @@
     config_root,
     protect,
     protect_mask,
+    protect_unmask,
     update_iter,
     match_callback=None,
     case_insensitive=False,
@@ -296,6 +297,7 @@
     config_root - location of files to update
     protect - list of paths from CONFIG_PROTECT
     protect_mask - list of paths from CONFIG_PROTECT_MASK
+    protect_unmask - list of paths from CONFIG_PROTECT_UNMASK
     update_iter - list of update commands as returned from parse_updates(),
             or dict of {repo_name: list}
     match_callback - a callback which will be called with three arguments:
@@ -439,7 +441,7 @@
                             sys.stdout.flush()
 
     protect_obj = ConfigProtect(
-        config_root, protect, protect_mask, case_insensitive=case_insensitive
+        config_root, protect, protect_mask, protect_unmask, case_insensitive=case_insensitive
     )
     for x in update_files:
         updating_file = os.path.join(abs_user_config, x)
diff -urN portage-3.0.44-orig/lib/portage/util/__init__.py portage-3.0.44/lib/portage/util/__init__.py
--- portage-3.0.44-orig/lib/portage/util/__init__.py	2023-01-16 07:11:19 +0900
+++ portage-3.0.44/lib/portage/util/__init__.py	2023-01-31 08:15:28 +0900
@@ -1759,10 +1759,11 @@
 
 
 class ConfigProtect:
-    def __init__(self, myroot, protect_list, mask_list, case_insensitive=False):
+    def __init__(self, myroot, protect_list, mask_list, unmask_list, case_insensitive=False):
         self.myroot = myroot
         self.protect_list = protect_list
         self.mask_list = mask_list
+        self.unmask_list = unmask_list
         self.case_insensitive = case_insensitive
         self.updateprotect()
 
@@ -1804,6 +1805,17 @@
                 # If it doesn't exist, there's no need to mask it.
                 pass
 
+        self.protectunmask = []
+        for x in self.unmask_list:
+            ppath = normalize_path(os.path.join(self.myroot, x.lstrip(os.path.sep)))
+            if os.path.isdir(os.path.dirname(ppath)):
+                self.protectunmask.append(ppath)
+            try:
+                if stat.S_ISDIR(os.stat(ppath).st_mode):
+                    self._dirs.add(ppath)
+            except OSError:
+                pass
+
     def isprotected(self, obj):
         """Returns True if obj is protected, False otherwise.  The caller must
         ensure that obj is normalized with a single leading slash.  A trailing
@@ -1837,7 +1849,17 @@
                             continue
                         # skip, it's in the mask
                         masked = len(pmpath)
-        return protected > masked
+        if protected > masked:
+            return True
+        for pupath in self.protectunmask:
+            if obj == pupath:
+                # target is unmasked by exact match, treat as protected
+                return True
+            if pupath in self._dirs:
+                if obj.startswith(pupath + sep):
+                    # target is in unmasked dir, treat as protected
+                    return True
+        return False
 
 
 def new_protect_filename(mydest, newmd5=None, force=False):
diff -urN portage-3.0.44-orig/lib/portage/util/env_update.py portage-3.0.44/lib/portage/util/env_update.py
--- portage-3.0.44-orig/lib/portage/util/env_update.py	2023-01-16 07:11:19 +0900
+++ portage-3.0.44/lib/portage/util/env_update.py	2023-01-31 08:15:28 +0900
@@ -118,7 +118,7 @@
     fns = templist
     del templist
 
-    space_separated = {"CONFIG_PROTECT", "CONFIG_PROTECT_MASK"}
+    space_separated = {"CONFIG_PROTECT", "CONFIG_PROTECT_MASK", "CONFIG_PROTECT_UNMASK"}
     colon_separated = {
         "ADA_INCLUDE_PATH",
         "ADA_OBJECTS_PATH",
