All of lore.kernel.org
 help / color / mirror / Atom feed
* [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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.