1
votes

I'd need to know where can I make zeroization for the received/transmitted network packets in the e1000 linux driver. I need to know this to pass one compliance requirement, but I'm not able to find in the code of the e1000 where to do zeroization of the network packet buffer (or if it already does the zeroization somewhere, that would be great)

I saw that it does ring zeroization when the interface goes up or down in the kernel in the file Intel_LAN_15.0.0_Linux_Source_A00/Source/base_driver/e1000e-2.4.14/src/netdev.c, in the e1000_clean_rx_ring() and e1000_clean_tx_ring() functions:

    /* Zero out the descriptor ring */
    memset(rx_ring->desc, 0, rx_ring->size);

But I'm not able to find where it should be done for each packet that the system receives/send.

So, does anybody know where is the place in the code where the buffer zeroization for the tx/rx packets should happen? I bet that it will introduce some overhead, but I have to do it anyway.

We're using the intel EF multi port network card: https://www-ssl.intel.com/content/www/us/en/network-adapters/gigabit-network-adapters/gigabit-et-et2-ef-multi-port-server-adapters-brief.html? and the kernel 3.4.107

We're using the linux-image-3.4.107-0304107-generic_3.4.107-0304107.201504210712_amd64.deb kernel

EDIT: @skgrrwasme pointed correctly that the e1000_clean_tx_ring and e1000_clean_rx_ring functions seem to do the zeroize work, but as it is done only when the hw is down it is not valid for our compliance need.

So, it seems that the functions that are doing the work for each packet are e1000_clean_rx_irq and e1000_clean_tx_irq, but those functions doesn't zeroize data, they only free memory but doesn't make a memset() with 0 to overwrite memory (and that's what is required). So, what I think could be done is, as it is enough to zeroize data when rx or tx, inside e1000_clean_tx_irq() calls to e1000_unmap_and_free_tx_resource(), but in fact it only frees it, not zeroize it:

    if (buffer_info->skb) {
            dev_kfree_skb_any(buffer_info->skb);
            buffer_info->skb = NULL;
    }

So what I think is that we can wrote inside dev_kfree_skb_any(), the memset. That function calls to two functions: dev_kfree_skb_any(struct sk_buff *skb) { if (in_irq() || irqs_disabled()) dev_kfree_skb_irq(skb); else dev_kfree_skb(skb); }

So, something easy would be a call to skb_recycle_check(skb); that will do a:

    memset(skb, 0, offsetof(struct sk_buff, tail));

Does this make sense? I think that with this, the memory will be overwritten with zeroes, and the work will be done, but I'm not sure...

1
Is this to prevent information leaks? If so, the network driver should do it already (zero out the padding for frames smaller than the ethernet minimum). - ninjalj
What kernel version are you using? - skrrgwasme
Yes @ninjalj , it is to prevent information leaks. I guessed that the driver may do that but I wasn't sure where it is donde (and I need to specify it). skrrgwasme, I'm using the 3.4.107 kernel - Alberto
@Alberto Instead of editing your answer into the question, please put it down in an answers box. You'll then be able to click the big checkmark outline under the vote counts to mark it as accepted. Answering your own question on SO is encouraged, but the answers should stay separate from the questions. - skrrgwasme
wooppsss sorry @skrrgwasme, you're right - Alberto

1 Answers

2
votes

TL;DR

As far as I can tell, both the transmit and receive buffers are already cleaned by the driver for both transmit and receive. I don't think you need to do anything.

Longer Answer

I don't think you have to worry about it. The transmit and receive buffer clearing functions, e1000_clean_rx__irq and e1000_clean_rx_irq, seem to be called in any interrupt configuration, and for both transmit and receive. Interrupts can be triggered with any of the following interrupt signaling methods: legacy, MSI, or MSI-X. It appears that ring buffer cleaning happens in any interrupt mode, but they call the cleaning functions in different locations.

Since you have two types of transfers (transmit and receive) and three different types of interrupt invocations (Legacy, MSI, and MSI-X), you have a total of six scenarious where you need to make sure things are cleaned. Fortunately, five of the six situations handle the packets by scheduling a job for NAPI. These scenarios are transmit and receive for Legacy and MSI interrupts, and receive for MSI-X. Part of NAPI handling those packets is calling the e1000_clean function as a callback. If you look at the code, you'll see that it calls the buffer cleaning functions for both TX and RX.

The outlier is the MSI-X TX handler. However, it seems to directly call the TX buffer cleaning function, rather than having NAPI handle it.

Here are the relevant interrupt handlers that weren't specifically listed above:
Legacy (both RX and TX)
MSI (both RX and TX)
MSI-X RX

Notes

  1. All of my function references will open a file in the e1000e driver called netdev.c. They will open a window in the Linux Cross Reference database.

  2. This post discusses the e1000e driver, but some of the function names are "e1000...". I think a lot of the e1000 code was reused in the newer e1000e driver, so some of the names carried over. Just know that it isn't a typo.

  3. The e1000_clean_tx_ring and e1000_clean_rx_ring functions that you referred too appear to only be called when the driver is trying to free resources or the hardware is down, during any actual packet handling. The two I referenced above seem to, though. I'm not sure exactly what the difference between them is, but they appear to get the job done.