From dada@sbox.tugraz.at  Mon Jun  5 15:16:27 2006
Return-Path: <dada@sbox.tugraz.at>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 49CA516AE3C
	for <freebsd-gnats-submit@freebsd.org>; Mon,  5 Jun 2006 15:16:27 +0000 (UTC)
	(envelope-from dada@sbox.tugraz.at)
Received: from mailrelay1.tu-graz.ac.at (mailrelay.tu-graz.ac.at [129.27.2.202])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 4AEC943D46
	for <freebsd-gnats-submit@freebsd.org>; Mon,  5 Jun 2006 15:16:25 +0000 (GMT)
	(envelope-from dada@sbox.tugraz.at)
Received: from webmail.tugraz.at (webmail.tu-graz.ac.at [129.27.2.204])
	by mailrelay1.tu-graz.ac.at (8.13.6/8.13.6) with ESMTP id k55FGOV8028556
	for <freebsd-gnats-submit@freebsd.org>; Mon, 5 Jun 2006 17:16:24 +0200 (CEST)
Received: from BGSZ103.kfunigraz.ac.at (BGSZ103.kfunigraz.ac.at
	[143.50.30.103]) by webmail.tugraz.at (Horde MIME library) with HTTP; Mon,
	05 Jun 2006 17:16:24 +0200
Message-Id: <20060605171624.q6hcr9s920c4kg0g@webmail.tugraz.at>
Date: Mon, 05 Jun 2006 17:16:24 +0200
From: "Bakk.techn., Martin Kammerhofer" <dada@sbox.tugraz.at>
To: FreeBSD problem reports <freebsd-gnats-submit@freebsd.org>
Subject: [patch] /bin/rm has problems with symbolic link flags

>Number:         98532
>Category:       bin
>Synopsis:       Re: bin/88365: [patch] /bin/rm has problems with symbolic link flags
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Jun 05 15:20:23 GMT 2006
>Closed-Date:    Mon Jun 05 18:19:55 GMT 2006
>Last-Modified:  Mon Jun 05 18:19:55 GMT 2006
>Originator:     =09Martin Kammerhofer
>Release:        =09FreeBSD 6.1-STABLE i386
>Organization:
=09Graz Uni
>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:
=09The FreeBSD /bin/rm silently overrides the UF_APPEND|UF_IMMUTABLE
=09flags when running as super user. This should be documented
=09in the rm(1) manual page.

=09Since FreeBSD 5.X and later have gotten lchflags(2) support, semantics
=09are slightly broken. While standards dictate that rm(1), unlink(2) and
=09rename(2) never follow symbolic links, the FreeBSD /bin/rm _does_
=09sometimes follow symbolic links inside the implicit chflags(2) call.

=09This leads to the following behaviour:
=09(1)=09/bin/rm operating as super user cannot remove a symbolic link
=09=09which has UF_APPEND|UF_IMMUTABLE !=3D 0.
=09(2)=09/bin/rm when running as super user and failing to unlink a
=09=09UF_APPEND|UF_IMMUTABLE protected symbolic link will reset the
=09=09UF_APPEND and UF_IMMUTABLE flags on the symbolic links target
=09=09- an object that /bin/rm must not change!

=09Imho (1) is a nuisance while I consider (2) broken behaviour.

=09/usr/bin/find ... -delete behaves like /bin/rm.

=09pkg_add has a similar issue when creating backup files.

=09Finally /bin/cp -Rp should be made aware of lchflags(2)
=09(Patch fragment below is similar to the slightly more verbose
=09patch in PR bin/90823)

>How-To-Repeat:
=09su
=09touch myfile
=09ln -s myfile myslink
=09chflags -h uchg myfile myslink
=09ls -lo myfile myslink
=09rm -f myslink=09=09=09# fails and modifies myfile instead
=09ls -lo myfile myslink
=09cp -Rp myslink myslink2=09=09# fails to copy uchg flag (ENOSYS!)
=09ls -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 29355=C2=B4s userland part.
29355 is 4 years old now and most of its functionality is already in the tre=
e.
My patch catches up on the still missing "s/chflags/lchflags/"-parts.

