net-lwip: wget: add LMB and buffer checks
Legacy NET wget invokes a store_block() function which performs buffer validation (LMB, address wrapping). Do the same with NET_LWIP. Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org> Suggested-by: Sughosh Ganu <sughosh.ganu@linaro.org> Acked-by: Sughosh Ganu <sughosh.ganu@linaro.org> Tested-by: Sughosh Ganu <sughosh.ganu@linaro.org>
This commit is contained in:
@@ -6,6 +6,7 @@
|
|||||||
#include <display_options.h>
|
#include <display_options.h>
|
||||||
#include <efi_loader.h>
|
#include <efi_loader.h>
|
||||||
#include <image.h>
|
#include <image.h>
|
||||||
|
#include <linux/kconfig.h>
|
||||||
#include <lwip/apps/http_client.h>
|
#include <lwip/apps/http_client.h>
|
||||||
#include "lwip/altcp_tls.h"
|
#include "lwip/altcp_tls.h"
|
||||||
#include <lwip/errno.h>
|
#include <lwip/errno.h>
|
||||||
@@ -202,11 +203,58 @@ static int parse_legacy_arg(char *arg, char *nurl, size_t rem)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* store_block() - copy received data
|
||||||
|
*
|
||||||
|
* This function is called by the receive callback to copy a block of data
|
||||||
|
* into its final location (ctx->daddr). Before doing so, it checks if the copy
|
||||||
|
* is allowed.
|
||||||
|
*
|
||||||
|
* @ctx: the context for the current transfer
|
||||||
|
* @src: the data received from the TCP stack
|
||||||
|
* @len: the length of the data
|
||||||
|
*/
|
||||||
|
static int store_block(struct wget_ctx *ctx, void *src, u16_t len)
|
||||||
|
{
|
||||||
|
ulong store_addr = ctx->daddr;
|
||||||
|
uchar *ptr;
|
||||||
|
|
||||||
|
/* Avoid overflow */
|
||||||
|
if (wget_info->buffer_size && wget_info->buffer_size < ctx->size + len)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (CONFIG_IS_ENABLED(LMB) && wget_info->set_bootdev) {
|
||||||
|
if (store_addr + len < store_addr ||
|
||||||
|
lmb_read_check(store_addr, len)) {
|
||||||
|
if (!wget_info->silent) {
|
||||||
|
printf("\nwget error: ");
|
||||||
|
printf("trying to overwrite reserved memory\n");
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr = map_sysmem(store_addr, len);
|
||||||
|
memcpy(ptr, src, len);
|
||||||
|
unmap_sysmem(ptr);
|
||||||
|
|
||||||
|
ctx->daddr += len;
|
||||||
|
ctx->size += len;
|
||||||
|
if (ctx->size - ctx->prevsize > PROGRESS_PRINT_STEP_BYTES) {
|
||||||
|
if (!wget_info->silent)
|
||||||
|
printf("#");
|
||||||
|
ctx->prevsize = ctx->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static err_t httpc_recv_cb(void *arg, struct altcp_pcb *pcb, struct pbuf *pbuf,
|
static err_t httpc_recv_cb(void *arg, struct altcp_pcb *pcb, struct pbuf *pbuf,
|
||||||
err_t err)
|
err_t err)
|
||||||
{
|
{
|
||||||
struct wget_ctx *ctx = arg;
|
struct wget_ctx *ctx = arg;
|
||||||
struct pbuf *buf;
|
struct pbuf *buf;
|
||||||
|
err_t ret;
|
||||||
|
|
||||||
if (!pbuf)
|
if (!pbuf)
|
||||||
return ERR_BUF;
|
return ERR_BUF;
|
||||||
@@ -215,19 +263,17 @@ static err_t httpc_recv_cb(void *arg, struct altcp_pcb *pcb, struct pbuf *pbuf,
|
|||||||
ctx->start_time = get_timer(0);
|
ctx->start_time = get_timer(0);
|
||||||
|
|
||||||
for (buf = pbuf; buf; buf = buf->next) {
|
for (buf = pbuf; buf; buf = buf->next) {
|
||||||
memcpy((void *)ctx->daddr, buf->payload, buf->len);
|
if (store_block(ctx, buf->payload, buf->len) < 0) {
|
||||||
ctx->daddr += buf->len;
|
altcp_abort(pcb);
|
||||||
ctx->size += buf->len;
|
ret = ERR_BUF;
|
||||||
if (!wget_info->silent &&
|
goto out;
|
||||||
ctx->size - ctx->prevsize > PROGRESS_PRINT_STEP_BYTES) {
|
|
||||||
printf("#");
|
|
||||||
ctx->prevsize = ctx->size;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
altcp_recved(pcb, pbuf->tot_len);
|
altcp_recved(pcb, pbuf->tot_len);
|
||||||
|
ret = ERR_OK;
|
||||||
|
out:
|
||||||
pbuf_free(pbuf);
|
pbuf_free(pbuf);
|
||||||
return ERR_OK;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void httpc_result_cb(void *arg, httpc_result_t httpc_result,
|
static void httpc_result_cb(void *arg, httpc_result_t httpc_result,
|
||||||
|
Reference in New Issue
Block a user