Don't use fts_statp uninitialized for "chown -RLh --preserve-root ...".
authorJim Meyering <jim@meyering.net>
Wed, 10 Jan 2007 21:00:44 +0000 (22:00 +0100)
committerJim Meyering <jim@meyering.net>
Wed, 10 Jan 2007 21:00:44 +0000 (22:00 +0100)
* src/chown-core.c (FTSENT_IS_DIRECTORY): New macro.
(change_file_owner): Perform the ROOT_DEV_INO_CHECK only for a
directory.  Non-directory entries lack fts_statp data when using
the FTS_NOSTAT option.

ChangeLog
src/chown-core.c

index d4e766e..a89a016 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2007-01-10  Jim Meyering  <jim@meyering.net>
+
+       Don't use fts_statp uninitialized for "chown -RLh --preserve-root ...".
+       * src/chown-core.c (FTSENT_IS_DIRECTORY): New macro.
+       (change_file_owner): Perform the ROOT_DEV_INO_CHECK only for a
+       directory.  Non-directory entries lack fts_statp data when using
+       the FTS_NOSTAT option.
+
 2007-01-07  Jim Meyering  <jim@meyering.net>
 
        * tests/sample-test: Update copyright date to 2007.
index b390610..bd987a8 100644 (file)
@@ -1,5 +1,5 @@
 /* chown-core.c -- core functions for changing ownership.
-   Copyright (C) 2000, 2002, 2003, 2004, 2005, 2006 Free Software Foundation.
+   Copyright (C) 2000, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 #include "root-dev-ino.h"
 #include "xfts.h"
 
+#define FTSENT_IS_DIRECTORY(E) \
+  ((E)->fts_info == FTS_D      \
+   || (E)->fts_info == FTS_DC  \
+   || (E)->fts_info == FTS_DP  \
+   || (E)->fts_info == FTS_DNR)
+
 enum RCH_status
   {
     /* we called fchown and close, and both succeeded */
@@ -351,7 +357,9 @@ change_file_owner (FTS *fts, FTSENT *ent,
     }
 
   /* This happens when chown -LR --preserve-root encounters a symlink-to-/.  */
-  if (ROOT_DEV_INO_CHECK (chopt->root_dev_ino, file_stats))
+  if (ok
+      && FTSENT_IS_DIRECTORY (ent)
+      && ROOT_DEV_INO_CHECK (chopt->root_dev_ino, file_stats))
     {
       ROOT_DEV_INO_WARN (file_full_name);
       return false;