內核一個轉發模塊,在做IPv4轉IPv6的時候,對原來的IPv4報文指針進行了釋放操作,然後新建一個skb buffer存儲IPv6報文,使用
kfree_skb釋放掉舊的IPv4 skb後直接將新的IPv6 SKB指針傳遞給了指向舊的指針(如下),結果引起了內核奔潰。
struct sk_buff *skb, skb_cp;
/* 創建一個新的skb buffer */
skb_cp = skb_copy_expand(skb, head, tail, GFP_ATOMIC);
if (skb_cp)
{
/* 創建成功後,釋放skb所指向的舊的buffer,然後將新的skb指針賦值給它 */
dev_kfree_skb_any(skb);
skb = skb_cp;
}
上述操作是在一個函數體內進行的,導致跳出函數體後,skb仍然指向被釋放的skb buffer,引起系統異常。以前以爲指針傳遞可以改變原有的內容,原來是對指針沒理解透徹,將指針傳遞給函數後,可以在該函數體內修改該指針指向的數據內容,但是如果更改該指針所存儲的對象位置,對函數外部而言是無效的,相當於指針傳遞是傳遞了一個指針副本,這個指針副本和原有的指針指向同一個內容,可以對該內容進行修改,但是如果修改了該指針副本所指向的位置,並不會修改原有指針的內容。