diff -urN portage-3.0.65-orig/bin/dispatch-conf portage-3.0.65/bin/dispatch-conf
--- portage-3.0.65-orig/bin/dispatch-conf	2024-06-04 10:27:26 +0900
+++ portage-3.0.65/bin/dispatch-conf	2024-06-08 17:47:22 +0900
@@ -204,6 +204,7 @@
             config_root,
             config_paths,
             portage.settings.get("CONFIG_PROTECT_MASK", "").split(),
+            portage.settings.get("CONFIG_PROTECT_UNMASK", "").split(),
             case_insensitive=("case-insensitive-fs" in portage.settings.features),
         )
 
diff -urN portage-3.0.65-orig/bin/portageq portage-3.0.65/bin/portageq
--- portage-3.0.65-orig/bin/portageq	2024-06-04 10:27:26 +0900
+++ portage-3.0.65/bin/portageq	2024-06-08 17:47:02 +0900
@@ -412,10 +412,12 @@
         settings = portage.settings
         protect = settings.get("CONFIG_PROTECT", "").split()
         protect_mask = settings.get("CONFIG_PROTECT_MASK", "").split()
+        protect_unmask = settings.get("CONFIG_PROTECT_UNMASK", "").split()
         protect_obj = ConfigProtect(
             root,
             protect,
             protect_mask,
+            protect_unmask,
             case_insensitive=("case-insensitive-fs" in settings.features),
         )
         if protect_obj.isprotected(f):
@@ -451,10 +453,12 @@
         settings = portage.settings
         protect = settings.get("CONFIG_PROTECT", "").split()
         protect_mask = settings.get("CONFIG_PROTECT_MASK", "").split()
+        protect_unmask = settings.get("CONFIG_PROTECT_UNMASK", "").split()
         protect_obj = ConfigProtect(
             root,
             protect,
             protect_mask,
+            protect_unmask,
             case_insensitive=("case-insensitive-fs" in settings.features),
         )
 
diff -urN portage-3.0.65-orig/lib/_emerge/actions.py portage-3.0.65/lib/_emerge/actions.py
--- portage-3.0.65-orig/lib/_emerge/actions.py	2024-06-04 10:27:26 +0900
+++ portage-3.0.65/lib/_emerge/actions.py	2024-06-08 17:44:41 +0900
@@ -2168,6 +2168,7 @@
             "GENTOO_MIRRORS",
             "CONFIG_PROTECT",
             "CONFIG_PROTECT_MASK",
+            "CONFIG_PROTECT_UNMASK",
             "DISTDIR",
             "ENV_UNSET",
             "PKGDIR",
diff -urN portage-3.0.65-orig/lib/_emerge/depgraph.py portage-3.0.65/lib/_emerge/depgraph.py
--- portage-3.0.65-orig/lib/_emerge/depgraph.py	2024-06-04 10:27:26 +0900
+++ portage-3.0.65/lib/_emerge/depgraph.py	2024-06-08 17:46:07 +0900
@@ -10623,6 +10623,7 @@
                     settings["PORTAGE_CONFIGROOT"],
                     settings.get("CONFIG_PROTECT", "").split(),
                     settings.get("CONFIG_PROTECT_MASK", "").split(),
+                    settings.get("CONFIG_PROTECT_UNMASK", "").split(),
                     case_insensitive=("case-insensitive-fs" in settings.features),
                 )
 
diff -urN portage-3.0.65-orig/lib/portage/_global_updates.py portage-3.0.65/lib/portage/_global_updates.py
--- portage-3.0.65-orig/lib/portage/_global_updates.py	2024-06-04 10:27:26 +0900
+++ portage-3.0.65/lib/portage/_global_updates.py	2024-06-08 17:45:03 +0900
@@ -229,6 +229,7 @@
             root,
             mysettings.get("CONFIG_PROTECT", "").split(),
             mysettings.get("CONFIG_PROTECT_MASK", "").split(),
+            mysettings.get("CONFIG_PROTECT_UNMASK", "").split(),
             repo_map,
             match_callback=_config_repo_match,
             case_insensitive="case-insensitive-fs" in mysettings.features,
diff -urN portage-3.0.65-orig/lib/portage/const.py portage-3.0.65/lib/portage/const.py
--- portage-3.0.65-orig/lib/portage/const.py	2024-06-04 10:27:26 +0900
+++ portage-3.0.65/lib/portage/const.py	2024-06-08 17:44:41 +0900
@@ -122,6 +122,7 @@
     "ACCEPT_KEYWORDS",
     "CONFIG_PROTECT",
     "CONFIG_PROTECT_MASK",
+    "CONFIG_PROTECT_UNMASK",
     "ENV_UNSET",
     "FEATURES",
     "IUSE_IMPLICIT",
