DevTools Hub

Search tools

Search for a developer tool

umask Explained

Part of the Linux Security Toolkit

Create a new file on Linux and it doesn't start with no permissions at all, or with every permission granted — it starts with whatever umask says. Most people never touch it and never need to, until a shared directory turns out to be unexpectedly writable by everyone, or a script's output files land group-unreadable when they needed to be shared. This post covers what umask actually does, the arithmetic behind it, and where it fits alongside chmod rather than replacing it.

The problem umask solves

Every time a program creates a file — a text editor saving a document, a script writing a log, a compiler producing an object file — the operating system needs to decide what permissions that new file gets before anyone has a chance to run chmod on it. Leaving that decision entirely to each individual program would be inconsistent and insecure by default; umask is the single, session-wide setting that answers it uniformly, for every program, without each one needing its own permission logic.

The starting point: 666 and 777

Before umask is applied at all, a newly created file starts from a maximum of 666 (rw-rw-rw-) — readable and writable by everyone, but never executable, regardless of umask. A newly created directory starts from 777 (rwxrwxrwx), since a directory needs its execute bit (the ability to be entered) to be useful at all, so nothing is withheld from the starting point the way execute is for files.

umask is then subtracted from that starting point, bit by bit: result = max & ~umask. It can only remove permissions the maximum already offered — it can never add a bit that wasn't already available, which is exactly why a file's execute bit can never be turned on by umask alone, no matter what value you set.

Working through the standard example

The most common default, umask 022, broken down digit by digit:

      max (files)   umask   result
owner    rw-  (6)      0     rw-  (6)   → unchanged
group    rw-  (6)      2     r--  (4)   → write removed
other    rw-  (6)      2     r--  (4)   → write removed

Files land at 644 (rw-r--r--) and, applying the same umask to the directory maximum of 777, directories land at 755 (rwxr-xr-x). Owner keeps full access; group and others can read (and, for directories, enter and list) but not write. This single umask value simultaneously determines both outcomes — there's no separate file-umask and directory-umask, just one value interpreted against two different starting points.

A quick-reference table

umask   Files   Directories   Typical use
022     644     755           Common default — group/others can read, not write
002     664     775           Shared group collaboration — group can also write
027     640     750           Group can read, others get nothing
077     600     700           Private — nobody but the owner gets any access
000     666     777           No restriction at all — rarely what you actually want

Moving down this table, notice the same relationship holds every time: whatever bits umask removes from the file result, it removes the corresponding read/write bits from the directory result too — the two are never independent, since they come from the same umask value applied to two different (but related) maximums.

Why reversing the calculation needs both values

Going the other direction — "I want files at 644, what umask do I set?" — has a subtlety worth understanding rather than just plugging into a calculator. Since files never carry an execute bit, a desired file permission alone doesn't reveal what umask's execute-bit component was, even though that component still fully determines the resulting directory permission. Working from a desired directory permission avoids the ambiguity, since 777 has no missing bits to obscure anything — which is why a correct reverse calculator needs both a desired file and a desired directory value to check for internal consistency, rather than deriving one from the other and guessing at the rest.

Checking the current value

Running umask alone at a prompt prints the current session's value in octal — the same three-digit form this post has been working with. A second form, umask -S, prints it symbolically instead, but with an important twist worth not confusing with a normal permission string: it shows what's allowed at each position, not what's removed — the inverse of how umask's own octal digits work. umask 022 and umask -S showing u=rwx,g=rx,o=rx describe the identical setting; the second is just phrased as a grant rather than a subtraction, which is worth knowing so it isn't mistaken for a file's actual permission string when it shows up in a script's output.

Where umask actually gets set

Running umask alone at a shell prompt shows the current session's value; running umask 022 changes it, but only for that shell and anything it subsequently launches — closing the terminal reverts to whatever was set before. A persistent, login-wide default belongs in a shell startup file:

# ~/.bashrc or ~/.profile — applies to one user
umask 022

# /etc/profile — applies system-wide, to every login

Some services and daemons set their own umask independently of any shell configuration — worth checking specifically for anything that writes files other accounts need to read, since a service running under a restrictive inherited umask can silently produce files nobody else can access.

umask vs. chmod: two different moments

The two are easy to conflate since both ultimately produce a permission value, but they act at different times: umask decides the default the instant a file is created; chmod changes the permissions of a file that already exists, whenever you run it. Setting umask 077 does nothing at all to files created before that point — it only changes what happens going forward. For working directly with an existing file's permissions rather than the default new ones get, Linux Permissions Calculator and chmod Command Generator cover that separate job.

Common mistakes

  • Setting umask 000 to make a permission error go away. Exactly the same class of mistake as chmod 777 — it removes the restriction that was probably protecting something, rather than fixing whatever actually caused the error.
  • Assuming umask retroactively fixes existing files. It only affects files created after the change; anything already on disk needs an explicit chmod pass.
  • Forgetting umask is inherited, not directory-specific. A restrictive umask set in one shell session doesn't follow a file into a shared directory on its own — combining it with the setgid bit on that directory is the usual way to get consistent group ownership regardless of who creates a file there.
  • Assuming a cron job or a systemd service inherits your interactive umask. Scheduled and system-managed processes often run with their own separate default (frequently the stricter 022 or even 077, regardless of whatever a user has set in their own shell), which is a common reason a script's output files land with different permissions when run manually versus when run on schedule.

FAQ

Is umask a security setting or just a convenience default?

Both — it's a convenience in that it saves running chmod after every file creation, and a real security control in that a permissive umask (000 or 002) on a multi-user system means every new file is readable, and sometimes writable, by accounts that have no reason to touch it, from the moment it's created.

Does umask affect files that already exist?

No — it only applies at the moment of creation. Changing umask has no effect on any file or directory that already exists; use chmod to change those directly.

Why do some systems default to 022 and others to 002?

022 is the more common default and assumes files shouldn't be group-writable unless explicitly made so. 002 is more common on systems designed around shared group collaboration — a development server where a whole team's account belongs to one group and needs to edit each other's files by default.

Can umask be set per-directory instead of per-session?

Not directly — umask is a per-process setting inherited by child processes, not a per-directory attribute. For a shared directory where every file should land with a specific group and permissions regardless of who creates it, the setgid bit on the directory (which controls group inheritance) combined with a suitable umask is the usual combination, rather than trying to make umask itself directory-specific.

Why does umask use subtraction instead of just stating the permissions directly?

Historically, umask needed to work uniformly regardless of what a given program requested at creation time — a permissive mask subtracted from whatever the program asked for reliably restricts it further, without needing every program to know about the administrator's preferred default. It's an older design than more modern per-directory ACL systems, but it's simple, universal, and still the mechanism every Unix-like system relies on.

Try it yourself

umask Calculator runs every calculation in this post — umask to resulting permissions, and back — entirely in your browser. For how umask fits into the bigger picture, see Linux Security.

Related tools