~6 min read|
With macOS Catalina, Apple made zsh the default shell. That’s all well and good since I have been using zsh for a while now.
However, in getting a new machine setup, I started getting an error every time I opened a new terminal:
zsh compinit: insecure directories, run compaudit for list. Ignore insecure directories and continue [y] or abort compinit [n]?
y isn’t hard, but it certainly didn’t feel right that I should have to. So, I started looking around the internet to find an answer.
Plenty of others have had this issue before, though the reason for it surprised me: write privileges for the directories in question.
Wesley Moore beat me to the investigation and has a good write up of the on his blog.
compinit, I found it in the
compsys part of the manual. As the name suggests (in retrospect, this is clearer),
compinit is the standard way that the shell is initialized.
The error has to do with a security check (emphasis mine):
For security reasons
compinitalso checks if the completion system would use files not owned by root or by the current user, or files in directories that are world- or group-writable or that are not owned by root or by the current user. If such files or directories are found,
compinitwill ask if the completion system should really be used. To avoid these tests and make all files found be used without asking, use the option
-u, and to make
compinitsilently ignore all insecure files and directories use the option
-i. This security check is skipped entirely when the
-Coption is given.
The security check can be retried at any time by running the function
compaudit. This is the same check used by
compinit, but when it is executed directly any changes to
fpathare made local to the function so they do not persist. The directories to be checked may be passed as arguments; if none are given,
_compdirto find completion system directories, adding missing ones to fpath as necessary. To force a check of exactly the directories currently named in
_compdirto an empty string before calling
That seems to describe the error I’m getting, which begs the question - which directories are owned by the root / current user but are world- or group-writable?
Running the audit:
$ compaudit There are insecure directories: /usr/local/share/zsh/site-functions /usr/local/share/zsh
Investigating those directories in particular:
$ ls -la /usr/local/share total 0 drwxrwxr-x 9 stephen admin 288 Mar 12 09:31 . drwxr-xr-x 14 root wheel 448 Mar 11 17:40 .. -rw-r--r-- 1 stephen admin 0 Mar 12 09:27 .keepme drwxr-xr-x 5 stephen admin 160 Mar 12 09:31 doc drwxr-xr-x 3 stephen admin 96 Mar 11 17:43 fish drwxr-xr-x 6 stephen admin 192 Mar 12 09:31 man drwxr-xr-x 19 stephen admin 608 Mar 12 09:28 postgresql lrwxr-xr-x 1 stephen admin 38 Mar 12 09:31 systemtap -> ../Cellar/node/13.10.1/share/systemtap drwxrwxr-x 3 stephen admin 96 Mar 11 17:40 zsh $ ls -la /usr/local/share/zsh total 0 drwxrwxr-x 3 stephen admin 96 Mar 11 17:40 . drwxrwxr-x 9 stephen admin 288 Mar 12 09:31 .. drwxrwxr-x 4 stephen admin 128 Mar 11 17:43 site-functions
Only the directories listed in the audit were writable in the user group. (For a quick refresher on file permissions in Unix systems, check out my previous post.)
At this point, we know that the permissions of the directories are problematic - a perfect fit for the
the manual entry for
chmod states the following in the
Modes may be absolute or symbolic. […] The symbolic mode is described by the following grammar:
mode ::= clause [, clause ...] clause ::= [who ...] [action ...] action action ::= op [perm ...] who ::= a | u | g | o op ::= + | - | = perm ::= r | s | t | w | x | X | u | g | o The who symbols ‘’u’’, ‘’g’’, and ‘’o’’ specify the user, group, and other parts of the mode bits, respectively. The who symbol ‘’a’’ is equivalent to ‘’ugo''. The perm symbols represent the portions of the mode bits as follows: r The read bits. s The set-user-ID-on-execution and set-group-ID-on-execution bits. t The sticky bit. w The write bits. x The execute/search bits. X The execute/search bits if the file is a directory or any of the execute/search bits are set in the original (unmodi- fied) mode. Operations with the perm symbol ``X'' are only meaningful in conjunction with the op symbol ``+'', and are ignored in all other cases. u The user permission bits in the original mode of the file. g The group permission bits in the original mode of the file. o The other permission bits in the original mode of the file.
If you’ve ever seen
chmod 755, that’s using the absolute to change file modes and access.
Wesley’s ultimate suggestion was a more expressive approach - describing intent instead of relying on magic numbers. He used the symbolic mode to describe his desired output:
$ chmod g-w <target file or directory> […other targets]
That is, for the group (
g) section of the permissions, use the remove operation (
-) for the write (
This was further simplified into a one line command by piping the output into an
As a reminder (from the manual):
xargsutility works by reading “space, tab, newline and end-of-file delimited strings from the standard input” and executing a utility with the strings as arguments.
$ compaudit | xargs chmod g-w
Minor annoyance resolved and I learned more about the
chmod utility in the process!
Hi there and thanks for reading! My name's Stephen. I live in Chicago with my wife, Kate, and dog, Finn. Want more? See about and get in touch!