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_COLORS
environment 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