Index: bin/cp/utils.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
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=095 Sep 2005 04:36:08 -0000=091.46
+++ bin/cp/utils.c=095 Jun 2006 10:55:29 -0000
@@ -321,7 +321,7 @@
         if (!gotstat || fs->st_flags !=3D ts.st_flags)
                 if (fdval ?
                     fchflags(fd, fs->st_flags) :
-                    (islink ? (errno =3D ENOSYS) :
+                    (islink ? lchflags(to.p_path, fs->st_flags) :
                     chflags(to.p_path, fs->st_flags))) {
                         warn("chflags: %s", to.p_path);
                         rval =3D 1;
Index: bin/rm/rm.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
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=0915 Apr 2006 09:26:23 -0000=091.54
+++ bin/rm/rm.c=095 Jun 2006 10:47:38 -0000
@@ -231,7 +231,7 @@
                         else if (!uid &&
                                  (p->fts_statp->st_flags & (UF_APPEND|UF_IM=
MUTABLE)) &&
                                  !(p->fts_statp->st_flags & (SF_APPEND|SF_I=
MMUTABLE)) &&
-                                 chflags(p->fts_accpath,
+                                 lchflags(p->fts_accpath,
                                          p->fts_statp->st_flags &=3D ~(UF_A=
PPEND|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 =3D chflags(p->fts_accpath,
+                        rval =3D lchflags(p->fts_accpath,
                                        p->fts_statp->st_flags &=3D ~(UF_APP=
END|UF_IMMUTABLE));
                 if (rval =3D=3D 0) {
                         /*
@@ -350,7 +350,7 @@
                 if (!uid &&
                     (sb.st_flags & (UF_APPEND|UF_IMMUTABLE)) &&
                     !(sb.st_flags & (SF_APPEND|SF_IMMUTABLE)))
-                        rval =3D chflags(f, sb.st_flags & ~(UF_APPEND|UF_IM=
MUTABLE));
+                        rval =3D lchflags(f, sb.st_flags & ~(UF_APPEND|UF_I=
MMUTABLE));
                 if (rval =3D=3D 0) {
                         if (S_ISWHT(sb.st_mode))
                                 rval =3D undelete(f);
Index: usr.bin/find/function.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
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=093 Apr 2006 20:36:37 -0000=091.55
+++ usr.bin/find/function.c=095 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() =3D=3D 0)
-                chflags(entry->fts_accpath,
+                lchflags(entry->fts_accpath,
                        entry->fts_statp->st_flags &=3D ~(UF_APPEND|UF_IMMUT=
ABLE));
=20
         /* rmdir directories, unlink everything else */
Index: usr.sbin/pkg_install/add/extract.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
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=097 Jan 2006 22:10:57 -0000=091.44
+++ usr.sbin/pkg_install/add/extract.c=095 Jun 2006 12:40:05 -0000
@@ -63,8 +63,7 @@
         if (q->type =3D=3D 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 immu=
table, rename fails */
+                    (void)lchflags(try, 0);     /* XXX hack - if truly immu=
table, rename fails */
                     if (preserve && PkgName) {
                         char pf[FILENAME_MAX];
=20

--=_6z9ntg2r5qsc--

>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->closed 
State-Changed-By: linimon 
State-Changed-When: Mon Jun 5 18:16:54 UTC 2006 
State-Changed-Why:  
Misfiled followup to bin/88365; content migrated. 

Note to submitter: your mailer changed all the tabs to escape characters, 
and thus the patch is useless.  Please try resubmitting it without those 
characters, and with "Re: bin/88365: " at the beginning of the Subject line. 
Thanks. 


Responsible-Changed-From-To: gnats-admin->freebsd-bugs 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Mon Jun 5 18:16:54 UTC 2006 
Responsible-Changed-Why:  

http://www.freebsd.org/cgi/query-pr.cgi?pr=98532 
>Unformatted:
 This message is in MIME format.
 
 --=_6z9ntg2r5qsc
 Content-Type: text/plain;
 	charset=ISO-8859-1;
 	DelSp="Yes";
 	format="flowed"
 Content-Disposition: inline
 Content-Transfer-Encoding: 7bit
 
 
 
 --=_6z9ntg2r5qsc
 Content-Type: text/plain;
 	charset=UTF-8;
 	name="PR"
 Content-Disposition: inline;
 	filename="PR"
 Content-Transfer-Encoding: quoted-printable
 
