I did some basic testing and investigations and I am attaching a
corrected patch.
I have found that the problem only started appearing in version 3.8.0.
In versions prior to that, the security-388608.patch used an
unlink(fileName) in the beginning of createOutputFile function call.
However, in debian/changelog it is mentioned that the security bug that
this patch was related to was fixed upstream. I don't know how it was
fixed, but the unlink was gone and the O_EXCL flag in the
createOutputFile is set in fopen causing the call to fail when the
destination file exists.
diff --git a/logrotate.c b/logrotate.c
index 174a26b..1306b1f 100644
--- a/logrotate.c
+++ b/logrotate.c
@@ -300,10 +300,35 @@ static int runScript(struct logInfo *log, char *logfn, char *script)
int createOutputFile(char *fileName, int flags, struct stat *sb, acl_type acl, int force_mode)
{
int fd;
- struct stat sb_create;
- int acl_set = 0;
+ struct stat sb_create;
+ int acl_set = 0;
+
+ if (stat(fileName, &sb_create) == 0) {
+ /* this indicates that the destination file exists, while it should not */
+ if (sb_create.st_size == 0) {
+ /* the file is of zero size, so not needed */
+ if (unlink(fileName) != 0) {
+ message(MESS_ERROR, "output file %s exists and failed to remove it: %s\n",
+ fileName, strerror(errno));
+ return -1;
+ }
+ } else {
+ int fnlength=sizeof(fileName);
+ char* garbage=malloc(fnlength+8); /* 'garbage\0' */
+ strncpy(garbage, fileName, fnlength);
+ strncpy(garbage+fnlength, "garbage\0", 8);
+ if (rename(fileName,garbage) != 0) {
+ message(MESS_ERROR, "output file %s exists and failed to rename it to %s: %s\n",
+ fileName, garbage, strerror(errno));
+ free(garbage);
+ return -1;
+ }
+ free(garbage);
+
+ }
+ }
- fd = open(fileName, (flags | O_EXCL | O_NOFOLLOW),
+ fd = open(fileName, (flags | O_EXCL | O_NOFOLLOW),
(S_IRUSR | S_IWUSR) & sb->st_mode);
if (fd < 0) {