From cbe044e0f12b5ae86a47b7ec1bc61bbe0ad785ad Mon Sep 17 00:00:00 2001 From: John Marino Date: Fri, 16 Nov 2012 00:31:35 +0100 Subject: [PATCH] /bin/rm: fix removing symlinks with uchg/uappnd set One error case described in FreeBSD PR bin/111226: /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 link's target (if that target exists) - an object that /bin/rm should not touch! (Quote from SUSv3: "The rm utility removes symbolic links themselves, not the files they refer to, as a consequence of the dependence on the unlink() functionality"). There was a failure case for /usr/bin/find as well, but swildner recently synchronized find with FreeBSD and fixed that one. Taken-from: FreeBSD SVN 193087 (30 MAY 2009) --- bin/rm/rm.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/bin/rm/rm.c b/bin/rm/rm.c index 47529b5f2b..25d7d9fdd3 100644 --- a/bin/rm/rm.c +++ b/bin/rm/rm.c @@ -33,7 +33,6 @@ * @(#) Copyright (c) 1990, 1993, 1994 The Regents of the University of California. All rights reserved. * @(#)rm.c 8.5 (Berkeley) 4/18/94 * $FreeBSD: src/bin/rm/rm.c,v 1.29.2.5 2002/07/12 07:25:48 tjr Exp $ - * $DragonFly: src/bin/rm/rm.c,v 1.19 2006/11/12 00:51:47 swildner Exp $ */ #include @@ -239,7 +238,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)) && - chflags(p->fts_accpath, + lchflags(p->fts_accpath, p->fts_statp->st_flags &= ~(UF_APPEND|UF_IMMUTABLE)) < 0) goto err; continue; @@ -263,7 +262,7 @@ rm_tree(char **argv) 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) { @@ -369,7 +368,7 @@ rm_file(char **argv) 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); -- 2.41.0