misc/131999: chflags: unable to unset flags on symlinks when link
target exists
Deomid Ryabkov
myself at rojer.pp.ru
Sun Feb 22 23:30:05 PST 2009
>Number: 131999
>Category: misc
>Synopsis: chflags: unable to unset flags on symlinks when link target exists
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Mon Feb 23 07:30:03 UTC 2009
>Closed-Date:
>Last-Modified:
>Originator: Deomid Ryabkov
>Release: 7.1-PRERELEASE #0: Mon Sep 8 14:15:33 MSD 2008
>Organization:
>Environment:
FreeBSD xxx 7.1-PRERELEASE FreeBSD 7.1-PRERELEASE #0: Mon Sep 8 14:15:33 MSD 2008 rojer at xxx:/usr/obj/usr/src/sys/GENERIC amd64
>Description:
# ls -lo logs
lrwxr-xr-x 1 root www-rojer schg 17 Sep 16 2006 logs -> /logs/rojer
# ls -ldo /logs/rojer
drwxr-x--- 2 root www-rojer - 512 Feb 23 09:59 /logs/rojer
# chflags -h noschg logs
# ls -lo logs
lrwxr-xr-x 1 root www-rojer schg 17 Sep 16 2006 logs -> /logs/rojer.pp.ru
i. e. nothing happened
truss of chflags reveals the problem: usage of stat() where lstat() should have been used.
# truss chflags -h noschg logs
[...]
stat("logs",{ mode=drwxr-x--- ,inode=22303757,size=512,blksize=4096 }) = 0 (0x0)
process exit, rval = 0
this way, lchflags(2) is never actually called because chflags(3) doesn't think it is necessary.
>How-To-Repeat:
create a symlink pointing to an existing flagless entry (this is important),
use chfalgs -h to set flags on the symlink - this one succeeds.
then try chflags -h to remove the flag you just set - this one fails, because stat(2) returns information on the entry symlink points at that does not have the flag.
>Fix:
i had a glance at bin/chflags/chflags.c and it seems to be using fts_* functions to traverse the tree. somehow those need to be told to use lstat to return information, when appropriate.
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list