On Sun, Feb 12, 2017 at 09:53:19PM -0500, Christopher Wellons wrote:
> 
> # touch foo
> # ls -l foo
> -rw-r--r--  1 root  wheel  0 Feb 12 21:50 foo
> # ln -s foo bar
> # ls -l bar
> lrwxr-xr-x  1 root  wheel  3 Feb 12 21:51 bar -> foo
> # chmod go-rwx bar
> # ls -l foo
> -rwx------  1 root  wheel  0 Feb 12 21:50 foo

It was pointed out to me that you gave a more detailed report on reddit,
thanks for persevering: 
https://www.reddit.com/r/openbsd/comments/5uixuu/openbsd_chmod_bug/

I missed the x in the last line of your first report, which is indeed a
bug introduced in chmod.c r1.33.  chflags(1) has a similar problem:

$ touch foo && ln -s foo bar && chflags -h uchg bar && ls -lo
total 0
lrwxr-xr-x  1 theo  wheel  uchg 3 Feb 17 04:13 bar -> foo
-rw-r--r--  1 theo  wheel  -    0 Feb 17 04:13 foo
$ chflags uappnd bar && ls -lo
total 0
lrwxr-xr-x  1 theo  wheel  uchg        3 Feb 17 04:13 bar -> foo
-rw-r--r--  1 theo  wheel  uappnd,uchg 0 Feb 17 04:13 foo

Patch below fixes this, ensuring that without -h flag we use the actual
file's permissions/flags, not the ones of the symlink. For chmod:

260                     if (!fchmodat(AT_FDCWD, p->fts_accpath, oct ? omode :
261                         getmode(set, p->fts_statp->st_mode), atflags)
262                         || fflag)

The problem for chflags is similar and chown is unaffected by this
patch.


Index: chmod.c
===================================================================
RCS file: /var/cvs/src/bin/chmod/chmod.c,v
retrieving revision 1.40
diff -u -p -r1.40 chmod.c
--- chmod.c     19 Oct 2016 18:20:25 -0000      1.40
+++ chmod.c     17 Feb 2017 02:55:25 -0000
@@ -146,8 +146,10 @@ done:
                        fts_options |= FTS_LOGICAL;
                        atflags = 0;
                }
-       } else if (!hflag)
+       } else if (!hflag) {
+               fts_options |= FTS_COMFOLLOW;
                atflags = 0;
+       }
 
        if (ischflags) {
                if (pledge("stdio rpath fattr", NULL) == -1)

Reply via email to