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)
