kern/126433: [patch]: some missing checks in rm(1)

Ighighi ighighi at gmail.com
Sun Aug 10 20:10:05 UTC 2008


>Number:         126433
>Category:       kern
>Synopsis:       [patch]: some missing checks in rm(1)
>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:   Sun Aug 10 20:10:04 UTC 2008
>Closed-Date:
>Last-Modified:
>Originator:     Ighighi
>Release:        6.3-STABLE (RELENG_6)
>Organization:
>Environment:
FreeBSD orion 6.3-STABLE FreeBSD 6.3-STABLE #0: Tue Aug  5 17:02:02 VET 2008     root at orion:/usr/obj/usr/src/sys/CUSTOM  i386
>Description:
rm(1) allows root to delete uchg/uappend files.  Before unlinking, it checks
whether schg|sappend are set to skip the chflags() system call that clears
uchg and uappend.

It must also check whether uunlink|sunlink are set as they'd also make unlink()
fail later.

PS: Can anyone explain to me the usefulness of letting root skip uchg/uappend?
FreeBSD and DragonFly are the only BSD's that do this.
I'm playing with a -F option to unset uchg/uappend/uunlink for any user. The 
patch is available to anyone on request.
>How-To-Repeat:

>Fix:
Attached patch successfully built and tested on RELENG_6 & -CURRENT sources.

Patch attached with submission follows:

--- rm.c.orig	2008-07-25 15:05:23.000000000 -0430
+++ rm.c	2008-08-10 15:00:05.465754091 -0430
@@ -230,7 +230,7 @@ rm_tree(char **argv)
 			}
 			else if (!uid &&
 				 (p->fts_statp->st_flags & (UF_APPEND|UF_IMMUTABLE)) &&
-				 !(p->fts_statp->st_flags & (SF_APPEND|SF_IMMUTABLE)) &&
+				 !(p->fts_statp->st_flags & (SF_APPEND|SF_IMMUTABLE|SF_NOUNLINK|UF_NOUNLINK)) &&
 				 chflags(p->fts_accpath,
 					 p->fts_statp->st_flags &= ~(UF_APPEND|UF_IMMUTABLE)) < 0)
 				goto err;
@@ -249,7 +249,7 @@ rm_tree(char **argv)
 		rval = 0;
 		if (!uid &&
 		    (p->fts_statp->st_flags & (UF_APPEND|UF_IMMUTABLE)) &&
-		    !(p->fts_statp->st_flags & (SF_APPEND|SF_IMMUTABLE)))
+		    !(p->fts_statp->st_flags & (SF_APPEND|SF_IMMUTABLE|SF_NOUNLINK|UF_NOUNLINK)))
 			rval = chflags(p->fts_accpath,
 				       p->fts_statp->st_flags &= ~(UF_APPEND|UF_IMMUTABLE));
 		if (rval == 0) {
@@ -349,7 +349,7 @@ rm_file(char **argv)
 		rval = 0;
 		if (!uid && !S_ISWHT(sb.st_mode) &&
 		    (sb.st_flags & (UF_APPEND|UF_IMMUTABLE)) &&
-		    !(sb.st_flags & (SF_APPEND|SF_IMMUTABLE)))
+		    !(sb.st_flags & (SF_APPEND|SF_IMMUTABLE|SF_NOUNLINK|UF_NOUNLINK)))
 			rval = chflags(f, sb.st_flags & ~(UF_APPEND|UF_IMMUTABLE));
 		if (rval == 0) {
 			if (S_ISWHT(sb.st_mode))


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list