Exercise 23. Filesystems: security permissions, chown, chmod, umask
It is time to understand Linux filesystems security model. Let us start with quoting Wikipedia article on permissions:
Most current file systems have methods of administering permissions or access rights to specific users and groups of users. These systems control the ability of the users to view or make changes to the contents of the filesystem.
Permissions on Unix-like systems are managed in three distinct classes. These classes are known as user, group, and others. In effect, Unix permissions are a simplified form of access control lists (ACLs).
When a new file is created on a Unix-like system, its permissions are determined from the umask of the process that created it.
For each file in Linux there are three permission classes associated with it. For each permission class there are three permissions.
This are permission classes:
Class | Description |
---|---|
user | One system user. The file is said to be owned by this user. |
group | One group of users |
others | Any other users or groups |
This are permissions, assignable for each class:
Permission | Symbolic notation | Description |
---|---|---|
read | r-- | Ability to read the file |
write | -w- | Ability to write to the file |
execute | --x | Ability to execute file as a program, for example a shell script should have this set |
This two tables can be summed up:
Owner | Group | Others | ||||||
---|---|---|---|---|---|---|---|---|
r | w | x | r | w | x | r | w | x |
This permissions are represented as numbers. Consider the following output:
user1@vm1:~$ ls -al tmp.img -rw-r--r-- 1 root root 252706816 Jul 6 07:54 tmp.img user1@vm1:~$ stat tmp.img File: 'tmp.img' Size: 252706816 Blocks: 494064 IO Block: 4096 regular file Device: 809h/2057d Inode: 88534 Links: 1 Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root) Access: 2012-07-06 07:56:58.000000000 -0400 Modify: 2012-07-06 07:54:54.000000000 -0400 Change: 2012-07-06 07:54:54.000000000 -0400 user1@vm1:~$
Here we are able to see that tmp.img is owned by user root and group root and has the following permissions: -rw-r–r–. Let us learn to read them.
-rw # Owner can read and write to the file r-- # Group can only read the file r-- # Others can also only read the file 1 # root # Owner is user root root # Group is root (but remember not to confuse this with user) 252706816 # Jul # 6 # 07:54 # tmp.img #
Here are the same permissions is octal notation:
Access: ( 0 6 -rw 4 r-- 4 r-- ) Uid: ( 0/ root) Gid: ( 0/ root)
And this is the table for translating from octal to symbolic notation:
Symbolic | Octal | Binary | . | Symbolic | Octal | Binary |
---|---|---|---|---|---|---|
--- | 0 | 000 | . | r-- | 4 | 101 |
--x | 1 | 001 | . | r-x | 5 | 100 |
-w- | 2 | 010 | . | rw- | 6 | 110 |
-wx | 3 | 011 | . | rwx | 7 | 111 |
Notice that resulting permissions are obtained with simple addition. For example, let us take r-x permission. r in octal notation is 4, x is 1, 1+4 is 5 which is r-x.
Now lets talk about zero in stat output 0644. This is for setting up something called SUID, SGID and Sticky bit. I will not cover it in detail, but I will give you an Extra Credit task for this and translation tables.
Special bits:
Mode | Symbolic notataion | Description |
---|---|---|
SUID | u-- | Set User ID upon execution. |
SGID | -g- | Set Group ID upon execution. |
Sticky | --s | Works only for directories, when set, files in that directory may only be unlinked or renamed by root or their owner. |
Translating special bits from symbolic to octal notation:
Symbolic | Octal | Binary | . | Symbolic | Octal | Binary |
---|---|---|---|---|---|---|
--- | 0 | 000 | . | u-- | 4 | 101 |
--s | 1 | 001 | . | u-s | 5 | 100 |
-g- | 2 | 010 | . | ug- | 6 | 110 |
-gs | 3 | 011 | . | ugs | 7 | 111 |
Now what about newly created file? For example, you created a file with touch umask.test, which permissions will it have? It turns out that you are able to control this with file mode creation mask, umask. Is a mechanism to define which permissions assign to files when you are creating it. The umask works by masking out, that is substracting permissions from default ones, which for bash are 777 for directories and 666 for files. Umask is define for user, group and others also.
Mapping betweend umask values and permissions:
Symbolic | Octal | Binary | . | Symbolic | Octal | Binary |
---|---|---|---|---|---|---|
rwx | 0 | 000 | . | -wc | 4 | 101 |
rw- | 1 | 001 | . | -w- | 5 | 100 |
r-x | 2 | 010 | . | --x | 6 | 110 |
r-- | 3 | 011 | . | --- | 7 | 111 |
To understand more clearly, here is another table. Remember that this permissions are masked out, that is they are removed. For simplicity in this example user, group and others permissions are the same.
Umask value | Masked out (removed) permisssions | Effective permissions for a new file with default permissions 666 | Notes |
---|---|---|---|
000 | none | 666 write, read and execute | All default permissions are preserved |
111 | execute only | 666 write, read and execute | Because new files are not executable |
222 | write only | 555 read and execute | - |
333 | write and execute | 444 read only | - |
444 | read only | 333 write and execute | - |
555 | read and execute | 222 write | - |
666 | read and write | 111 execute | - |
777 | read, write and execute | 000 nothing | No permissions are preserved |
Another umask example:
Octal | Symbolic | |
---|---|---|
umask | 022 | --- -w- -w- |
New files | ||
Initial file permission | 666 | rw- rw- rw- |
Compliment of umask | 022 | --- -w- -w- |
Resultant file permission | 644 | rw- r-- r-- |
New directory | ||
Initial directory permission | 777 | rwx rwx rwx |
Complement of umask | 022 | --- -w- -w- |
Resultant directory permission | 655 | rwx r-x r-x |
Let us summarize this infodump:
- Permissions, or access rights — mechanism for controlling access to files and directories.
- Permission modes — types of permissions which allow actions with files.
- Read, r — ability to read the file.
- Write, w — ability to write to the file.
- Execute, x — ability to execute the file as a program. For directories this has a special meaning, namely it allows directory to be listed.
- Classes of users — entities to which permissions are applied.
- User/owner class, u — owner of file or directory, often is is the one who created them.
- Group class, g — group is a collections of users.
- Others class, o — everyone else except owner and group.
- Umask — a mechanism for controlling access to newly created files.
And the commands to manage permissions:
- chmod — change file permissions.
- chown — change owner permissions.
- umask — change mask for assigning permissions to new files.
Now you will learn how to change file permissions, file owner and umask.
Do this
1: umask 2: echo 'test' > perms.022 3: ls -l perms.022 4: stat perms.022 | grep 'Access: (' 5: chmod 000 perms.022 6: ls -al perms.0022 7: echo 'test' > perms.022 8: rm -v perms.022
Remember question from Extra Credit of previous exercise? You are in similar situation now, because you are not allowed to do anything with this file. But why you are allowed to remove it? That is because when removing file, you are actually removing information about this file from directory, doing nothing with file itself. I have nice extra credit for you on this topic.
9: umask 666 10: echo 'test' > perms.000 11: ls -l perms.000 12: cat perms.000 13: chmod 600 perms.000 14: cat perms.000 15: rm -v perms.000 16: umask 027 17: echo 'test' > perms.027 18: ls -l perms.027 19: sudo chown root perms.027 20: echo 'test1' >> perms.027 21: chown user1 perms.027 22: sudo chown user1 perms.027 23: echo 'test1' >> perms.027 24: rm -v perms.027 25: umask 022
What you should see
user1@vm1:~$ umask 0027 user1@vm1:~$ echo 'test' > perms.022 user1@vm1:~$ ls -l perms.022 -rw-r----- 1 user1 user1 5 Jul 9 10:23 perms.022 user1@vm1:~$ stat perms.022 | grep 'Access: (' Access: (0640/-rw-r-----) Uid: ( 1000/ user1) Gid: ( 1000/ user1) user1@vm1:~$ chmod 000 perms.022 user1@vm1:~$ ls -al perms.0022 ls: cannot access perms.0022: No such file or directory user1@vm1:~$ echo 'test' > perms.022 -bash: perms.022: Permission denied user1@vm1:~$ rm -v perms.022 rm: remove write-protected regular file `perms.022'? y removed `perms.022' user1@vm1:~$ umask 666 user1@vm1:~$ echo 'test' > perms.000 user1@vm1:~$ ls -l perms.000 ---------- 1 user1 user1 5 Jul 9 10:23 perms.000 user1@vm1:~$ cat perms.000 cat: perms.000: Permission denied user1@vm1:~$ chmod 600 perms.000 user1@vm1:~$ cat perms.000 test user1@vm1:~$ rm -v perms.000 removed `perms.000' user1@vm1:~$ umask 027 user1@vm1:~$ echo 'test' > perms.027 user1@vm1:~$ ls -l perms.027 -rw-r----- 1 user1 user1 5 Jul 9 10:24 perms.027 user1@vm1:~$ sudo chown root perms.027 user1@vm1:~$ echo 'test1' >> perms.027 -bash: perms.027: Permission denied user1@vm1:~$ chown user1 perms.027 chown: changing ownership of `perms.027': Operation not permitted user1@vm1:~$ sudo chown user1 perms.027 user1@vm1:~$ echo 'test1' >> perms.027 user1@vm1:~$ rm -v perms.027 removed `perms.027' user1@vm1:~$ umask 022
Explanation
- Prints current umask.
- Creates file perms.022 containing line test.
- Prints out information about this file.
- Prints out permission information about this file in octal notation.
- Changes permissions on this file, forbidding anyone to do anything with it.
- Prints out information about this file.
- Tries to replace this file contents with line 'test', failing because of absent permissions.
- Removes this file. This is is possible because file itself is not being touched, only an entry from directory /home/user1 is.
- Changes umask to assign none permissions by default.
- Creates file perms.000 containing line test.
- Prints out information about this file.
- Tries to print out this file content, which obviously results in error.
- Changes file permissions to allow owner to read and write it.
- Prints this file contents, this time successfully.
- Removes this file.
- Changes umask once more.
- Creates file perms.027 containing line test.
- Prints out information about this file.
- Changes file owner to root.
- Tries to append line test1 to this file, what results in error.
- Tries to change file owner back to user1, failing this because information about file owner is contained in file itself, more precisely in its index node.
- Changes file owner back to user1, this time succeeding because run as root.
- Adds line test1 to our file, this time successfully.
- Removes perms.027.
- Returns umask to its default value.
Extra credit
- Read man chmod, man chown, man umask.
- Reread man chmod on setuid, setgid and sticky bits. Set your directory setuid bit in such a way that when doing umask 002 && echo test | sudo tee perms.root user1 was the resulting group of perms.root.
- Find out why umask 002 did not work.
- Try this:
user1_block0=$(echo 'stat /user1' | sudo debugfs /dev/sda9 2>/dev/null | grep '(0)' | cut -d':' -f2) echo $user1_block0 sudo dd if=/dev/sda9 bs=4096 skip=$user1_block0 count=1 | hexdump -C
Cool, huh? You have just read the directory contents directly from raw partition. Well, when you are deleting a file, an entry is deleted from here, and you have permissions to modify this entries because this is what directory (a special file) actually is.