A protest sign that says 'Civil disobedience requires no permission slip'.
Photo attribution here.

Throughout my write-up on how RBENV works, I perform multiple experiments where I create an executable file which replicates specific behavior in the codebase. But in order to actually run the program I've written, I first have to modify the program's file to be executable, since it's not executable by default.

I did this by using the chmod terminal command, for example chmod +x (filename). This was a necessary step every time I created a new file that I planned to execute.

After doing this enough times, I started to ask myself why it's even necessary to do this. After all, I'm the person who created this file. Shouldn't I be able to execute my own file on my own laptop? I couldn't find an answer to this question from Google, so I did some research to find out.

UNIX was designed to be multi-user

I started by asking a question on StackOverflow. The question I asked involves a command called umask which isn't super-important here. The gist of my question, which you can see in the comments below this answer, is "Why can't a file's creator execute a file without jumping through chmod hoops?" The person who responded wrote:

Because most files are data, and this is generally safer in the unknown broader context. The folk designing the system built it to be easy for me to do quick scripting work, especially on a dedicated private machine, but also easy for sysadmins to manage if the machine is a highly networked production system where very few people should be creating new scripts. When in doubt, a more conservative decision is safer, and the risk tolerances of end users vary wildly.

The rest of the comment thread is worth reading as well. TL;DR- UNIX was designed to be handle multiple users on the same system, so it needs to account for the scenario where a user gains access to a system that they shouldn't have access to, and writes a malicious script that they then try to execute.

The mechanism which prevents this from happening is the UNIX requirement that files are non-executable by default. Unless the malicious user has somehow granted themselves sysadmin privileges, they won't have permission to execute the script without authorization from the system's administrator. This, in a nutshell, is why we have to chmod our scripts every time.

How to read a file's permissions

File permissions are divided into 3 different categories- one for the file's owner, one for the group that the user belongs to, and one for everybody else. The +x flag for chmod actually updates the executable permissions for all 3 of those groups, not just for the file's creator. We can see this in action by running an experiment.

In a scratch / sandbox directory, we can create a new file called "foo", then inspect its permissions:

$ rm foo
$ touch foo
$ ls -la foo
-rw-r--r--  1 richiethomas  staff  0 Jan 31 09:54 foo
$ 

The thing we want to focus on in this output is the -rw-r--r-- section. According to this source, the first - (i.e. the - in -rw) means that what we're looking at are file permissions, not directory permissions.

If the reverse were true, we would see a leading d (i.e. drw) instead of -rw. We can see that by creating a directory as well:

$ mkdir bar
$ ls -la
total 0
drwxr-xr-x  4 richiethomas  staff  128 Jan 31 09:56 .
drwxr-xr-x  6 richiethomas  staff  192 Jan 11 10:35 ..
drwxr-xr-x  2 richiethomas  staff   64 Jan 31 09:56 bar
-rw-r--r--  1 richiethomas  staff    0 Jan 31 09:54 foo
$ 

Here we see that the bar/ directory's permissions line starts with d, unlike that of the foo file.

Characters 2-4 (i.e. rw- for the foo file) represent the permissions for the file's creator. Characters 5-7 (r–) are for users in the same user group as the file's creator, and characters 8-10 (also r–) are for everyone else. In each of these bunches of 3 characters, r means that group can read the file, w means they can write to it, and x means they can execute it.

Experiment- updating a file's permissions

Let's run chmod +x foo and then re-run ls -l foo:

$ chmod +x foo
$ ls -la foo
-rwxr-xr-x  1 richiethomas  staff  0 Jan 31 09:54 foo
$ 

We see that the file permissions line has changed from -rw-r--r-- to -rwxr-xr-x. Now each permissions category has x (i.e. executable permissions) turned on.

We can also set permissions in a more granular manner, for example only changing permissions for the file's owner, their user group, etc. To do this, we can use chmod in a bitwise fashion, passing numbers instead of +x or similar arguments. We pass a sequence of 3 numbers:

  • The 1st number stands for the permissions we'll give to the creator.
  • The 2nd number stands for the permissions we'll give to group members.
  • The 3rd number stands for the permissions we'll give to others.

The number 1 in any of the 3 positions means we're granting execution permissions. Passing the number 2 means we're granting write permissions, and 4 means we're granting read permissions. Passing the number 0 means we're revoking all permissions. If we want to grant a combination of these permissions, we just add the representative numbers together.

For example, suppose we wanted to turn on execution-only permissions to the foo file's creator, and revoke permissions for everyone else. We can call chmod 100 foo, like so:

$ ls -la foo
-rwxr-xr-x  1 richiethomas  staff  0 Jan 31 09:54 foo
$ chmod 100 foo
$ ls -la foo
---x------  1 richiethomas  staff  0 Jan 31 09:54 foo
$ 

Above, we see the "before" and "after" states of our foo file.

Now let's say we want to grant all 3 permissions to the creator, but only read and write permissions to group members and others. We'd run chmod 766 foo, like so:

$ ls -la foo
---x------  1 richiethomas  staff  0 Jan 31 09:54 foo
$ chmod 766 foo
$ ls -la foo
-rwxrw-rw-  1 richiethomas  staff  0 Jan 31 09:54 foo
$ 

Again, we see the "before" and "after" states of foo.

Photo Attribution

Title: Civil Disobedience requires no permission slip - #climatestrike Melbourne IMG_3459

Author: John Englart

Source: Flickr

License: CC BY-SA 2.0 DEED Attribution-ShareAlike 2.0 Generic


Description:

As part of the movement started by 15 year old Swedish student Greta Thundberg for ramping up climate action, thousands of students around Australia and in Melbourne rallied and marched on November 30, 2018. The Melbourne protest had several thousand students and adult supporters attending and was full of energy, music, chanting, and lots of home-made placards and signs. Towards the end of a march through the city streets some students decided to sitdown on the road and tram tracks on Spring Street in front of the Victorian Parliament and maintained their position for 40 minutes before deciding to move to the end point in the Treasury Gardens.