--- bzip2/bzip2recover.c +++ bzip2/bzip2recover.c @@ -24,10 +24,20 @@ #include #endif +#define BZ_UNIX 1 +#if defined(_WIN32) && !defined(__CYGWIN__) +# undef BZ_UNIX +# define BZ_UNIX 0 +#endif + #include #include #include #include +#if BZ_UNIX +# include +# include +#endif /* This program records bit locations in the file to be recovered. @@ -274,6 +284,33 @@ static Bool endsInBz2 ( Char* name ) } +/*---------------------------------------------*/ +/* Open an output file safely with O_EXCL and good permissions. + This avoids a race condition in older versions, in which + the file was first opened and then had its interim permissions + set safely. We instead use open() to create the file with + the interim permissions required (rw-------). + + For non-Unix platforms, if we are not worrying about + security issues, this simply behaves like fopen. +*/ +static +FILE* fopen_output_safely ( Char* name, const char* mode ) +{ +#if BZ_UNIX + FILE* fp; + int fh; + fh = open(name, O_WRONLY|O_CREAT|O_EXCL, S_IWUSR|S_IRUSR); + if (fh == -1) return NULL; + fp = fdopen(fh, mode); + if (fp == NULL) close(fh); + return fp; +#else + return fopen(name, mode); +#endif +} + + /*---------------------------------------------------*/ /*--- ---*/ /*---------------------------------------------------*/ @@ -490,7 +527,7 @@ Int32 main ( Int32 argc, Char** argv ) fprintf ( stderr, " writing block %d to `%s' ...\n", wrBlock+1, outFileName ); - outFile = fopen ( outFileName, "wb" ); + outFile = fopen_output_safely ( outFileName, "wb" ); if (outFile == NULL) { fprintf ( stderr, "%s: can't write `%s'\n", progName, outFileName );