-
Notifications
You must be signed in to change notification settings - Fork 7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
net: buf: Fix net_buf struct issue due to frags and node elem union #38830
net: buf: Fix net_buf struct issue due to frags and node elem union #38830
Conversation
net_buf elements are used in net_pool which are based on lifo implementation. Yet, net_buf structure doesn't respect lifo requierement that the first word must be reserved for the lifo kernel implementation. In most cases, this is fine as this word is mostly accessed when the element is not allocated, however, this is not always true. In such situation, node element is written, ehnce frags element value is not NULL anymore and anything might happen... This fixes zephyrproject-rtos#38829 issue. Signed-off-by: Xavier Chapron <xavier.chapron@stimio.fr>
fd639f2
to
80e5a7b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The way net_buf is currently designed (there may be bugs there however) is that when the buffer is inside a FIFO the frags member is never used. Instead there's a separate flag bit that's set in the buffer flags to indicate that there are related fragments coming after the buffer in the FIFO. Take a look at the net_buf_get() and net_buf_put() implementations which should be used to insert and remove buffers from a FIFO.
The memset to zero looks like a potentially valid fix, but the removal of the union doesn't. Or rather, if we are going to remove the union then there's much more rework to be done than just a simple bug fix.
FWIW, there has been plans to eliminate this feature with fragments and FIFOs and have a separate fragments list, however it needs some careful consideration because it increases the net_buf struct size, which can be quite critical for memory constrained systems that use a lot of buffers.
@@ -265,6 +265,7 @@ struct net_buf *net_buf_alloc_len(struct net_buf_pool *pool, size_t size, | |||
irq_unlock(key); | |||
|
|||
buf = pool_get_uninit(pool, uninit_count); | |||
memset(&buf->node, 0, sizeof(buf->node)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure about this one, it might be better placed near buf->frags = NULL;
below.
@jhedberg zephyr/subsys/mgmt/mcumgr/buf.c Line 22 in 1715e39
And net_buf_unref() cares about the frags member.
Maybe it means that we should more simply update However, I don't find it safe to have a "reserved member for kernel", used in a union which is memset at each alloc and shared with some other things.... I understand the optimisation, but I don't think that's the best 4 bytes to spare... |
@jhedberg This rule seems not to be correctly applied in multiples parts of the code. I've not find a single usage of I think we either need to fixed this quitte everywhere or sanitize the usage of |
No,
I'm not following. What's wrong with |
@jhedberg It seem I didn't get your first message, I've understant that you were telling me that rather than updating
To me, Anyway, my problem was more related to |
I simply meant to look at those implementations to see how they solve fragment buffer accounting with the help of There might be a missing resetting of the first four bytes somewhere, but least both |
@XavierChapron now that I look at your |
Ok my bad, it's already fixed in zephyr 2.6... See #33780 In my opinion there are two others ways to fix this:
|
net_buf elements are used in net_pool which are based on lifo
implementation. Yet, net_buf structure doesn't respect lifo requierement
that the first word must be reserved for the lifo kernel implementation.
In most cases, this is fine as this word is mostly accessed when the
element is not allocated, however, this is not always true.
In such situation, node element is written, ehnce frags element value is
not NULL anymore and anything might happen...
This fixes #38829 issue.
Signed-off-by: Xavier Chapron xavier.chapron@stimio.fr