mirror of
https://github.com/obgm/libcoap.git
synced 2026-11-12 11:40:39 +03:00
partially fixed bug invalid reads in option.c - ID: 3538692
applied patch provided by John Sucaet small fix in coap_read() to avoid potential crashes
This commit is contained in:
1 parent
a3f8fdaa59
commit
e3c81ec1b6
2 files changed
+28
-7
No files matched your search
@@ -610,6 +610,20 @@ _order_transaction_id( coap_queue_t *lhs, coap_queue_t *rhs ) {
|
||||
: 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if @p opt fits into the message that ends with @p maxpos.
|
||||
* This function returns @c 1 on success, or @c 0 if the option @p opt
|
||||
* would exceed @p maxpos.
|
||||
*/
|
||||
static inline int
|
||||
check_opt_size(coap_opt_t *opt, unsigned char *maxpos) {
|
||||
if (opt && opt < maxpos) {
|
||||
if (((*opt & 0x0f) < 0x0f) || (opt + 1 < maxpos))
|
||||
return opt + COAP_OPT_SIZE(opt) < maxpos;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
coap_read( coap_context_t *ctx ) {
|
||||
#ifndef WITH_CONTIKI
|
||||
@@ -707,6 +721,12 @@ coap_read( coap_context_t *ctx ) {
|
||||
} else {
|
||||
--cnt;
|
||||
}
|
||||
|
||||
if (cnt &&
|
||||
!check_opt_size(opt, (unsigned char *)node->pdu->hdr + node->pdu->max_size)) {
|
||||
debug("drop\n");
|
||||
goto error;
|
||||
}
|
||||
opt = options_next(opt);
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ coap_option_iterator_init(coap_pdu_t *pdu, coap_opt_iterator_t *oi,
|
||||
}
|
||||
|
||||
#define IS_EMPTY_NOOP(Type,Option) \
|
||||
((Type) % COAP_OPTION_NOOP == 0 && COAP_OPT_LENGTH(Option) == 0)
|
||||
(((Type) % COAP_OPTION_NOOP == 0) && (COAP_OPT_LENGTH(Option) == 0))
|
||||
|
||||
#define opt_finished(oi) ((oi)->optcnt == COAP_OPT_LONG \
|
||||
? ((oi)->option && *((oi)->option) == COAP_OPT_END) \
|
||||
@@ -56,24 +56,25 @@ coap_option_next(coap_opt_iterator_t *oi) {
|
||||
/* proceed to next option */
|
||||
if (oi->n++) {
|
||||
oi->option = options_next(oi->option);
|
||||
if (opt_finished(oi))
|
||||
return NULL;
|
||||
oi->type += COAP_OPT_DELTA(oi->option);
|
||||
}
|
||||
|
||||
/* Skip subsequent options if it is an empty no-op (used for
|
||||
* fence-posting) or the filter bit is not set. */
|
||||
while (!opt_finished(oi) &&
|
||||
(IS_EMPTY_NOOP(oi->type, oi->option)
|
||||
|| coap_option_getb(oi->filter, oi->type) == 0)) {
|
||||
while (oi->option && (IS_EMPTY_NOOP(oi->type, oi->option)
|
||||
|| coap_option_getb(oi->filter, oi->type) == 0)) {
|
||||
oi->n++;
|
||||
oi->option = options_next(oi->option);
|
||||
|
||||
if (opt_finished(oi))
|
||||
break;
|
||||
if (!oi->option || opt_finished(oi))
|
||||
return NULL;
|
||||
|
||||
oi->type += COAP_OPT_DELTA(oi->option);
|
||||
}
|
||||
|
||||
return opt_finished(oi) ? NULL : oi->option;
|
||||
return oi->option;
|
||||
}
|
||||
|
||||
coap_opt_t *
|
||||
|
||||
Reference in new issue
Block a user