Fix dhcp option buffer issue (#12033)
Why I did it Current isc-dhcp uses below code to remove DHCP option: memmove(sp, op, op[1] + 2); sp += op[1] + 2; sp points to the option to be stripped, we can call it as option S. op points to the option after options S, we can call it as option O. DHCP option is a typical type-length-value structure, the first byte is type, the second byte is length, and remain parts are value. In this case, option O length is bigger than option S, and more than 2 bytes, after the memmove, we will get this result: Now Option S and Option O are overwritten, op[1] was the length of Option O, and it's modified after memmove. But current implementation is still using op[1] as length to update sp (sp+=op[1]+2), so we get the wrong sp. How I did it Create patch from https://github.com/isc-projects/dhcp The new impelementation use mlen to store the length of Option O before memmove, that's how it fixed the bug. size_t mlen = op[1] + 2; memmove(sp, op, mlen); sp += mlen; How to verify it I have a PR for sonic-mgmt to cover this issue: sonic-net/sonic-mgmt#6330 Signed-off-by: Gang Lv ganglv@microsoft.com
This commit is contained in:
parent
a1b50cac41
commit
5650762f2c
@ -0,0 +1,53 @@
|
||||
From 0a2f9a62bceb90b0d30461add2e25c4ce7a24547 Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Markwalder <tmark@isc.org>
|
||||
Date: Fri, 20 Dec 2019 10:11:54 -0500
|
||||
Subject: [PATCH] [#71] Fix dhcrelay agent option buffer pointer logic
|
||||
|
||||
relay/dhcrelay.c
|
||||
strip_relay_agent_options()
|
||||
strip_relay_agent_options()
|
||||
- corrected buffer pointer logic
|
||||
|
||||
---
|
||||
relay/dhcrelay.c | 18 ++++++++++++++----
|
||||
1 file changed, 14 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c
|
||||
index 896e1e2e..980dacae 100644
|
||||
--- a/relay/dhcrelay.c
|
||||
+++ b/relay/dhcrelay.c
|
||||
@@ -1238,8 +1238,13 @@ strip_relay_agent_options(struct interface_info *in,
|
||||
return (0);
|
||||
|
||||
if (sp != op) {
|
||||
- memmove(sp, op, op[1] + 2);
|
||||
- sp += op[1] + 2;
|
||||
+ size_t mlen = op[1] + 2;
|
||||
+ memmove(sp, op, mlen);
|
||||
+ sp += mlen;
|
||||
+ if (sp > max) {
|
||||
+ return (0);
|
||||
+ }
|
||||
+
|
||||
op = nextop;
|
||||
} else
|
||||
op = sp = nextop;
|
||||
@@ -1620,8 +1620,13 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet,
|
||||
end_pad = NULL;
|
||||
|
||||
if (sp != op) {
|
||||
- memmove(sp, op, op[1] + 2);
|
||||
- sp += op[1] + 2;
|
||||
+ size_t mlen = op[1] + 2;
|
||||
+ memmove(sp, op, mlen);
|
||||
+ sp += mlen;
|
||||
+ if (sp > max) {
|
||||
+ return (0);
|
||||
+ }
|
||||
+
|
||||
op = nextop;
|
||||
} else
|
||||
op = sp = nextop;
|
||||
--
|
||||
2.17.1
|
||||
|
@ -11,3 +11,4 @@
|
||||
0010-Bugfix-correctly-set-interface-netmask.patch
|
||||
0011-dhcp-relay-Prevent-Buffer-Overrun.patch
|
||||
0012-add-option-si-to-support-using-src-intf-ip-in-relay.patch
|
||||
0013-Fix-dhcrelay-agent-option-buffer-pointer-logic.patch
|
||||
|
Loading…
Reference in New Issue
Block a user