[PATCHv3 1/3] radius: avoid memcpy in radius_msg_add_wfa
michael-dev at fami-braun.de
michael-dev at fami-braun.de
Sat May 1 01:46:42 BST 2021
From: Michael Braun <michael-dev at fami-braun.de>
Signed-off-by: Michael Braun <michael-dev at fami-braun.de>
---
src/radius/radius.c | 50 +++++++++++++++++++++++++++------------------
src/radius/radius.h | 6 ++++++
2 files changed, 36 insertions(+), 20 deletions(-)
diff --git a/src/radius/radius.c b/src/radius/radius.c
index be16e27b9..fe4d23a5d 100644
--- a/src/radius/radius.c
+++ b/src/radius/radius.c
@@ -629,21 +629,35 @@ static int radius_msg_add_attr_to_array(struct radius_msg *msg,
struct radius_attr_hdr *radius_msg_add_attr(struct radius_msg *msg, u8 type,
const u8 *data, size_t data_len)
+{
+ return radius_msg_add_attr_frag(msg, type, 0, NULL, NULL, data,
+ data_len);
+}
+
+struct radius_attr_hdr * radius_msg_add_attr_frag(struct radius_msg *msg,
+ u8 type, int num_frag,
+ const u8 **frag,
+ const size_t *frag_len,
+ const u8 *data,
+ size_t data_len)
{
size_t buf_needed;
struct radius_attr_hdr *attr;
+ int i;
if (TEST_FAIL())
return NULL;
- if (data_len > RADIUS_MAX_ATTR_LEN) {
+ buf_needed = sizeof(*attr) + data_len;
+ for (i = 0; i < num_frag; i++)
+ buf_needed += frag_len[i];
+
+ if (buf_needed > sizeof(*attr) + RADIUS_MAX_ATTR_LEN) {
wpa_printf(MSG_ERROR, "radius_msg_add_attr: too long attribute (%lu bytes)",
- (unsigned long) data_len);
+ (unsigned long) (buf_needed - sizeof(*attr)));
return NULL;
}
- buf_needed = sizeof(*attr) + data_len;
-
if (wpabuf_tailroom(msg->buf) < buf_needed) {
/* allocate more space for message buffer */
if (wpabuf_resize(&msg->buf, buf_needed) < 0)
@@ -653,7 +667,9 @@ struct radius_attr_hdr *radius_msg_add_attr(struct radius_msg *msg, u8 type,
attr = wpabuf_put(msg->buf, sizeof(struct radius_attr_hdr));
attr->type = type;
- attr->length = sizeof(*attr) + data_len;
+ attr->length = buf_needed;
+ for (i = 0; i < num_frag; i++)
+ wpabuf_put_data(msg->buf, frag[i], frag_len[i]);
wpabuf_put_data(msg->buf, data, data_len);
if (radius_msg_add_attr_to_array(msg, attr))
@@ -1262,22 +1278,16 @@ int radius_msg_add_wfa(struct radius_msg *msg, u8 subtype, const u8 *data,
size_t len)
{
struct radius_attr_hdr *attr;
- u8 *buf, *pos;
- size_t alen;
+ u8 buf[6];
+ size_t buflen = sizeof(buf);
- alen = 4 + 2 + len;
- buf = os_malloc(alen);
- if (buf == NULL)
- return 0;
- pos = buf;
- WPA_PUT_BE32(pos, RADIUS_VENDOR_ID_WFA);
- pos += 4;
- *pos++ = subtype;
- *pos++ = 2 + len;
- os_memcpy(pos, data, len);
- attr = radius_msg_add_attr(msg, RADIUS_ATTR_VENDOR_SPECIFIC,
- buf, alen);
- os_free(buf);
+ WPA_PUT_BE32(buf, RADIUS_VENDOR_ID_WFA);
+ buf[4] = subtype;
+ buf[5] = 2 + len;
+
+ const u8 *bufptr = buf;
+ attr = radius_msg_add_attr_frag(msg, RADIUS_ATTR_VENDOR_SPECIFIC,
+ 1, &bufptr, &buflen, data, len);
if (attr == NULL)
return 0;
diff --git a/src/radius/radius.h b/src/radius/radius.h
index fb8148180..3dc73bdc5 100644
--- a/src/radius/radius.h
+++ b/src/radius/radius.h
@@ -257,6 +257,12 @@ int radius_msg_verify_acct_req(struct radius_msg *msg, const u8 *secret,
int radius_msg_verify_das_req(struct radius_msg *msg, const u8 *secret,
size_t secret_len,
int require_message_authenticator);
+struct radius_attr_hdr * radius_msg_add_attr_frag(struct radius_msg *msg,
+ u8 type, int num_frag,
+ const u8 **frag,
+ const size_t *frag_len,
+ const u8 *data,
+ size_t data_len);
struct radius_attr_hdr * radius_msg_add_attr(struct radius_msg *msg, u8 type,
const u8 *data, size_t data_len);
struct radius_msg * radius_msg_parse(const u8 *data, size_t len);
--
2.20.1
More information about the Hostap
mailing list