Let's examine this perplexing case where user 'bob' can't access files he supposedly owns. Here's the exact situation as presented:
> ls -al .
total 32
drwxrwxr-x 7 bob bob 4096 May 18 14:33 .
drwxrwxr-x 4 bob bob 4096 May 12 15:44 ..
drwxr-xr-x 2 bob bob 4096 June 1 14:22 log
> cd ./log
-bash: cd: log/: Permission denied
The critical observation here is the directory permission mask. While the directory is owned by bob, the execute bit (x) is missing from the owner's permission set:
drw-rw-r-- 3 bob bob 4096 Jun 2 04:11 .
This missing execute permission (shown as 'drw-rw-r--') is what's preventing directory access, despite the ownership. In Linux:
- Read (r) allows listing directory contents
- Write (w) allows creating/deleting files
- Execute (x) allows entering/cd'ing into the directory
Several scenarios could lead to this situation:
- Accidental permission modification via
chmod
- Filesystem corruption (less likely but possible)
- Inherited permissions from a restrictive umask setting
- SELinux context issues (especially on Fedora)
Here's how to properly diagnose and fix the issue:
# First verify permissions
stat log/
# Check for SELinux context
ls -Z log/
# Correct the directory permissions
chmod u+x log/
# For recursive fixes (if needed)
chmod -R u+X log/
The -X
(capital X) in recursive mode sets execute only for directories, not regular files.
For thorough system administrators, these additional checks help identify root causes:
# Check mount options
mount | grep 'on / '
# Verify ACLs (if any)
getfacl log/
# Check filesystem health
sudo fsck -n /dev/sdXN
To avoid such issues in future:
- Set proper umask in ~/.bashrc:
umask 0022
- Use
chmod
carefully, especially with recursive operations - Consider using ACLs for complex permission needs
Remember that directory execute permission is fundamentally different from file execute permission - this is a common point of confusion even among experienced Linux users.
Recently I encountered a bizarre permission issue where my user account couldn't access files it supposedly owned. Here's what happened:
> ls -al .
total 32
drwxrwxr-x 7 bob bob 4096 May 18 14:33 .
drwxrwxr-x 4 bob bob 4096 May 12 15:44 ..
drwxr-xr-x 2 bob bob 4096 June 1 14:22 log
> cd ./log
-bash: cd: log/: Permission denied
The most puzzling part was the output from ls -al ./log
:
> ls -al ./log
ls: cannot access log/..: Permission denied
ls: cannot access log/the.log: Permission denied
ls: cannot access log/.: Permission denied
total 0
d????????? ? ? ? ? ? .
d????????? ? ? ? ? ? ..
-????????? ? ? ? ? ? the.log
Yet when using sudo, the permissions appeared normal:
> sudo ls -al ./log
drw-rw-r-- 3 bob bob 4096 Jun 2 04:11 .
drwxrwxr-x 7 bob bob 4096 May 18 14:33 ..
-rw-rw-r-- 1 bob bob 0 Jun 1 04:12 the.log
After some research, I discovered this was an SELinux context issue. Here's how to check:
ls -Z /path/to/directory
And to restore the proper context:
restorecon -Rv /path/to/directory
If SELinux isn't the culprit, consider these checks:
# Check filesystem mount options
mount | grep " / "
# Verify ACLs
getfacl /path/to/file
# Check for filesystem errors
fsck /dev/sdXN
To avoid similar problems:
- Regularly check SELinux contexts when moving files between locations
- Use
rsync -aX
to preserve contexts when copying files - Consider adding SELinux context awareness to your backup scripts
Here's a simple script to monitor context changes:
#!/bin/bash
DIR="/path/to/monitor"
LOG="/var/log/selinux_context_changes.log"
find "$DIR" -exec ls -Zd {} + | sort > /tmp/current_contexts
if [ -f "/tmp/previous_contexts" ]; then
diff -u /tmp/previous_contexts /tmp/current_contexts >> "$LOG"
fi
mv /tmp/current_contexts /tmp/previous_contexts