umask Fun Times With WSL
Updated:
Recently, I noticed that the ls colour output of my directories was strange.
ls uses use different colours and formatting to denote file attributes:
- Symlinks
- Sticky bit
- Directories vs. files
- Executables
This is set with the
LS_COLORSenvironment variable.
What I noticed was that every directory was executable.
Meaning that other has permission to ‘execute’ on the directory, which is unusual for home dir subdirectories.
My initial guess was that I botched a chown command at some point in time.
Or a malicious script I ran did so.
I sanity checked this by running mkdir to create a new directory and noticed the permissions were already set by
default.
This is a big clue!
This means it’s related to umask.
What is umask
umask is a bit mask that’s applied to turn off permissions.
I don’t know why it’s a bit mask, instead of simply default permissions.
I bet it has to do with historical reasons. AKA a half-complete hack that ended up sticking.
Octal permissions of 777 means read, write, and execute for owner, group, and all others. Applying a bit mask will reduce permissions. The common setting on many Linux distros is 022, which removes write permissions from group and others.
Bug in WSL
There’s a bug in WSL implementation that doesn’t call /bin/login, which
is how umask is set.
It’s a bit disappointing that this bug has existed for 2 years. Windows has enough hurdles as it is, with respect to using it as a unix-like development environment.
There’s a fix in the ticket somewhere.
Something that involves changing the default user to root and running /bin/login or something.
But I really don’t feel in spending time for a band-aid solution to a band-aid.
Maybe one day, it’ll be magically fixed upstream.
Fix
umask is only set for the current shell.
Changing the value of umask won’t change the behaviour of processes.
Shell-specific settings can be set in config.fish.
But in this particular case, we want to apply this fix for all users.
I added this snippet to /etc/fish/config.fish:
if not string match '??22' (umask)
umask 0022
end