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:
Olaf Bergmann committed 2012-07-05 16:56:40 +02:00
1 parent a3f8fdaa59
commit e3c81ec1b6
2 files changed
+28 -7

No files matched your search

+20
View File
@@ -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);
}
+8 -7
View File
@@ -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 *