Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 40 additions & 4 deletions src/common/permission_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,27 +13,63 @@

logger = logging.getLogger(__name__)

# System directories that should never have their permissions modified
# These directories have special system-level permissions that must be preserved
PROTECTED_SYSTEM_DIRECTORIES = {
'/tmp',
'/var/tmp',
'/dev',
'/proc',
'/sys',
'/run',
'/var/run',
'/etc',
'/boot',
'/var',
'/usr',
'/lib',
'/lib64',
'/bin',
'/sbin',
}


def ensure_directory_permissions(path: Path, mode: int = 0o775) -> None:
"""
Create directory and set permissions.

If the directory already exists and we cannot change its permissions,
we check if it's usable (readable/writable). If so, we continue without
raising an exception. This allows the system to work even when running
as a non-root user who cannot change permissions on existing directories.


Protected system directories (like /tmp, /etc, /var) are never modified
to prevent breaking system functionality.

Args:
path: Directory path to create/ensure
mode: Permission mode (default: 0o775 for group-writable directories)

Raises:
OSError: If directory creation fails or directory exists but is not usable
"""
try:
# Never modify permissions on system directories
path_str = str(path.resolve() if path.is_absolute() else path)
if path_str in PROTECTED_SYSTEM_DIRECTORIES:
logger.debug(f"Skipping permission modification on protected system directory: {path_str}")
# Verify the directory is usable
if path.exists() and os.access(path, os.R_OK | os.W_OK):
return
elif path.exists():
logger.warning(f"Protected system directory {path_str} exists but is not writable")
return
else:
raise OSError(f"Protected system directory {path_str} does not exist")

# Create directory if it doesn't exist
path.mkdir(parents=True, exist_ok=True)

# Try to set permissions
try:
os.chmod(path, mode)
Expand Down
8 changes: 6 additions & 2 deletions src/display_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -816,8 +816,12 @@ def _write_snapshot_if_due(self) -> None:
get_assets_file_mode
)
snapshot_path_obj = Path(self._snapshot_path)
if snapshot_path_obj.parent:
ensure_directory_permissions(snapshot_path_obj.parent, get_assets_dir_mode())
# Only ensure permissions on non-system directories
# Never modify /tmp permissions - it has special system permissions (1777)
# that must not be changed or it breaks apt and other system tools
parent_dir = snapshot_path_obj.parent
if parent_dir and str(parent_dir) != '/tmp':
ensure_directory_permissions(parent_dir, get_assets_dir_mode())
# Write atomically: temp then replace
tmp_path = f"{self._snapshot_path}.tmp"
self.image.save(tmp_path, format='PNG')
Expand Down