* [Suggestion] drivers/isdn/divert: break looping, or memory leak by calling kmalloc again
@ 2013-04-01 2:11 Chen Gang
2013-04-01 10:08 ` Tilman Schmidt
0 siblings, 1 reply; 3+ messages in thread
From: Chen Gang @ 2013-04-01 2:11 UTC (permalink / raw)
To: isdn, Jiri Slaby, Jiri Kosina, tilman; +Cc: David Miller, netdev
Hello Maintainers:
in drivers/isdn/divert/isdn_divert.c:
in 'for' looping (line 395..515)
the 'cs' may call kmalloc again (line 453).
it seems need break looping, when get valid 'cs' value (line 509)
please help check, thanks.
gchen.
382 /*************************************************/
383 /* called from common module on an incoming call */
384 /*************************************************/
385 static int isdn_divert_icall(isdn_ctrl *ic)
386 {
387 int retval = 0;
388 unsigned long flags;
389 struct call_struc *cs = NULL;
390 struct deflect_struc *dv;
391 char *p, *p1;
392 u_char accept;
393
394 /* first check the internal deflection table */
395 for (dv = table_head; dv; dv = dv->next) {
396 /* scan table */
397 if (((dv->rule.callopt == 1) && (ic->command == ISDN_STAT_ICALLW)) ||
398 ((dv->rule.callopt == 2) && (ic->command == ISDN_STAT_ICALL)))
399 continue; /* call option check */
400 if (!(dv->rule.drvid & (1L << ic->driver)))
401 continue; /* driver not matching */
402 if ((dv->rule.si1) && (dv->rule.si1 != ic->parm.setup.si1))
403 continue; /* si1 not matching */
404 if ((dv->rule.si2) && (dv->rule.si2 != ic->parm.setup.si2))
405 continue; /* si2 not matching */
406
407 p = dv->rule.my_msn;
408 p1 = ic->parm.setup.eazmsn;
409 accept = 0;
410 while (*p) {
411 /* complete compare */
412 if (*p == '-') {
413 accept = 1; /* call accepted */
414 break;
415 }
416 if (*p++ != *p1++)
417 break; /* not accepted */
418 if ((!*p) && (!*p1))
419 accept = 1;
420 } /* complete compare */
421 if (!accept) continue; /* not accepted */
422
423 if ((strcmp(dv->rule.caller, "0")) ||
424 (ic->parm.setup.phone[0])) {
425 p = dv->rule.caller;
426 p1 = ic->parm.setup.phone;
427 accept = 0;
428 while (*p) {
429 /* complete compare */
430 if (*p == '-') {
431 accept = 1; /* call accepted */
432 break;
433 }
434 if (*p++ != *p1++)
435 break; /* not accepted */
436 if ((!*p) && (!*p1))
437 accept = 1;
438 } /* complete compare */
439 if (!accept) continue; /* not accepted */
440 }
441
442 switch (dv->rule.action) {
443 case DEFLECT_IGNORE:
444 return (0);
445
446 case DEFLECT_ALERT:
447 case DEFLECT_PROCEED:
448 case DEFLECT_REPORT:
449 case DEFLECT_REJECT:
450 if (dv->rule.action == DEFLECT_PROCEED)
451 if ((!if_used) || ((!extern_wait_max) && (!dv->rule.waittime)))
452 return (0); /* no external deflection needed */
453 if (!(cs = kmalloc(sizeof(struct call_struc), GFP_ATOMIC)))
454 return (0); /* no memory */
455 init_timer(&cs->timer);
456 cs->info[0] = '\0';
457 cs->timer.function = deflect_timer_expire;
458 cs->timer.data = (ulong) cs; /* pointer to own structure */
459
460 cs->ics = *ic; /* copy incoming data */
461 if (!cs->ics.parm.setup.phone[0]) strcpy(cs->ics.parm.setup.phone, "0");
462 if (!cs->ics.parm.setup.eazmsn[0]) strcpy(cs->ics.parm.setup.eazmsn, "0");
463 cs->ics.parm.setup.screen = dv->rule.screen;
464 if (dv->rule.waittime)
465 cs->timer.expires = jiffies + (HZ * dv->rule.waittime);
466 else if (dv->rule.action == DEFLECT_PROCEED)
467 cs->timer.expires = jiffies + (HZ * extern_wait_max);
468 else
469 cs->timer.expires = 0;
470 cs->akt_state = dv->rule.action;
471 spin_lock_irqsave(&divert_lock, flags);
472 cs->divert_id = next_id++; /* new sequence number */
473 spin_unlock_irqrestore(&divert_lock, flags);
474 cs->prev = NULL;
475 if (cs->akt_state == DEFLECT_ALERT) {
476 strcpy(cs->deflect_dest, dv->rule.to_nr);
477 if (!cs->timer.expires) {
478 strcpy(ic->parm.setup.eazmsn,
479 "Testtext direct");
480 ic->parm.setup.screen = dv->rule.screen;
481 strlcpy(ic->parm.setup.phone, dv->rule.to_nr, sizeof(ic->parm.setup.phone));
482 cs->akt_state = DEFLECT_AUTODEL; /* delete after timeout */
483 cs->timer.expires = jiffies + (HZ * AUTODEL_TIME);
484 retval = 5;
485 } else
486 retval = 1; /* alerting */
487 } else {
488 cs->deflect_dest[0] = '\0';
489 retval = 4; /* only proceed */
490 }
491 sprintf(cs->info, "%d 0x%lx %s %s %s %s 0x%x 0x%x %d %d %s\n",
492 cs->akt_state,
493 cs->divert_id,
494 divert_if.drv_to_name(cs->ics.driver),
495 (ic->command == ISDN_STAT_ICALLW) ? "1" : "0",
496 cs->ics.parm.setup.phone,
497 cs->ics.parm.setup.eazmsn,
498 cs->ics.parm.setup.si1,
499 cs->ics.parm.setup.si2,
500 cs->ics.parm.setup.screen,
501 dv->rule.waittime,
502 cs->deflect_dest);
503 if ((dv->rule.action == DEFLECT_REPORT) ||
504 (dv->rule.action == DEFLECT_REJECT)) {
505 put_info_buffer(cs->info);
506 kfree(cs); /* remove */
507 return ((dv->rule.action == DEFLECT_REPORT) ? 0 : 2); /* nothing to do */
508 }
509 break;
510
511 default:
512 return (0); /* ignore call */
513 } /* switch action */
514 break;
515 } /* scan_table */
516
517 if (cs) {
518 cs->prev = NULL;
519 spin_lock_irqsave(&divert_lock, flags);
520 cs->next = divert_head;
521 divert_head = cs;
522 if (cs->timer.expires) add_timer(&cs->timer);
523 spin_unlock_irqrestore(&divert_lock, flags);
524
525 put_info_buffer(cs->info);
526 return (retval);
527 } else
528 return (0);
529 } /* isdn_divert_icall */
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [Suggestion] drivers/isdn/divert: break looping, or memory leak by calling kmalloc again
2013-04-01 2:11 [Suggestion] drivers/isdn/divert: break looping, or memory leak by calling kmalloc again Chen Gang
@ 2013-04-01 10:08 ` Tilman Schmidt
2013-04-01 10:19 ` Chen Gang
0 siblings, 1 reply; 3+ messages in thread
From: Tilman Schmidt @ 2013-04-01 10:08 UTC (permalink / raw)
To: Chen Gang; +Cc: isdn, Jiri Slaby, Jiri Kosina, David Miller, netdev
[-- Attachment #1: Type: text/plain, Size: 698 bytes --]
Am 01.04.2013 04:11, schrieb Chen Gang:
> in drivers/isdn/divert/isdn_divert.c:
>
> in 'for' looping (line 395..515)
> the 'cs' may call kmalloc again (line 453).
>
> it seems need break looping, when get valid 'cs' value (line 509)
I don't think so. If the kmalloc for cs succeeds, control flow will
continue linearly up to the 'if' statement in line 503. Then it will
either kfree(cs) and return, or reach the 'break' in line 514 which
will end the 'for' loop.
HTH
Tilman
--
Tilman Schmidt E-Mail: tilman@imap.cc
Bonn, Germany
Diese Nachricht besteht zu 100% aus wiederverwerteten Bits.
Ungeöffnet mindestens haltbar bis: (siehe Rückseite)
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 261 bytes --]
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [Suggestion] drivers/isdn/divert: break looping, or memory leak by calling kmalloc again
2013-04-01 10:08 ` Tilman Schmidt
@ 2013-04-01 10:19 ` Chen Gang
0 siblings, 0 replies; 3+ messages in thread
From: Chen Gang @ 2013-04-01 10:19 UTC (permalink / raw)
To: Tilman Schmidt; +Cc: isdn, Jiri Slaby, Jiri Kosina, David Miller, netdev
On 2013年04月01日 18:08, Tilman Schmidt wrote:
> Am 01.04.2013 04:11, schrieb Chen Gang:
>> > in drivers/isdn/divert/isdn_divert.c:
>> >
>> > in 'for' looping (line 395..515)
>> > the 'cs' may call kmalloc again (line 453).
>> >
>> > it seems need break looping, when get valid 'cs' value (line 509)
> I don't think so. If the kmalloc for cs succeeds, control flow will
> continue linearly up to the 'if' statement in line 503. Then it will
> either kfree(cs) and return, or reach the 'break' in line 514 which
> will end the 'for' loop.
oh, really it is, it is my fault !
(I did not see the break at line 514)
thanks.
:-)
--
Chen Gang
Asianux Corporation
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2013-04-01 10:20 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-04-01 2:11 [Suggestion] drivers/isdn/divert: break looping, or memory leak by calling kmalloc again Chen Gang
2013-04-01 10:08 ` Tilman Schmidt
2013-04-01 10:19 ` Chen Gang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox