提交 62d494e1 编写于 作者: Z zhangtian 提交者: jun-ping

BugID:23325808:[coap]fix memory out of bounds risk issue

Change-Id: Ib1f8b0759e82aeb15d3fe3c759006ee0729f24f8
Reviewed-on: http://yuncode.alibaba-inc.com/c/alios_things_rtos_core/+/240357Tested-by: N李诚 lc122798 <lc122798@alibaba-inc.com>
Reviewed-by: N于海龙 hailong.yhl <hailong.yhl@alibaba-inc.com>
Tested-by: N于海龙 hailong.yhl <hailong.yhl@alibaba-inc.com>
Reviewed-by: N庞军平 junping.pjp <junping.pjp@alibaba-inc.com>
上级 00c77fda
......@@ -23,11 +23,28 @@ int CoAPDeserialize_Header(CoAPMessage *msg, unsigned char *buf)
int CoAPDeserialize_Token(CoAPMessage *msg, unsigned char *buf)
{
memcpy(msg->token, buf, msg->header.tokenlen);
memcpy(msg->token, buf, msg->header.tokenlen > COAP_MSG_MAX_TOKEN_LEN ? COAP_MSG_MAX_TOKEN_LEN : msg->header.tokenlen);
return msg->header.tokenlen;
}
static int CoAPDeserialize_Option(CoAPMsgOption *option, unsigned char *buf, unsigned short *predeltas)
#define COAP_OPT(o,e,step) if ((e) < step) { \
return -1; \
} else { \
(e) -= step; \
(o) = ((o)) + step; \
}
/*
* Used to prevent access to *option when pointing to after end of buffer
* after doing a COAP_OPT()
*/
#define COAP_OPT_CHECK(o,e,step) do { \
COAP_OPT(o,e,step); \
if ((e) < 1) \
return -1; \
} while (0)
static int CoAPDeserialize_Option(CoAPMsgOption *option, unsigned char *buf, int left, unsigned short *predeltas)
{
unsigned char *ptr = buf;
unsigned short optdelta = 0;
......@@ -36,18 +53,17 @@ static int CoAPDeserialize_Option(CoAPMsgOption *option, unsigned char *buf, uns
optdelta = (*ptr & 0xF0) >> 4;
optlen = (*ptr & 0x0F);
ptr++;
COAP_OPT_CHECK(ptr, left, 1);
predelta = *predeltas;
if (13 == optdelta) {
predelta += 13 + *ptr;
ptr ++;
COAP_OPT_CHECK(ptr, left, 1);
} else if (14 == optdelta) {
predelta += 269;
predelta += (*ptr << 8);
predelta += *(ptr + 1);
ptr += 2;
COAP_OPT_CHECK(ptr, left, 2);
} else {
predelta += optdelta;
}
......@@ -55,12 +71,15 @@ static int CoAPDeserialize_Option(CoAPMsgOption *option, unsigned char *buf, uns
if (13 == optlen) {
optlen = 13 + *ptr;
ptr ++;
COAP_OPT_CHECK(ptr, left, 1);
} else if (14 == optlen) {
optlen = 269;
optlen += (*ptr << 8);
optlen += *(ptr + 1);
ptr += 2;
optlen = (*ptr << 8) + (*(ptr + 1));
if (optlen + 269 < 269) {
return -1;
}
optlen += 269;
COAP_OPT_CHECK(ptr, left, 2);
}
option->len = optlen;
......@@ -73,18 +92,21 @@ static int CoAPDeserialize_Option(CoAPMsgOption *option, unsigned char *buf, uns
int CoAPDeserialize_Options(CoAPMessage *msg, unsigned char *buf, int buflen)
{
int index = 0;
int count = 0;
unsigned char *ptr = buf;
unsigned short len = 0;
int len = 0;
int left = buflen;
unsigned short optdeltas = 0;
msg->optcount = 0;
while ((count < buflen) && (0xFF != *ptr)) {
len = CoAPDeserialize_Option(&msg->options[index], ptr, &optdeltas);
while (left > 0 && (0xFF != *ptr) && index < COAP_MSG_MAX_OPTION_NUM) {
len = CoAPDeserialize_Option(&msg->options[index], ptr, left, &optdeltas);
if (len < 0) {
return len;
}
msg->optcount += 1;
ptr += len;
left -= len;
index ++;
count += len;
}
return (int)(ptr - buf);
......@@ -121,15 +143,24 @@ int CoAPDeserialize_Message(CoAPMessage *msg, unsigned char *buf, int buflen)
/* Deserialize CoAP header. */
count = CoAPDeserialize_Header(msg, ptr);
if (count > remlen) {
return COAP_ERROR_INVALID_LENGTH;
}
ptr += count;
remlen -= count;
/* Deserialize the token, if any. */
count = CoAPDeserialize_Token(msg, ptr);
if (count > remlen) {
return COAP_ERROR_INVALID_LENGTH;
}
ptr += count;
remlen -= count;
count = CoAPDeserialize_Options(msg, ptr, remlen);
if (count > remlen || count < 0) {
return COAP_ERROR_INVALID_LENGTH;
}
ptr += count;
remlen -= count;
......
......@@ -2,9 +2,6 @@
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#include <stdio.h>
#include "CoAPExport.h"
......@@ -22,11 +19,28 @@ int CoAPDeserialize_Header(CoAPMessage *msg, unsigned char *buf)
int CoAPDeserialize_Token(CoAPMessage *msg, unsigned char *buf)
{
memcpy(msg->token, buf, msg->header.tokenlen);
memcpy(msg->token, buf, msg->header.tokenlen > COAP_MSG_MAX_TOKEN_LEN ? COAP_MSG_MAX_TOKEN_LEN : msg->header.tokenlen);
return msg->header.tokenlen;
}
static int CoAPDeserialize_Option(CoAPMsgOption *option, unsigned char *buf, unsigned short *predeltas)
#define COAP_OPT(o,e,step) if ((e) < step) { \
return -1; \
} else { \
(e) -= step; \
(o) = ((o)) + step; \
}
/*
* Used to prevent access to *option when pointing to after end of buffer
* after doing a COAP_OPT()
*/
#define COAP_OPT_CHECK(o,e,step) do { \
COAP_OPT(o,e,step); \
if ((e) < 1) \
return -1; \
} while (0)
static int CoAPDeserialize_Option(CoAPMsgOption *option, unsigned char *buf, int left, unsigned short *predeltas)
{
unsigned char *ptr = buf;
unsigned short optdelta = 0;
......@@ -35,18 +49,17 @@ static int CoAPDeserialize_Option(CoAPMsgOption *option, unsigned char *buf, uns
optdelta = (*ptr & 0xF0) >> 4;
optlen = (*ptr & 0x0F);
ptr++;
COAP_OPT_CHECK(ptr, left, 1);
predelta = *predeltas;
if (13 == optdelta) {
predelta += 13 + *ptr;
ptr ++;
COAP_OPT_CHECK(ptr, left, 1);
} else if (14 == optdelta) {
predelta += 269;
predelta += (*ptr << 8);
predelta += *(ptr + 1);
ptr += 2;
COAP_OPT_CHECK(ptr, left, 2);
} else {
predelta += optdelta;
}
......@@ -54,12 +67,15 @@ static int CoAPDeserialize_Option(CoAPMsgOption *option, unsigned char *buf, uns
if (13 == optlen) {
optlen = 13 + *ptr;
ptr ++;
COAP_OPT_CHECK(ptr, left, 1);
} else if (14 == optlen) {
optlen = 269;
optlen += (*ptr << 8);
optlen += *(ptr + 1);
ptr += 2;
optlen = (*ptr << 8) + (*(ptr + 1));
if (optlen + 269 < 269) {
return -1;
}
optlen += 269;
COAP_OPT_CHECK(ptr, left, 2);
}
option->len = optlen;
......@@ -72,18 +88,21 @@ static int CoAPDeserialize_Option(CoAPMsgOption *option, unsigned char *buf, uns
int CoAPDeserialize_Options(CoAPMessage *msg, unsigned char *buf, int buflen)
{
int index = 0;
int count = 0;
unsigned char *ptr = buf;
unsigned short len = 0;
int len = 0;
int left = buflen;
unsigned short optdeltas = 0;
msg->optnum = 0;
while ((count < buflen) && (0xFF != *ptr)) {
len = CoAPDeserialize_Option(&msg->options[index], ptr, &optdeltas);
while (left > 0 && (0xFF != *ptr) && index < COAP_MSG_MAX_OPTION_NUM) {
len = CoAPDeserialize_Option(&msg->options[index], ptr, left, &optdeltas);
if (len < 0) {
return len;
}
msg->optnum += 1;
ptr += len;
left -= len;
index ++;
count += len;
}
return (int)(ptr - buf);
......@@ -120,15 +139,24 @@ int CoAPDeserialize_Message(CoAPMessage *msg, unsigned char *buf, int buflen)
/* Deserialize CoAP header. */
count = CoAPDeserialize_Header(msg, ptr);
if (count > remlen) {
return COAP_ERROR_INVALID_LENGTH;
}
ptr += count;
remlen -= count;
/* Deserialize the token, if any. */
count = CoAPDeserialize_Token(msg, ptr);
if (count > remlen) {
return COAP_ERROR_INVALID_LENGTH;
}
ptr += count;
remlen -= count;
count = CoAPDeserialize_Options(msg, ptr, remlen);
if (count > remlen || count < 0) {
return COAP_ERROR_INVALID_LENGTH;
}
ptr += count;
remlen -= count;
......@@ -136,3 +164,4 @@ int CoAPDeserialize_Message(CoAPMessage *msg, unsigned char *buf, int buflen)
return COAP_SUCCESS;
}
......@@ -129,7 +129,7 @@ static int iotx_parse_auth_from_json(char *p_str, iotx_coap_t *p_iotx_coap)
lite_cjson_t node;
unsigned char key[32] = {0};
unsigned char buff[128] = {0};
unsigned char random[32] = {0};
unsigned char random[32 + 1] = {0};
if(NULL == p_str || NULL == p_iotx_coap){
return IOTX_ERR_INVALID_PARAM;
......@@ -164,7 +164,9 @@ static int iotx_parse_auth_from_json(char *p_str, iotx_coap_t *p_iotx_coap)
if(-1 == ret){
return IOTX_ERR_AUTH_FAILED;
}
if(node.value_length > 32) {
return IOTX_ERR_BUFF_TOO_SHORT;
}
memcpy(random, node.value, node.value_length);
HAL_Snprintf((char *)buff, sizeof(buff), "%s,%s",
p_iotx_coap->p_devinfo->device_secret, random);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册