mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-05-17 10:43:32 +00:00
fix: prevent /tmp permission corruption breaking system updates (#209)
Issue: LEDMatrix was changing /tmp permissions from 1777 (drwxrwxrwt) to 2775 (drwxrwsr-x), breaking apt update and other system tools. Root cause: display_manager.py's _write_snapshot_if_due() called ensure_directory_permissions() on /tmp when writing snapshots to /tmp/led_matrix_preview.png. This removed the sticky bit and world-writable permissions that /tmp requires. Fix: - Added PROTECTED_SYSTEM_DIRECTORIES safelist to permission_utils.py to prevent modifying permissions on /tmp and other system directories - Added explicit check in display_manager.py to skip /tmp - Defense-in-depth approach prevents similar issues in other code paths The sticky bit (1xxx) is critical for /tmp - it prevents users from deleting files they don't own. Without world-writable permissions, regular users cannot create temp files. Fixes #202 Co-authored-by: Chuck <chuck@example.com> Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -13,27 +13,63 @@ from typing import Optional
|
||||
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user