dhcpv4: Fix AVL tree corruption bugs#381
Merged
openwrt-bot merged 2 commits intoopenwrt:masterfrom Mar 16, 2026
Merged
Conversation
Contributor
Author
|
Supersedes #376 |
4bddf1a to
f641760
Compare
Contributor
Author
Contributor
Author
|
I found another bug, see second commit. |
Noltari
approved these changes
Mar 16, 2026
systemcrash
approved these changes
Mar 16, 2026
Noltari
pushed a commit
to mmmspatz/odhcpd
that referenced
this pull request
Mar 16, 2026
dhcpv4_free_lease() unconditionally calls avl_delete() to remove the lease from the avl tree at lease->iface->dhcpv4_leases. This corrupts the tree if the lease is not in it, which happens if dhcpv4_assign() returns false during address reassignment (line ~611) or assignment (line ~630). The check for (lease->iface == NULL) before avl_delete() does not guard against this and is not necessary, because lease->iface is populated by dhcpv4_alloc_lease() and never cleared. Fix by explicitly checking that the lease is in the tree before deleting it. Fixes: aa6870b ("dhcpv4: use an AVL to store leases") Signed-off-by: Mark H. Spatz <mark.h.spatz@gmail.com> Link: openwrt#381 Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
3e2c1ff to
82169b1
Compare
Noltari
pushed a commit
to mmmspatz/odhcpd
that referenced
this pull request
Mar 16, 2026
dhcpv4_free_lease already calls avl_delete() on the node it's freeing, and thus shouldn't be called inside an avl_remove_all_elements() loop. Use avl_for_each_element_safe() instead. Its documentation says: "This loop can be used if the current element might be removed from the tree during the loop." Fixes: openwrt#371 Signed-off-by: Mark H. Spatz <mark.h.spatz@gmail.com> Link: openwrt#381 Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
Noltari
pushed a commit
to mmmspatz/odhcpd
that referenced
this pull request
Mar 16, 2026
dhcpv4_free_lease() unconditionally calls avl_delete() to remove the lease from the avl tree at lease->iface->dhcpv4_leases. This corrupts the tree if the lease is not in it, which happens if dhcpv4_assign() returns false during address reassignment (line ~611) or assignment (line ~630). The check for (lease->iface == NULL) before avl_delete() does not guard against this and is not necessary, because lease->iface is populated by dhcpv4_alloc_lease() and never cleared. Fix by explicitly checking that the lease is in the tree before deleting it. Fixes: aa6870b ("dhcpv4: use an AVL to store leases") Signed-off-by: Mark H. Spatz <mark.h.spatz@gmail.com> Link: openwrt#381 Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
82169b1 to
5206a35
Compare
dhcpv4_free_lease already calls avl_delete() on the node it's freeing, and thus shouldn't be called inside an avl_remove_all_elements() loop. Use avl_for_each_element_safe() instead. Its documentation says: "This loop can be used if the current element might be removed from the tree during the loop." Closes: openwrt#371 Signed-off-by: Mark H. Spatz <mark.h.spatz@gmail.com> Link: openwrt#381 Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
dhcpv4_free_lease() unconditionally calls avl_delete() to remove the lease from the avl tree at lease->iface->dhcpv4_leases. This corrupts the tree if the lease is not in it, which happens if dhcpv4_assign() returns false during address reassignment (line ~611) or assignment (line ~630). The check for (lease->iface == NULL) before avl_delete() does not guard against this and is not necessary, because lease->iface is populated by dhcpv4_alloc_lease() and never cleared. Fix by explicitly checking that the lease is in the tree before deleting it. Fixes: aa6870b ("dhcpv4: use an AVL to store leases") Signed-off-by: Mark H. Spatz <mark.h.spatz@gmail.com> Link: openwrt#381 Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
5206a35 to
4e26e13
Compare
Member
|
Merged, thanks @mmmspatz! |
Noltari
pushed a commit
to Noltari/odhcpd
that referenced
this pull request
Mar 16, 2026
dhcpv4_free_lease already calls avl_delete() on the node it's freeing, and thus shouldn't be called inside an avl_remove_all_elements() loop. Use avl_for_each_element_safe() instead. Its documentation says: "This loop can be used if the current element might be removed from the tree during the loop." (cherry picked from commit ea5af5b) Closes: openwrt#371 Signed-off-by: Mark H. Spatz <mark.h.spatz@gmail.com> Link: openwrt#381 Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
Noltari
pushed a commit
to Noltari/odhcpd
that referenced
this pull request
Mar 16, 2026
dhcpv4_free_lease() unconditionally calls avl_delete() to remove the lease from the avl tree at lease->iface->dhcpv4_leases. This corrupts the tree if the lease is not in it, which happens if dhcpv4_assign() returns false during address reassignment (line ~611) or assignment (line ~630). The check for (lease->iface == NULL) before avl_delete() does not guard against this and is not necessary, because lease->iface is populated by dhcpv4_alloc_lease() and never cleared. Fix by explicitly checking that the lease is in the tree before deleting it. (cherry picked from commit 4e26e13) Fixes: aa6870b ("dhcpv4: use an AVL to store leases") Signed-off-by: Mark H. Spatz <mark.h.spatz@gmail.com> Link: openwrt#381 Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
dhcpv4_free_lease already calls avl_delete() on the node it's freeing, and thus shouldn't be called inside an avl_remove_all_elements() loop.
Use avl_for_each_element_safe() instead. Its documentation says: "This loop can be used if the current element might be removed from the tree during the loop."
Fixes: #371