132

Let's say you have this structure:

+ directory
-- file1
-- file2
-- file3 -> /tmp/file3

file3 is a link to another file3 somewhere else on the system.

Now let's say I chmod 777 the directory and all contents inside it. Does my file3 in /tmp receive those permissions? Also, let's say we have the same situation but reversed.

/tmp/file3 -> /directory/file3

If I apply the permissions on the file being linked to, how does that effect the link?

2
  • 1
    Permissions only affect the file, not the symlink.
    – baraboom
    Jun 27, 2011 at 21:12
  • N.B. above comment does not quite apply to macOS, see answer from @astralblue below for the surprising behaviour there Jun 9, 2022 at 14:12

4 Answers 4

127

It depends on how you call chmod and the platform you are running on.

For example, on a Linux system, man chmod says this:

chmod never changes the permissions of symbolic links; the chmod system call cannot change their permissions. This is not a problem since the permissions of symbolic links are never used. However, for each symbolic link listed on the command line, chmod changes the permissions of the pointed-to file. In contrast, chmod ignores symbolic links encountered during recursive directory traversals.

However, on a Mac, chmod can be used to modify the permissions of a symbolic link using options such as this (from man chmod):

-h If the file is a symbolic link, change the mode of the link itself rather than the file that the link points to.

For the sake of example, lets assume you are on a Linux machine for the rest of this answer.

If in the first case you run chmod -R 777 directory to recursively change the permissions, the link target will not be affected, but if you do chmod 777 directory/*, it will.

If you change the permissions on the link target directly, those permissions will carry through (since as man page and baraboom say, the actual link permissions aren't used for anything).


Test log for illustration:

$ mkdir dir && touch dir/file{1,2} /tmp/file3 && ln -s {/tmp,dir}/file3
$ ls -l dir/* /tmp/file3
-rw-r--r-- 1 user group  0 2011-06-27 22:02 /tmp/file3
-rw-r--r-- 1 user group  0 2011-06-27 22:02 dir/file1
-rw-r--r-- 1 user group  0 2011-06-27 22:02 dir/file2
lrwxrwxrwx 1 user group 10 2011-06-27 22:02 dir/file3 -> /tmp/file3

$ chmod -R 777 dir && ls -l dir/* /tmp/file3
-rw-r--r-- 1 user group  0 2011-06-27 22:02 /tmp/file3
-rwxrwxrwx 1 user group  0 2011-06-27 22:02 dir/file1
-rwxrwxrwx 1 user group  0 2011-06-27 22:02 dir/file2
lrwxrwxrwx 1 user group 10 2011-06-27 22:02 dir/file3 -> /tmp/file3

$ chmod 700 dir/* && ls -l dir/* /tmp/file3
-rwx------ 1 user group  0 2011-06-27 22:02 /tmp/file3
-rwx------ 1 user group  0 2011-06-27 22:02 dir/file1
-rwx------ 1 user group  0 2011-06-27 22:02 dir/file2
lrwxrwxrwx 1 user group 10 2011-06-27 22:02 dir/file3 -> /tmp/file3
4
  • 5
    That was a surprise to me too. Next question: who do the permissions on a symlink mean? Jun 22, 2016 at 1:59
  • 3
    @EdwardFalk symlink permissions are not non-restrictive since everything needs to be able to traverse it to get the permissions from the linked file.
    – Walf
    Mar 22, 2017 at 3:31
  • why do permissions on /tmp/file3 change in your last/third section?
    – nmz787
    Mar 8, 2023 at 22:57
  • That happened because of the sentence in the quoted man page, However, for each symbolic link listed on the command line, chmod changes the permissions of the pointed-to file. The second chmod was given a symlink, /dir/file3, so it changed the mode of the target, /tmp/file3.
    – Jim
    Apr 4, 2023 at 21:48
18

baraboom's and peth's answers are both correct: Permission bits on the symbolic links themselves are irrelevant (except on macOS; see below), and changing permission on a symbolic link – by the chmod command-line tool or by the chmod() system call – will simply act as if it was performed against the target of the symbolic link.

To quote the SUSv4/POSIX.1-2008 description of symlink() system call:

The values of the file mode bits for the created symbolic link are unspecified. All interfaces specified by POSIX.1-2008 shall behave as if the contents of symbolic links can always be read, except that the value of the file mode bits returned in the st_mode field of the stat structure is unspecified.

Here, “unspecified” leaves room of interpretation for each implementation. Specifics:

  • On Linux (tested using ext4fs), stat() returns st_mode=0777, no matter what the umask was when the symlink was created; ls -l therefore always displays lrwxrwxrwx for symbolic links.
  • On macOS (HFS) and FreeBSD (both UFS and ZFS), a symbolic link does have its own permission: The chmod -h command noted above can change this link permission (which internally uses a non-POSIX lchown() system call to achieve this), and the stat() system call returns this value for st_mode.

Symbolic links on Linux and FreeBSD can always be followed, as specified by POSIX. In particular, on FreeBSD, this means that the file mode of a symbolic link has no effect at all on access control.

On the other hand, macOS slightly breaks POSIX. Although a symbolic link can be followed regardless its read permission, readlink() fails with EACCES (Permission denied) if the user does not have read permission:

$ sudo ln -shf target symlink
$ sudo chmod -h 444 symlink
$ ls -l symlink
lr--r--r--  1 root  staff  1 Mar 14 13:05 symlink -> target
$ sudo chmod -h 000 symlink
$ ls -l symlink

ls: symlink: Permission denied
l---------  1 root  staff  1 Mar 14 13:05 symlink
$ echo kthxbye > target
$ cat symlink
kthxbye

(Note that the -> target portion is missing in the output from the second ls -l command, and that cat symlink still succeeded and printed the contents of the target file even though the user did not have read permission on symlink.)

NetBSD apparently offers a special mount option named symperm which, if set, causes symbolic link read/execute permissions to control readlink() and link traversal.

1
  • 1
    Double +1 for exposing this very surprising symlink permission behaviour on macOS -- had to confirm this for myself just now: on a symlink with restrictive permissions, the user cannot resolve the symlink, but can still use it to read and write to the target file! Jun 9, 2022 at 14:09
0

The following answer is about permissions implied ownership rather than read/write/exec permission bits.

While the permission bits on a symbolic link may not matter, the ownership is important in the case of a sticky-bit directory where everyone can create files such as, oh, /tmp.

Alice can create a symlink in /tmp, edit it and remove it:

alice@~ $ ln -sf /whatever /tmp/mylink
alice@~ $ ln -sf /whatever-else /tmp/mylink

But user Bob cannot replace or remove Alice's link (tested on Linux):

bob@~ $ rm /tmp/mylink
rm: cannot remove /tmp/mylink: Operation not permitted

If Bob could do this, Bob could perpetrate an attack against Alice's resolution of the /tmp/mylink path that Alice trusts to be as created.

Normally, removing an object depends on having directory permissions. This applies to symlinks. Bob certainly can remove a symlink owned by Alice in a directory that is writable to Bob, which doesn't have the sticky bit.

-3
  1. drop the link file (after ensuring it is not used by any process)
  2. set umask such a way that the 777-umask=required file permissions
  3. create the link file afresh
1
  • 6
    How does this answer the question?
    – jww
    Jan 20, 2016 at 5:00

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .