Chapter 25 — Permissions, ownership, and links
In one sentence
Every file has an owner, a group, and three sets of read/write/execute permissions (for the owner, the group, and everyone else) — and two special kinds of files, hard links and symbolic links, let a single piece of data be reachable by more than one name.
Why this matters
Permission mistakes are one of the most common real causes of both "why can't
I access this" AND serious security incidents — getting this model genuinely
right (not just cargo-culting chmod 777) matters.
How it actually works
THE PERMISSION MODEL: `ls -l` shows something like:
-rwxr-xr-- 1 alice developers 1234 Jan 1 12:00 script.sh
|||||||||
|||||||`- OTHERS: read only (r--)
||||`----- GROUP: read + execute (r-x)
`--------- OWNER (alice): read + write + execute (rwx)
Three PERMISSIONS (read, write, execute), applied to three CATEGORIES
of user (owner, group, everyone else). For a FILE: read = can view
contents, write = can modify, execute = can RUN it as a program. For
a DIRECTORY, the meanings shift slightly: read = can LIST its
contents, execute = can ENTER it / access files inside by name (even
without read), write = can CREATE/DELETE entries inside it.
chmod u+x script.sh # add execute for the owner (user)
chmod g-w file.txt # remove write for the group
chmod 755 script.sh # numeric form: owner=7(rwx), group=5(r-x),
# other=5(r-x) -- read each digit as a
# 3-bit binary sum: r=4, w=2, x=1
OWNERSHIP: every file has an OWNING USER and an OWNING GROUP
(`chown`, `chgrp`). This, combined with the permission bits above,
is the FULL access-control model for a standard Unix file (Chapter
36 covers more advanced access control beyond this).
HARD LINKS vs. SYMBOLIC LINKS (both introduced briefly in Chapter
15, formalised here):
HARD LINK (`ln target linkname`) another directory entry
pointing at the SAME INODE. Indistinguishable from "the
original" -- there IS no original, just multiple names for one
piece of data. Can't cross filesystems, can't link a directory.
SYMBOLIC LINK (`ln -s target linkname`) a SEPARATE, tiny file
that just CONTAINS A PATH STRING pointing at the target. Can
cross filesystems, can link directories, but BREAKS ("dangling
link") if the target is moved or deleted -- because it's just
a path, not a direct pointer to the data.
Real-world example
The SUID (Set User ID) permission bit is a real, historically
important, and still occasionally security-relevant extension of
this model: a program with the SUID bit set runs with the
PERMISSIONS OF ITS OWNER, not the permissions of whoever launched it.
The textbook LEGITIMATE use, present on essentially every Unix-like
system: `/usr/bin/passwd` (the program you run to change your own
password) is owned by root and has the SUID bit set, specifically so
an ORDINARY user can run it and have it write to `/etc/shadow` (the
system password file, which ordinary users otherwise cannot write to
at all) -- SUID is precisely the narrow, deliberate escape hatch that
makes this possible without giving every user general write access
to a security-critical file.
The FLIP SIDE is real and well documented: a MISCONFIGURED SUID
binary -- one that's SUID-root but has a bug, or is writable/
replaceable by a non-root user, or simply shouldn't have SUID set at
all -- is a classic, extremely common PRIVILEGE ESCALATION vector,
the subject of a large fraction of "local privilege escalation" CVEs
and CTF/security-training exercises (finding stray SUID binaries via
`find / -perm -4000` is a standard first step in real penetration
testing methodology, covered from the offensive side in this wiki's
security guides). This is a genuinely good, concrete illustration of
why understanding the permission model precisely -- not just "chmod
777 and move on" -- is a real, practical security skill, not academic
trivia.
Try it yourself
# See permissions and ownership, and change them
touch demo.txt
ls -l demo.txt
chmod u+x demo.txt; ls -l demo.txt
chmod 644 demo.txt; ls -l demo.txt # back to a normal, sane default
# See hard links vs symlinks in action
echo "original data" > original.txt
ln original.txt hardlink.txt
ln -s original.txt symlink.txt
ls -li original.txt hardlink.txt symlink.txt # -i shows inode numbers:
# hardlink SHARES one,
# symlink has its OWN
rm original.txt
cat hardlink.txt # still works
cat symlink.txt # BROKEN -- "No such file or directory"
# (dangling symlink, exactly as this chapter warns)
rm -f hardlink.txt symlink.txt
# Find SUID binaries on your own lab machine (informational, safe)
find /usr/bin /usr/sbin -perm -4000 2>/dev/null
Common mistakes
chmod 777as a reflex "fix" for permission errors. It removes ALL access control on that file/directory — almost always the wrong fix; find the actual owner/group mismatch instead.- Confusing "no read permission" with "file doesn't exist." A permission-denied error and a not-found error look similar in casual reading but mean very different things — read the actual error message.
- Assuming a symlink and its target are "the same file" for permission purposes. Symlink permissions are largely cosmetic on Linux (the TARGET's permissions are what actually apply when you follow it) — this trips people up constantly.
Check yourself
- Read
-rwxr-xr--and explain exactly what each group of three characters means. - What's the difference between a hard link and a symbolic link, concretely?
- What does the SUID bit do, and give both a legitimate and a risky real use of it.
Further reading
- Reference:
man 1 chmod,man 1 chown,man 2 stat. - Cheat sheet: any "chmod calculator" or permission-bits reference table — useful until the octal math becomes second nature.
- Guide: this wiki's security guides cover privilege escalation via SUID/capabilities in much greater depth, from the offensive side.