[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Bug#276352: du: segfaults if you move folder(s) while it is counting
From: |
Jim Meyering |
Subject: |
Re: Bug#276352: du: segfaults if you move folder(s) while it is counting |
Date: |
Wed, 13 Oct 2004 21:24:53 +0200 |
Luis Lopez Lopez <address@hidden> wrote:
> Package: coreutils
> Version: 5.2.1-2
> Severity: normal
>
> The size of 'd' folder is about 100Mb like 'a' folder.
> I leave 'du' process running on a terminal and open another to do some
> work.
>
> Folder 'd' contains a big folder called 'WORK' about 80 Mb. While 'du'
> was running I move 'WORK' outside 'd'. Later I got this message when I
> suppose 'du' was ready to read 'WORK':
>
> address@hidden:~/svn$ du -hs a b c d
> 119M a
> 11M b
> 25M c
> du: fts_read falló: No existe el fichero o el directorio
> Violación de segmento
>
> The message translated to english sould be something like this:
> du: fts_read falló: No such file or directory
> Segmentation fault
Thank you for the fine bug report.
It is indeed a bug in the latest sources.
I was able to reproduce it.
When a subdirectory of a du operand directory is removed
while du is traversing that subdirectory, the fts_read
function fails (as it should), but in so doing, it neglects
to set the sp->fts_cur state variable, and that causes the
subsequent fts_close to free an invalid pointer.
Here's a patch:
2004-10-13 Jim Meyering <address@hidden>
* fts.c (fts_read): When about to fail (by returning NULL) due
to a failed fchdir or failed fts_safe_changedir call, set
`sp->fts_cur = p'. Do this by removing the explicit `return NULL;'
statements and setting p->fts_errno so execution falls through
to the common-case code below. Otherwise, after such a failure,
calling fts_close would attempt to free an already-freed buffer.
Reported by Luis Lopez Lopez in http://bugs.debian.org/276352.
Index: lib/fts.c
===================================================================
RCS file: /fetish/cu/lib/fts.c,v
retrieving revision 1.20
diff -u -p -r1.20 fts.c
--- lib/fts.c 2 Sep 2004 23:56:59 -0000 1.20
+++ lib/fts.c 13 Oct 2004 18:13:42 -0000
@@ -716,27 +716,28 @@ name: t = sp->fts_path + NAPPEND(p->fts
*/
if (p->fts_level == FTS_ROOTLEVEL) {
if (FCHDIR(sp, sp->fts_rfd)) {
+ p->fts_errno = errno;
SET(FTS_STOP);
- return (NULL);
}
} else if (p->fts_flags & FTS_SYMFOLLOW) {
if (FCHDIR(sp, p->fts_symfd)) {
saved_errno = errno;
(void)close(p->fts_symfd);
__set_errno (saved_errno);
+ p->fts_errno = errno;
SET(FTS_STOP);
- return (NULL);
}
(void)close(p->fts_symfd);
} else if (!(p->fts_flags & FTS_DONTCHDIR) &&
fts_safe_changedir(sp, p->fts_parent, -1, "..")) {
+ p->fts_errno = errno;
SET(FTS_STOP);
- return (NULL);
}
p->fts_info = p->fts_errno ? FTS_ERR : FTS_DP;
if (p->fts_errno == 0)
LEAVE_DIR (sp, p, "3");
- return (sp->fts_cur = p);
+ sp->fts_cur = p;
+ return ISSET(FTS_STOP) ? NULL : p;
}
/*
- Re: Bug#276352: du: segfaults if you move folder(s) while it is counting,
Jim Meyering <=