aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDan Carpenter <dan.carpenter@oracle.com>2013-01-24 15:40:56 -0500
committerDavid S. Miller <davem@davemloft.net>2013-01-27 20:38:19 -0500
commit4bf613c6d87399e3c8a4d5e14281456b6959d8fd (patch)
tree6bdbb94f2d769c6c3b401a787d9f9f7f56ff3963 /net
parent6efecd8c51c0118038495a5e10a0d855938da9ad (diff)
irda: buffer overflow in irnet_ctrl_read()
The comments here say that the /* Max event is 61 char */ but in 2003 we changed the event format and now the max event size is 75. The longest event is: "Discovered %08x (%s) behind %08x {hints %02X-%02X}\n", 12345678901 23 456789012 34567890 1 2 3 +8 +21 +8 +2 +2 +1 = 75 characters. There was a check to return -EOVERFLOW if the user gave us a "count" value that was less than 64. Raising it to 75 might break backwards compatability. Instead I removed the check and now it returns a truncated string if "count" is too low. Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/irda/irnet/irnet_ppp.c117
1 files changed, 58 insertions, 59 deletions
diff --git a/net/irda/irnet/irnet_ppp.c b/net/irda/irnet/irnet_ppp.c
index 2bb2beb6a373..3c83a1e5ab03 100644
--- a/net/irda/irnet/irnet_ppp.c
+++ b/net/irda/irnet/irnet_ppp.c
@@ -214,8 +214,7 @@ irnet_get_discovery_log(irnet_socket * ap)
214 * After reading : discoveries = NULL ; disco_index = Y ; disco_number = -1 214 * After reading : discoveries = NULL ; disco_index = Y ; disco_number = -1
215 */ 215 */
216static inline int 216static inline int
217irnet_read_discovery_log(irnet_socket * ap, 217irnet_read_discovery_log(irnet_socket *ap, char *event, int buf_size)
218 char * event)
219{ 218{
220 int done_event = 0; 219 int done_event = 0;
221 220
@@ -237,12 +236,13 @@ irnet_read_discovery_log(irnet_socket * ap,
237 if(ap->disco_index < ap->disco_number) 236 if(ap->disco_index < ap->disco_number)
238 { 237 {
239 /* Write an event */ 238 /* Write an event */
240 sprintf(event, "Found %08x (%s) behind %08x {hints %02X-%02X}\n", 239 snprintf(event, buf_size,
241 ap->discoveries[ap->disco_index].daddr, 240 "Found %08x (%s) behind %08x {hints %02X-%02X}\n",
242 ap->discoveries[ap->disco_index].info, 241 ap->discoveries[ap->disco_index].daddr,
243 ap->discoveries[ap->disco_index].saddr, 242 ap->discoveries[ap->disco_index].info,
244 ap->discoveries[ap->disco_index].hints[0], 243 ap->discoveries[ap->disco_index].saddr,
245 ap->discoveries[ap->disco_index].hints[1]); 244 ap->discoveries[ap->disco_index].hints[0],
245 ap->discoveries[ap->disco_index].hints[1]);
246 DEBUG(CTRL_INFO, "Writing discovery %d : %s\n", 246 DEBUG(CTRL_INFO, "Writing discovery %d : %s\n",
247 ap->disco_index, ap->discoveries[ap->disco_index].info); 247 ap->disco_index, ap->discoveries[ap->disco_index].info);
248 248
@@ -282,27 +282,24 @@ irnet_ctrl_read(irnet_socket * ap,
282 size_t count) 282 size_t count)
283{ 283{
284 DECLARE_WAITQUEUE(wait, current); 284 DECLARE_WAITQUEUE(wait, current);
285 char event[64]; /* Max event is 61 char */ 285 char event[75];
286 ssize_t ret = 0; 286 ssize_t ret = 0;
287 287
288 DENTER(CTRL_TRACE, "(ap=0x%p, count=%Zd)\n", ap, count); 288 DENTER(CTRL_TRACE, "(ap=0x%p, count=%Zd)\n", ap, count);
289 289
290 /* Check if we can write an event out in one go */
291 DABORT(count < sizeof(event), -EOVERFLOW, CTRL_ERROR, "Buffer to small.\n");
292
293#ifdef INITIAL_DISCOVERY 290#ifdef INITIAL_DISCOVERY
294 /* Check if we have read the log */ 291 /* Check if we have read the log */
295 if(irnet_read_discovery_log(ap, event)) 292 if (irnet_read_discovery_log(ap, event, sizeof(event)))
296 { 293 {
297 /* We have an event !!! Copy it to the user */ 294 count = min(strlen(event), count);
298 if(copy_to_user(buf, event, strlen(event))) 295 if (copy_to_user(buf, event, count))
299 { 296 {
300 DERROR(CTRL_ERROR, "Invalid user space pointer.\n"); 297 DERROR(CTRL_ERROR, "Invalid user space pointer.\n");
301 return -EFAULT; 298 return -EFAULT;
302 } 299 }
303 300
304 DEXIT(CTRL_TRACE, "\n"); 301 DEXIT(CTRL_TRACE, "\n");
305 return strlen(event); 302 return count;
306 } 303 }
307#endif /* INITIAL_DISCOVERY */ 304#endif /* INITIAL_DISCOVERY */
308 305
@@ -339,79 +336,81 @@ irnet_ctrl_read(irnet_socket * ap,
339 switch(irnet_events.log[ap->event_index].event) 336 switch(irnet_events.log[ap->event_index].event)
340 { 337 {
341 case IRNET_DISCOVER: 338 case IRNET_DISCOVER:
342 sprintf(event, "Discovered %08x (%s) behind %08x {hints %02X-%02X}\n", 339 snprintf(event, sizeof(event),
343 irnet_events.log[ap->event_index].daddr, 340 "Discovered %08x (%s) behind %08x {hints %02X-%02X}\n",
344 irnet_events.log[ap->event_index].name, 341 irnet_events.log[ap->event_index].daddr,
345 irnet_events.log[ap->event_index].saddr, 342 irnet_events.log[ap->event_index].name,
346 irnet_events.log[ap->event_index].hints.byte[0], 343 irnet_events.log[ap->event_index].saddr,
347 irnet_events.log[ap->event_index].hints.byte[1]); 344 irnet_events.log[ap->event_index].hints.byte[0],
345 irnet_events.log[ap->event_index].hints.byte[1]);
348 break; 346 break;
349 case IRNET_EXPIRE: 347 case IRNET_EXPIRE:
350 sprintf(event, "Expired %08x (%s) behind %08x {hints %02X-%02X}\n", 348 snprintf(event, sizeof(event),
351 irnet_events.log[ap->event_index].daddr, 349 "Expired %08x (%s) behind %08x {hints %02X-%02X}\n",
352 irnet_events.log[ap->event_index].name, 350 irnet_events.log[ap->event_index].daddr,
353 irnet_events.log[ap->event_index].saddr, 351 irnet_events.log[ap->event_index].name,
354 irnet_events.log[ap->event_index].hints.byte[0], 352 irnet_events.log[ap->event_index].saddr,
355 irnet_events.log[ap->event_index].hints.byte[1]); 353 irnet_events.log[ap->event_index].hints.byte[0],
354 irnet_events.log[ap->event_index].hints.byte[1]);
356 break; 355 break;
357 case IRNET_CONNECT_TO: 356 case IRNET_CONNECT_TO:
358 sprintf(event, "Connected to %08x (%s) on ppp%d\n", 357 snprintf(event, sizeof(event), "Connected to %08x (%s) on ppp%d\n",
359 irnet_events.log[ap->event_index].daddr, 358 irnet_events.log[ap->event_index].daddr,
360 irnet_events.log[ap->event_index].name, 359 irnet_events.log[ap->event_index].name,
361 irnet_events.log[ap->event_index].unit); 360 irnet_events.log[ap->event_index].unit);
362 break; 361 break;
363 case IRNET_CONNECT_FROM: 362 case IRNET_CONNECT_FROM:
364 sprintf(event, "Connection from %08x (%s) on ppp%d\n", 363 snprintf(event, sizeof(event), "Connection from %08x (%s) on ppp%d\n",
365 irnet_events.log[ap->event_index].daddr, 364 irnet_events.log[ap->event_index].daddr,
366 irnet_events.log[ap->event_index].name, 365 irnet_events.log[ap->event_index].name,
367 irnet_events.log[ap->event_index].unit); 366 irnet_events.log[ap->event_index].unit);
368 break; 367 break;
369 case IRNET_REQUEST_FROM: 368 case IRNET_REQUEST_FROM:
370 sprintf(event, "Request from %08x (%s) behind %08x\n", 369 snprintf(event, sizeof(event), "Request from %08x (%s) behind %08x\n",
371 irnet_events.log[ap->event_index].daddr, 370 irnet_events.log[ap->event_index].daddr,
372 irnet_events.log[ap->event_index].name, 371 irnet_events.log[ap->event_index].name,
373 irnet_events.log[ap->event_index].saddr); 372 irnet_events.log[ap->event_index].saddr);
374 break; 373 break;
375 case IRNET_NOANSWER_FROM: 374 case IRNET_NOANSWER_FROM:
376 sprintf(event, "No-answer from %08x (%s) on ppp%d\n", 375 snprintf(event, sizeof(event), "No-answer from %08x (%s) on ppp%d\n",
377 irnet_events.log[ap->event_index].daddr, 376 irnet_events.log[ap->event_index].daddr,
378 irnet_events.log[ap->event_index].name, 377 irnet_events.log[ap->event_index].name,
379 irnet_events.log[ap->event_index].unit); 378 irnet_events.log[ap->event_index].unit);
380 break; 379 break;
381 case IRNET_BLOCKED_LINK: 380 case IRNET_BLOCKED_LINK:
382 sprintf(event, "Blocked link with %08x (%s) on ppp%d\n", 381 snprintf(event, sizeof(event), "Blocked link with %08x (%s) on ppp%d\n",
383 irnet_events.log[ap->event_index].daddr, 382 irnet_events.log[ap->event_index].daddr,
384 irnet_events.log[ap->event_index].name, 383 irnet_events.log[ap->event_index].name,
385 irnet_events.log[ap->event_index].unit); 384 irnet_events.log[ap->event_index].unit);
386 break; 385 break;
387 case IRNET_DISCONNECT_FROM: 386 case IRNET_DISCONNECT_FROM:
388 sprintf(event, "Disconnection from %08x (%s) on ppp%d\n", 387 snprintf(event, sizeof(event), "Disconnection from %08x (%s) on ppp%d\n",
389 irnet_events.log[ap->event_index].daddr, 388 irnet_events.log[ap->event_index].daddr,
390 irnet_events.log[ap->event_index].name, 389 irnet_events.log[ap->event_index].name,
391 irnet_events.log[ap->event_index].unit); 390 irnet_events.log[ap->event_index].unit);
392 break; 391 break;
393 case IRNET_DISCONNECT_TO: 392 case IRNET_DISCONNECT_TO:
394 sprintf(event, "Disconnected to %08x (%s)\n", 393 snprintf(event, sizeof(event), "Disconnected to %08x (%s)\n",
395 irnet_events.log[ap->event_index].daddr, 394 irnet_events.log[ap->event_index].daddr,
396 irnet_events.log[ap->event_index].name); 395 irnet_events.log[ap->event_index].name);
397 break; 396 break;
398 default: 397 default:
399 sprintf(event, "Bug\n"); 398 snprintf(event, sizeof(event), "Bug\n");
400 } 399 }
401 /* Increment our event index */ 400 /* Increment our event index */
402 ap->event_index = (ap->event_index + 1) % IRNET_MAX_EVENTS; 401 ap->event_index = (ap->event_index + 1) % IRNET_MAX_EVENTS;
403 402
404 DEBUG(CTRL_INFO, "Event is :%s", event); 403 DEBUG(CTRL_INFO, "Event is :%s", event);
405 404
406 /* Copy it to the user */ 405 count = min(strlen(event), count);
407 if(copy_to_user(buf, event, strlen(event))) 406 if (copy_to_user(buf, event, count))
408 { 407 {
409 DERROR(CTRL_ERROR, "Invalid user space pointer.\n"); 408 DERROR(CTRL_ERROR, "Invalid user space pointer.\n");
410 return -EFAULT; 409 return -EFAULT;
411 } 410 }
412 411
413 DEXIT(CTRL_TRACE, "\n"); 412 DEXIT(CTRL_TRACE, "\n");
414 return strlen(event); 413 return count;
415} 414}
416 415
417/*------------------------------------------------------------------*/ 416/*------------------------------------------------------------------*/