~ubuntu-branches/ubuntu/trusty/logrotate/trusty-proposed

« back to all changes in this revision

Viewing changes to debian/patches/CVE-2011-1154.patch

  • Committer: Bazaar Package Importer
  • Author(s): Marc Deslauriers
  • Date: 2011-06-17 13:36:27 UTC
  • Revision ID: james.westby@ubuntu.com-20110617133627-kmp1yvvfsxanvxhl
Tags: 3.7.8-6ubuntu4
* SECURITY UPDATE: arbitrary code execution via shell metacharacters in
  log filename
  - debian/patches/CVE-2011-1154.patch: improve shred logic in
    logrotate.c.
  - CVE-2011-1154
* SECURITY UPDATE: denial of service via invalid characters in log
  filename
  - debian/patches/CVE-2011-1155.patch: properly escape filenames in
    logrotate.c.
  - CVE-2011-1155

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
Description: fix arbitrary code execution via shell metacharacters in log filename
 
2
Origin: upstream, https://fedorahosted.org/logrotate/changeset/311
 
3
Origin: upstream, https://fedorahosted.org/logrotate/changeset/313
 
4
 
 
5
Index: logrotate-3.7.8/logrotate.c
 
6
===================================================================
 
7
--- logrotate-3.7.8.orig/logrotate.c    2011-06-17 13:30:54.081717762 -0400
 
8
+++ logrotate-3.7.8/logrotate.c 2011-06-17 13:32:25.321717738 -0400
 
9
@@ -58,7 +58,7 @@
 
10
 char *mailCommand = DEFAULT_MAIL_COMMAND;
 
11
 time_t nowSecs = 0;
 
12
 
 
13
-static int shred_file(char *filename, struct logInfo *log);
 
14
+static int shred_file(int fd, char *filename, struct logInfo *log);
 
15
 
 
16
 static int globerr(const char *pathname, int theerr)
 
17
 {
 
18
@@ -267,59 +267,79 @@
 
19
     return fd;
 
20
 }
 
21
 
 
22
-#define SHRED_CALL "shred -u "
 
23
-#define SHRED_COUNT_FLAG "-n "
 
24
 #define DIGITS 10
 
25
+
 
26
 /* unlink, but try to call shred from GNU fileutils */
 
27
-static int shred_file(char *filename, struct logInfo *log)
 
28
+static int shred_file(int fd, char *filename, struct logInfo *log)
 
