aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Mahoney <jeffm@suse.com>2009-03-30 14:02:22 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-03-30 15:16:36 -0400
commitcacbe3d7ad3c0a345ca1ce7bf1ecb4c5bfe54d7b (patch)
tree853abddd05fe175e7aacf9cc7868b28e1bfa6e62
parent45b03d5e8e674eb6555b767e1c8eb40b671ff892 (diff)
reiserfs: prepare_error_buf wrongly consumes va_arg
vsprintf will consume varargs on its own. Skipping them manually results in garbage in the error buffer, or Oopses in the case of pointers. This patch removes the advancement and fixes a number of bugs where crashes were observed as side effects of a regular error report. Signed-off-by: Jeff Mahoney <jeffm@suse.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--fs/reiserfs/prints.c12
1 files changed, 3 insertions, 9 deletions
diff --git a/fs/reiserfs/prints.c b/fs/reiserfs/prints.c
index 50ed4bd3ef63..b87b23717c23 100644
--- a/fs/reiserfs/prints.c
+++ b/fs/reiserfs/prints.c
@@ -157,19 +157,16 @@ static void sprintf_disk_child(char *buf, struct disk_child *dc)
157 dc_size(dc)); 157 dc_size(dc));
158} 158}
159 159
160static char *is_there_reiserfs_struct(char *fmt, int *what, int *skip) 160static char *is_there_reiserfs_struct(char *fmt, int *what)
161{ 161{
162 char *k = fmt; 162 char *k = fmt;
163 163
164 *skip = 0;
165
166 while ((k = strchr(k, '%')) != NULL) { 164 while ((k = strchr(k, '%')) != NULL) {
167 if (k[1] == 'k' || k[1] == 'K' || k[1] == 'h' || k[1] == 't' || 165 if (k[1] == 'k' || k[1] == 'K' || k[1] == 'h' || k[1] == 't' ||
168 k[1] == 'z' || k[1] == 'b' || k[1] == 'y' || k[1] == 'a') { 166 k[1] == 'z' || k[1] == 'b' || k[1] == 'y' || k[1] == 'a') {
169 *what = k[1]; 167 *what = k[1];
170 break; 168 break;
171 } 169 }
172 (*skip)++;
173 k++; 170 k++;
174 } 171 }
175 return k; 172 return k;
@@ -193,18 +190,15 @@ static void prepare_error_buf(const char *fmt, va_list args)
193 char *fmt1 = fmt_buf; 190 char *fmt1 = fmt_buf;
194 char *k; 191 char *k;
195 char *p = error_buf; 192 char *p = error_buf;
196 int i, j, what, skip; 193 int what;
197 194
198 strcpy(fmt1, fmt); 195 strcpy(fmt1, fmt);
199 196
200 while ((k = is_there_reiserfs_struct(fmt1, &what, &skip)) != NULL) { 197 while ((k = is_there_reiserfs_struct(fmt1, &what)) != NULL) {
201 *k = 0; 198 *k = 0;
202 199
203 p += vsprintf(p, fmt1, args); 200 p += vsprintf(p, fmt1, args);
204 201
205 for (i = 0; i < skip; i++)
206 j = va_arg(args, int);
207
208 switch (what) { 202 switch (what) {
209 case 'k': 203 case 'k':
210 sprintf_le_key(p, va_arg(args, struct reiserfs_key *)); 204 sprintf_le_key(p, va_arg(args, struct reiserfs_key *));