diff -urN portage-3.0.65-orig/lib/portage/dbapi/bintree.py portage-3.0.65/lib/portage/dbapi/bintree.py
--- portage-3.0.65-orig/lib/portage/dbapi/bintree.py	2024-06-04 10:27:26 +0900
+++ portage-3.0.65/lib/portage/dbapi/bintree.py	2024-06-08 17:44:41 +0900
@@ -593,6 +593,7 @@
             "CBUILD",
             "CONFIG_PROTECT",
             "CONFIG_PROTECT_MASK",
+            "CONFIG_PROTECT_UNMASK",
             "FEATURES",
             "GENTOO_MIRRORS",
             "INSTALL_MASK",
diff -urN portage-3.0.65-orig/lib/portage/dbapi/vartree.py portage-3.0.65/lib/portage/dbapi/vartree.py
--- portage-3.0.65-orig/lib/portage/dbapi/vartree.py	2024-06-04 10:27:26 +0900
+++ portage-3.0.65/lib/portage/dbapi/vartree.py	2024-06-08 17:45:48 +0900
@@ -1862,6 +1862,7 @@
                 self._eroot,
                 self.settings.get("CONFIG_PROTECT", "").split(),
                 self.settings.get("CONFIG_PROTECT_MASK", "").split(),
+                self.settings.get("CONFIG_PROTECT_UNMASK", "").split(),
                 case_insensitive=("case-insensitive-fs" in self.settings.features),
             )
 
@@ -2141,6 +2142,7 @@
                 settings["EROOT"],
                 settings.get("CONFIG_PROTECT", "").split(),
                 settings.get("CONFIG_PROTECT_MASK", "").split(),
+                settings.get("CONFIG_PROTECT_UNMASK", "").split(),
                 case_insensitive=("case-insensitive-fs" in settings.features),
             )
 
diff -urN portage-3.0.65-orig/lib/portage/package/ebuild/_config/special_env_vars.py portage-3.0.65/lib/portage/package/ebuild/_config/special_env_vars.py
--- portage-3.0.65-orig/lib/portage/package/ebuild/_config/special_env_vars.py	2024-06-04 10:27:26 +0900
+++ portage-3.0.65/lib/portage/package/ebuild/_config/special_env_vars.py	2024-06-08 17:44:41 +0900
@@ -278,6 +278,7 @@
         "COLLISION_IGNORE",
         "CONFIG_PROTECT",
         "CONFIG_PROTECT_MASK",
+        "CONFIG_PROTECT_UNMASK",
         "EGENCACHE_DEFAULT_OPTS",
         "EMERGE_DEFAULT_OPTS",
         "EMERGE_LOG_DIR",
@@ -343,6 +344,7 @@
 global_only_vars = frozenset(
     [
         "CONFIG_PROTECT",
+        "CONFIG_PROTECT_UNMASK",
     ]
 )
 
diff -urN portage-3.0.65-orig/lib/portage/package/ebuild/config.py portage-3.0.65/lib/portage/package/ebuild/config.py
--- portage-3.0.65-orig/lib/portage/package/ebuild/config.py	2024-06-04 10:27:26 +0900
+++ portage-3.0.65/lib/portage/package/ebuild/config.py	2024-06-08 17:44:41 +0900
@@ -1206,6 +1206,7 @@
         eroot_only_variables = (
             "CONFIG_PROTECT",
             "CONFIG_PROTECT_MASK",
+            "CONFIG_PROTECT_UNMASK",
             "INFODIR",
             "INFOPATH",
             "MANPATH",
diff -urN portage-3.0.65-orig/lib/portage/update.py portage-3.0.65/lib/portage/update.py
--- portage-3.0.65-orig/lib/portage/update.py	2024-06-04 10:27:26 +0900
+++ portage-3.0.65/lib/portage/update.py	2024-06-08 17:44:41 +0900
@@ -286,6 +286,7 @@
     config_root,
     protect,
     protect_mask,
+    protect_unmask,
     update_iter,
     match_callback=None,
     case_insensitive=False,
@@ -295,6 +296,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:
@@ -438,7 +440,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.65-orig/lib/portage/util/__init__.py portage-3.0.65/lib/portage/util/__init__.py
--- portage-3.0.65-orig/lib/portage/util/__init__.py	2024-06-04 10:27:26 +0900
+++ portage-3.0.65/lib/portage/util/__init__.py	2024-06-08 17:44:41 +0900
@@ -1776,10 +1776,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()
 
@@ -1821,6 +1822,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
@@ -1854,7 +1866,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.65-orig/lib/portage/util/env_update.py portage-3.0.65/lib/portage/util/env_update.py
--- portage-3.0.65-orig/lib/portage/util/env_update.py	2024-06-04 10:27:26 +0900
+++ portage-3.0.65/lib/portage/util/env_update.py	2024-06-08 17:44:41 +0900
@@ -119,7 +119,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",
