CWE-560, Use of umask() with chmod-style Argument, is a C bug about reading the wrong manual. MITRE says the product calls umask() with an incorrect argument that is specified as if it were an argument to chmod().
How it happens
The two calls take permission numbers, but they mean opposite things. With chmod(), the number says which permissions to grant. With umask(), the number says which permissions to remove from files created afterwards.
A developer wants new files to be private, owner only. Thinking in chmod terms, they write 0600:
/* Vulnerable: 0600 as a mask removes owner read/write, leaves group and others open */
umask(0600);
int fd = open("secrets.dat", O_CREAT | O_WRONLY, 0666);
The mask 0600 strips the owner's read and write bits and leaves group and others untouched. The file ends up with group and world permissions and without owner access, the opposite of the intent. Most callers want the mask that removes group and other access:
/* Fixed: mask out group and other bits */
umask(0077);
int fd = open("secrets.dat", O_CREAT | O_WRONLY, 0600);
What an attacker gains
MITRE lists confidentiality, integrity and access control effects: reading and modifying files or directories, and bypassing a protection mechanism. Files meant to be private can be readable or writable by other local users.
How to find it
MITRE suggests the simplest check: if you suspect misuse, use grep to spot calls to umask().
grep -rn "umask" src/
Then read each argument. A value that looks like a permission you want to keep, such as 0600 or 0644, deserves suspicion. After running the program, check the real permissions on files it creates with ls -l.
How to fix it
MITRE's mitigation: use umask() with the correct argument.
- Think of the argument as the bits to remove, not the bits to grant.
- Use a restrictive mask such as 0077 for files that hold private data.
- Set explicit modes when creating sensitive files, and test the result.
- Add a test that checks the permissions of created files.
Quick check
What does umask(0022) do to a file created with mode 0666?
It removes the group and other write bits, leaving 0644.