29
 {
 
30
-       int len, ret;
 
31
-       char *cmd;
 
32
        char count[DIGITS];    /*  that's a lot of shredding :)  */
 
33
+       const char **fullCommand;
 
34
+       int id = 0;
 
35
+       int status;
 
36
 
 
37
        if (!(log->flags & LOG_FLAG_SHRED)) {
 
38
                return unlink(filename);
 
39
        }
 
40
 
 
41
-       len = strlen(filename) + strlen(SHRED_CALL);
 
42
-       len += strlen(SHRED_COUNT_FLAG) + DIGITS;
 
43
-       cmd = malloc(len);
 
44
+       message(MESS_DEBUG, "Using shred to remove the file %s\n", filename);
 
45
 
 
46
-       if (!cmd) {
 
47
-               message(MESS_ERROR, "malloc error while shredding");
 
48
-               return unlink(filename);
 
49
+       if (log->shred_cycles != 0) {
 
50
+               fullCommand = alloca(sizeof(*fullCommand) * 6);
 
51
+       }
 
52
+       else {
 
53
+               fullCommand = alloca(sizeof(*fullCommand) * 4);
 
54
        }
 
55
-       strcpy(cmd, SHRED_CALL);
 
56
+       fullCommand[id++] = "shred";
 
57
+       fullCommand[id++] = "-u";
 
58
+
 
59
        if (log->shred_cycles != 0) {
 
60
-               strcat(cmd, SHRED_COUNT_FLAG);
 
61
+               fullCommand[id++] = "-n";
 
62
                snprintf(count, DIGITS - 1, "%d", log->shred_cycles);
 
63
-               strcat(count, " ");
 
64
-               strcat(cmd, count);
 
65
+               fullCommand[id++] = count;
 
66
+       }
 
67
+       fullCommand[id++] = "-";
 
68
+       fullCommand[id++] = NULL;
 
69
+
 
70
+       if (!fork()) {
 
71
+               dup2(fd, 1);
 
72
+               close(fd);
 
73
+
 
74
+               execvp(fullCommand[0], (void *) fullCommand);
 
75
+               exit(1);
 
76
        }
 
77
-       strcat(cmd, filename);
 
78
-       ret = system(cmd);
 
79
-       free(cmd);
 
80
-       if (ret != 0) {
 
81
+       
 
82
+       wait(&status);
 
83
+
 
84
+       if (!WIFEXITED(status) || WEXITSTATUS(status)) {
 
85
                message(MESS_ERROR, "Failed to shred %s\n, trying unlink", filename);
 
86
-               if (ret != -1) {
 
87
-                       message(MESS_NORMAL, "Shred returned %d\n", ret);
 
88
-               }
 
89
                return unlink(filename);
 
90
-       } else {
 
91
-               return ret;
 
92
        }
 
93
+
 
94
+       /* We have to unlink it after shred anyway,
 
95
+        * because it doesn't remove the file itself */
 
96
+       return unlink(filename);
 
97
 }
 
98
 
 
99
 static int removeLogFile(char *name, struct logInfo *log)
 
100
 {
 
101
-    message(MESS_DEBUG, "removing old log %s\n", name);
 
102
+       int fd;
 
103
+       message(MESS_DEBUG, "removing old log %s\n", name);
 
104
 
 
105
-    if (!debug && shred_file(name, log)) {
 
106
-       message(MESS_ERROR, "Failed to remove old log %s: %s\n",
 
107
-               name, strerror(errno));
 
108
-       return 1;
 
109
-    }
 
110
-    return 0;
 
111
+       if ((fd = open(name, O_RDWR)) < 0) {
 
112
+               message(MESS_ERROR, "error opening %s: %s\n",
 
113
+                       name, strerror(errno));
 
114
+               return 1;
 
115
+       }
 
116
+
 
117
+       if (!debug && shred_file(fd, name, log)) {
 
118
+               message(MESS_ERROR, "Failed to remove old log %s: %s\n",
 
119
+                       name, strerror(errno));
 
120
+               close(fd);
 
121
+               return 1;
 
122
+       }
 
123
+
 
124
+       close(fd);
 
125
+       return 0;
 
126
 }
 
127
 
 
128
 static int compressLogFile(char *name, struct logInfo *log, struct stat *sb)
 
129
@@ -346,7 +366,7 @@
 
130
     compressedName = alloca(strlen(name) + strlen(log->compress_ext) + 2);
 
131
     sprintf(compressedName, "%s%s", name, log->compress_ext);
 
132
 
 
133
-    if ((inFile = open(name, O_RDONLY | O_NOFOLLOW)) < 0) {
 
134
+    if ((inFile = open(name, O_RDWR | O_NOFOLLOW)) < 0) {
 
135
        message(MESS_ERROR, "unable to open %s for compression\n", name);
 
136
        return 1;
 
137
     }
 
138
@@ -368,7 +388,6 @@
 
139
        exit(1);
 
140
     }
 
141
 
 
142
-    close(inFile);
 
143
     close(outFile);
 
144
 
 
145
     wait(&status);
 
146
@@ -384,7 +403,8 @@
 
147
     /* If we can't change atime/mtime, it's not a disaster.
 
148
        It might possibly fail under SELinux. */
 
149
 
 
150
-    shred_file(name, log);
 
151
+    shred_file(inFile, name, log);
 
152
+       close(inFile);
 
153
 
 
154
     return 0;
 
155
 }