Coverity complained about this code and is partially right. We are not
really protected against integer overflows. Sure, unlikely, but lets just
avoid any overflows and properly protect our parser loop.
uint32_t id, counter;
grdrm_object *object;
char buf[4096];
uint32_t id, counter;
grdrm_object *object;
char buf[4096];
+ size_t len;
+ ssize_t l;
if (revents & (EPOLLHUP | EPOLLERR)) {
/* Immediately close device on HUP; no need to flush pending
if (revents & (EPOLLHUP | EPOLLERR)) {
/* Immediately close device on HUP; no need to flush pending
log_debug("grdrm: %s/%s: read error: %m", card->base.session->name, card->base.name);
grdrm_card_close(card);
return 0;
log_debug("grdrm: %s/%s: read error: %m", card->base.session->name, card->base.name);
grdrm_card_close(card);
return 0;
- } else if ((size_t)l < sizeof(*event)) {
- log_debug("grdrm: %s/%s: short read of %zd bytes", card->base.session->name, card->base.name, l);
- return 0;
- for (i = 0; i < l; i += event->length) {
- event = (void*)&buf[i];
+ for (len = l; len > 0; len -= event->length) {
+ event = (void*)buf;
- if (i + (ssize_t)sizeof(*event) > l || i + (ssize_t)event->length > l) {
+ if (len < sizeof(*event) || len < event->length) {
log_debug("grdrm: %s/%s: truncated event", card->base.session->name, card->base.name);
break;
}
log_debug("grdrm: %s/%s: truncated event", card->base.session->name, card->base.name);
break;
}