Thanks for all your error reports, I didn't forget it. I'll cleanup my guide soon. Thanks again!

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:

  1. Permissions, or access rights — mechanism for controlling access to files and directories.
  2. Permission modes — types of permissions which allow actions with files.
    1. Read, r — ability to read the file.
    2. Write, w — ability to write to the file.
    3. Execute, x — ability to execute the file as a program. For directories this has a special meaning, namely it allows directory to be listed.
  3. Classes of users — entities to which permissions are applied.
    1. User/owner class, u — owner of file or directory, often is is the one who created them.
    2. Group class, g — group is a collections of users.
    3. Others class, o — everyone else except owner and group.
  4. Umask — a mechanism for controlling access to newly created files.

And the commands to manage permissions:

  1. chmod — change file permissions.
  2. chown — change owner permissions.
  3. 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

  1. Prints current umask.
  2. Creates file perms.022 containing line test.
  3. Prints out information about this file.
  4. Prints out permission information about this file in octal notation.
  5. Changes permissions on this file, forbidding anyone to do anything with it.
  6. Prints out information about this file.
  7. Tries to replace this file contents with line 'test', failing because of absent permissions.
  8. Removes this file. This is is possible because file itself is not being touched, only an entry from directory /home/user1 is.
  9. Changes umask to assign none permissions by default.
  10. Creates file perms.000 containing line test.
  11. Prints out information about this file.
  12. Tries to print out this file content, which obviously results in error.
  13. Changes file permissions to allow owner to read and write it.
  14. Prints this file contents, this time successfully.
  15. Removes this file.
  16. Changes umask once more.
  17. Creates file perms.027 containing line test.
  18. Prints out information about this file.
  19. Changes file owner to root.
  20. Tries to append line test1 to this file, what results in error.
  21. 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.
  22. Changes file owner back to user1, this time succeeding because run as root.
  23. Adds line test1 to our file, this time successfully.
  24. Removes perms.027.
  25. Returns umask to its default value.

Extra credit

  1. Read man chmod, man chown, man umask.
  2. 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.
  3. Find out why umask 002 did not work.
  4. 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.

Discussion

Navigation

Learn Linux The Hard Way