Hi Prakash,

     I see a system crash if I do freemsg. Following is the crash analysis

kernel memory allocator:
buffer modified after being freed
modification occurred at offset 0x70 (0xdeadbeefdeadbeef replaced by  
0xaddebeefaddebeef)
buffer=ffffffff91266700  bufctl=ffffffff9127c870  cache: streams_dblk_80
previous transaction on buffer ffffffff91266700:
thread=fffffe80000adc80  time=T-0.000008601  slab=ffffffff83214890  cache:  
streams_dblk_80
kmem_cache_free_debug+f4
kmem_cache_free+43
dblk_lastfree+39
freemsg+7e
pwise_appendto_payload+1f3            // Hook function
pfil_precheck+cd2
pfilmodrput+395
putnext+1f1
gld_passon+b3
gld_sendup+fa
gld_recv_tagged+175
ri_ste_def+363ed6eb
rtls_receive+1f6
rtls_gld_intr+dc

panic[cpu0]/thread=fffffe80000adc80:
kernel heap corruption detected


fffffe80000ad500 fffffffffb95e318 (ffffffff91268500, fffffffff)
fffffe80000ad550 genunix:kmem_cache_alloc_debug+262 ()
fffffe80000ad580 genunix:kmem_cache_alloc+6f ()
fffffe80000ad5b0 genunix:allocb+77 ()
fffffe80000ad6e0 udp:udp_rput+853 ()
fffffe80000ad740 unix:putnext+1f1 ()
fffffe80000ad7f0 ip:ip_udp_input+632 ()
fffffe80000ad870 ip:ip_rput+6e1 ()
fffffe80000ad8d0 unix:putnext+1f1 ()
fffffe80000ad950 pfil:pfilmodrput+3e5 ()
fffffe80000ad9b0 unix:putnext+1f1 ()
fffffe80000ad9f0 gld:gld_passon+b3 ()
fffffe80000ada50 gld:gld_sendup+fa ()
fffffe80000adb70 gld:gld_recv_tagged+175 ()
fffffe80000adb80 gld:ri_ste_def+363ed6eb ()
fffffe80000adbd0 rtls:rtls_receive+1f6 ()
fffffe80000adc00 rtls:rtls_gld_intr+dc ()
fffffe80000adc10 gld:ri_ste_def+363ed507 ()
fffffe80000adc60 unix:av_dispatch_autovect+6a ()

     Whereas if I don't do freemsg atall the code run's fine.

Thanks,
Sachin

On Wed, 12 Apr 2006 00:32:31 +0530, Prakash Jalan <Prakash.Jalan at Sun.COM>  
wrote:

>
>>    At present I am creating a new mblk copying the original IP,UDP  
>> packets + new data
>> in new mblk, updating the length and checksums, then I freemsg() the  
>> original
>> mblk at **mp and make mp point at the newly created mblk. I know this
>> is not the correct way of doing as someone else maybe be pointing at  
>> original *mp.
>
> oh! don't worry about doing freemsg(). You are releasing your reference
> on the message by calling freemsg() which is perfectly fine. freemsg()
> internally takes care of other references by not freeing the dblk
> if the reference count is greater than 1.
>
> I see an issue with your code though. A message is defined as chain
> of message blocks (mblk_t) connected via b_cont field. For your case,
> a single UDP packet could be spanned over multiple mblks connected
> by b_cont field (still it would be single message). Your code looks
> at the first mblk only and assume it contains the full packet,
> which may not be the case. You should loop through the chain
> and append your data at the last mblk of the message.
>
> b_next and b_prev are used to chain _messages_ together.
>
> Following diagram will help:
>
> message A    mblk_A1.b_cont ---> mblk_A2.b_cont ---> mblk_A3.b_cont
>
>                A   |  b_next
>         b_prev |   V
>
> message B   mblk_B1.b_cont ---> mblk_B2.b_cont ---> mblk_B3.b_cont
>
>                A   |  b_next
>         b_prev |   V
>
> message C   mblk_C1.b_cont ---> mblk_C2.b_cont ---> mblk_C3.b_cont
>
>
> prakah
>
>>  Here is the code snip
>>  pfil_hook_function (...)
>> {
>>         struct udphdr *oldudp,*udp;
>>         u_short sz,newlen;
>>         mblk_t *m;
>>         struct ip *ip,*oldip;
>>         char data[6] = {0};
>>         int datalen = 6 ;
>>          oldip = (struct ip *)((*mp)->b_rptr) ;
>>         oldudp = (char *)oldip + hlen ;
>>         newlen = ntohs(oldudp->uh_ulen) + datalen;
>>          sz = hlen + newlen;
>>          if ((m = (mblk_t *)allocb((size_t)sz, BPRI_HI)) == NULL) {
>>                 return 0;
>>         }
>>         MTYPE(m) = M_DATA;
>>         m->b_wptr = m->b_rptr + sz;
>>         bzero((char *)m->b_rptr, (size_t)sz);
>>         udp = (struct udp *)(m->b_rptr + hlen);
>>         bcopy(oldudp,udp,ntohs(oldudp->uh_ulen));
>>         bcopy(data,(char *)udp + ntohs(oldudp->uh_ulen),datalen);
>>          ip = (struct ip *)m->b_rptr;
>>         bcopy(oldip,ip,hlen);
>>         ip->ip_len        = htons(oldip->ip_len + datalen);
>>         ip->ip_sum        =  0 ;
>>         ip->ip_sum        = my_ip_checksum(ip, hlen) ;
>>         udp->uh_ulen      = htons(newlen) ;
>>         udp->uh_sum       = 0 ;
>>         udp->uh_sum       = my_udp_checksum(ip->ip_dst.s_addr,
>>                                              
>> ip->ip_src.s_addr,udp->uh_ulen,udp,
>>                                             newlen);
>>         m->b_prev = (*mp)->b_prev ;
>>         m->b_next = (*mp)->b_next ;
>>          m->b_cont = (*mp)->b_cont ;
>>         freemsg(*mp);
>>          *mp = m;
>>          return 0;
>> }
>>  Any suggestions, or a better way of doing this ?
>>  Thanks,
>> -Sachin
>>     _______________________________________________
>> ug-bosug mailing list
>> List-Unsubscribe: mailto:ug-bosug-unsubscribe at opensolaris.org
>> List-Owner: mailto:ug-bosug-owner at opensolaris.org
>> List-Archives: http://www.opensolaris.org/jive/forum.jspa?forumID=54
>
> _______________________________________________
> ug-bosug mailing list
> List-Unsubscribe: mailto:ug-bosug-unsubscribe at opensolaris.org
> List-Owner: mailto:ug-bosug-owner at opensolaris.org
> List-Archives: http://www.opensolaris.org/jive/forum.jspa?forumID=54



-- 
Sachin Shelar
Software Engineer
S7 Software Solutions

Reply via email to