From owner-freebsd-bugs@FreeBSD.ORG Wed Jun 7 21:31:58 2006 Return-Path: X-Original-To: freebsd-bugs@hub.freebsd.org Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id A01F516EEB7 for ; Wed, 7 Jun 2006 19:20:25 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id E1DD243D58 for ; Wed, 7 Jun 2006 19:20:24 +0000 (GMT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.13.4/8.13.4) with ESMTP id k57JKO2O056026 for ; Wed, 7 Jun 2006 19:20:24 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.13.4/8.13.4/Submit) id k57JKOEi056025; Wed, 7 Jun 2006 19:20:24 GMT (envelope-from gnats) Date: Wed, 7 Jun 2006 19:20:24 GMT Message-Id: <200606071920.k57JKOEi056025@freefall.freebsd.org> To: freebsd-bugs@FreeBSD.org From: Martin Kammerhofer Cc: Subject: Re: bin/88365: resubmission of MTA mangled PR X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: Martin Kammerhofer List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 07 Jun 2006 21:31:58 -0000 The following reply was made to PR bin/88365; it has been noted by GNATS. From: Martin Kammerhofer To: dada@sbox.tugraz.at Cc: Subject: Re: bin/88365: resubmission of MTA mangled PR Date: Wed, 7 Jun 2006 19:02:12 +0200 >Submitter-Id: current-users >Originator: Martin Kammerhofer >Organization: Graz Uni >Confidential: no >Synopsis: [patch] /bin/rm has problems with symbolic link flags >Severity: non-critical >Priority: medium >Category: bin >Class: sw-bug >Release: FreeBSD 6.1-STABLE i386 >Environment: System: FreeBSD Martin.liebt.Susi 6.1-STABLE FreeBSD 6.1-STABLE #2: Fri Jun 2 14:53:34 CEST 2006 toor@Martin.liebt.Susi:/usr/obj/usr/src/sys/P2B-S i386 >Description: The FreeBSD /bin/rm silently overrides the UF_APPEND|UF_IMMUTABLE flags when running as super user. This should be documented in the rm(1) manual page. Since FreeBSD 5.X and later have gotten lchflags(2) support, semantics are slightly broken. While standards dictate that rm(1), unlink(2) and rename(2) never follow symbolic links, the FreeBSD /bin/rm _does_ sometimes follow symbolic links inside the implicit chflags(2) call. This leads to the following behaviour: (1) /bin/rm operating as super user cannot remove a symbolic link which has UF_APPEND|UF_IMMUTABLE != 0. (2) /bin/rm when running as super user and failing to unlink a UF_APPEND|UF_IMMUTABLE protected symbolic link will reset the UF_APPEND and UF_IMMUTABLE flags on the symbolic links target - an object that /bin/rm must not change! Imho (1) is a nuisance while I consider (2) broken behaviour. /usr/bin/find ... -delete behaves like /bin/rm. pkg_add has a similar issue when creating backup files. Finally /bin/cp -Rp should be made aware of lchflags(2) (Patch fragment below is similar to the slightly more verbose patch in PR bin/90823) >How-To-Repeat: su touch myfile ln -s myfile myslink chflags -h uchg myfile myslink ls -lo myfile myslink rm -f myslink # fails and modifies myfile instead ls -lo myfile myslink cp -Rp myslink myslink2 # fails to copy uchg flag (ENOSYS!) ls -lo myslink* >Fix: Note: When creating the patch below I was not aware of PR kern/29355. It turns out that my patch is a small subset of the PR 29355 userland part. 29355 is 4 years old now and most of its functionality is already in the tree. My patch catches up on the still missing "s/chflags/lchflags/"-parts. It is against --current. Index: bin/cp/utils.c =================================================================== RCS file: /home/ncvs/src/bin/cp/utils.c,v retrieving revision 1.46 diff -u -t -r1.46 utils.c --- bin/cp/utils.c 5 Sep 2005 04:36:08 -0000 1.46 +++ bin/cp/utils.c 5 Jun 2006 10:55:29 -0000 @@ -321,7 +321,7 @@ if (!gotstat || fs->st_flags != ts.st_flags) if (fdval ? fchflags(fd, fs->st_flags) : - (islink ? (errno = ENOSYS) : + (islink ? lchflags(to.p_path, fs->st_flags) : chflags(to.p_path, fs->st_flags))) { warn("chflags: %s", to.p_path); rval = 1; Index: bin/rm/rm.c =================================================================== RCS file: /home/ncvs/src/bin/rm/rm.c,v retrieving revision 1.54 diff -u -t -r1.54 rm.c --- bin/rm/rm.c 15 Apr 2006 09:26:23 -0000 1.54 +++ bin/rm/rm.c 5 Jun 2006 10:47:38 -0000 @@ -231,7 +231,7 @@ else if (!uid && (p->fts_statp->st_flags & (UF_APPEND|UF_IMMUTABLE)) && !(p->fts_statp->st_flags & (SF_APPEND|SF_IMMUTABLE)) && - chflags(p->fts_accpath, + lchflags(p->fts_accpath, p->fts_statp->st_flags &= ~(UF_APPEND|UF_IMMUTABLE)) < 0) goto err; continue; @@ -250,7 +250,7 @@ if (!uid && (p->fts_statp->st_flags & (UF_APPEND|UF_IMMUTABLE)) && !(p->fts_statp->st_flags & (SF_APPEND|SF_IMMUTABLE))) - rval = chflags(p->fts_accpath, + rval = lchflags(p->fts_accpath, p->fts_statp->st_flags &= ~(UF_APPEND|UF_IMMUTABLE)); if (rval == 0) { /* @@ -350,7 +350,7 @@ if (!uid && (sb.st_flags & (UF_APPEND|UF_IMMUTABLE)) && !(sb.st_flags & (SF_APPEND|SF_IMMUTABLE))) - rval = chflags(f, sb.st_flags & ~(UF_APPEND|UF_IMMUTABLE)); + rval = lchflags(f, sb.st_flags & ~(UF_APPEND|UF_IMMUTABLE)); if (rval == 0) { if (S_ISWHT(sb.st_mode)) rval = undelete(f); Index: usr.bin/find/function.c =================================================================== RCS file: /home/ncvs/src/usr.bin/find/function.c,v retrieving revision 1.55 diff -u -t -r1.55 function.c --- usr.bin/find/function.c 3 Apr 2006 20:36:37 -0000 1.55 +++ usr.bin/find/function.c 5 Jun 2006 11:05:26 -0000 @@ -439,7 +439,7 @@ if ((entry->fts_statp->st_flags & (UF_APPEND|UF_IMMUTABLE)) && !(entry->fts_statp->st_flags & (SF_APPEND|SF_IMMUTABLE)) && geteuid() == 0) - chflags(entry->fts_accpath, + lchflags(entry->fts_accpath, entry->fts_statp->st_flags &= ~(UF_APPEND|UF_IMMUTABLE)); /* rmdir directories, unlink everything else */ Index: usr.sbin/pkg_install/add/extract.c =================================================================== RCS file: /home/ncvs/src/usr.sbin/pkg_install/add/extract.c,v retrieving revision 1.44 diff -u -t -r1.44 extract.c --- usr.sbin/pkg_install/add/extract.c 7 Jan 2006 22:10:57 -0000 1.44 +++ usr.sbin/pkg_install/add/extract.c 5 Jun 2006 12:40:05 -0000 @@ -63,8 +63,7 @@ if (q->type == PLIST_FILE) { snprintf(try, FILENAME_MAX, "%s/%s", dir, q->name); if (make_preserve_name(bup, FILENAME_MAX, name, try) && fexists(bup)) { - (void)chflags(try, 0); - (void)unlink(try); + (void)lchflags(try, 0); if (rename(bup, try)) warnx("rollback: unable to rename %s back to %s", bup, try); } @@ -160,7 +159,7 @@ /* first try to rename it into place */ snprintf(try, FILENAME_MAX, "%s/%s", Directory, p->name); if (fexists(try)) { - (void)chflags(try, 0); /* XXX hack - if truly immutable, rename fails */ + (void)lchflags(try, 0); /* XXX hack - if truly immutable, rename fails */ if (preserve && PkgName) { char pf[FILENAME_MAX];