net-lwip: tftp: add LMB and buffer checks
Legacy NET tftp 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:
@@ -8,6 +8,7 @@
|
|||||||
#include <efi_loader.h>
|
#include <efi_loader.h>
|
||||||
#include <image.h>
|
#include <image.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
|
#include <linux/kconfig.h>
|
||||||
#include <lwip/apps/tftp_client.h>
|
#include <lwip/apps/tftp_client.h>
|
||||||
#include <lwip/timeouts.h>
|
#include <lwip/timeouts.h>
|
||||||
#include <mapmem.h>
|
#include <mapmem.h>
|
||||||
@@ -31,6 +32,47 @@ struct tftp_ctx {
|
|||||||
enum done_state done;
|
enum done_state done;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 tftp_ctx *ctx, void *src, u16_t len)
|
||||||
|
{
|
||||||
|
ulong store_addr = ctx->daddr;
|
||||||
|
void *ptr;
|
||||||
|
|
||||||
|
if (CONFIG_IS_ENABLED(LMB)) {
|
||||||
|
if (store_addr + len < store_addr ||
|
||||||
|
lmb_read_check(store_addr, len)) {
|
||||||
|
puts("\nTFTP error: ");
|
||||||
|
puts("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;
|
||||||
|
ctx->block_count++;
|
||||||
|
if (ctx->block_count % 10 == 0) {
|
||||||
|
putc('#');
|
||||||
|
if (ctx->block_count % (65 * 10) == 0)
|
||||||
|
puts("\n\t ");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void *tftp_open(const char *fname, const char *mode, u8_t is_write)
|
static void *tftp_open(const char *fname, const char *mode, u8_t is_write)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -71,17 +113,9 @@ static int tftp_write(void *handle, struct pbuf *p)
|
|||||||
struct tftp_ctx *ctx = handle;
|
struct tftp_ctx *ctx = handle;
|
||||||
struct pbuf *q;
|
struct pbuf *q;
|
||||||
|
|
||||||
for (q = p; q; q = q->next) {
|
for (q = p; q; q = q->next)
|
||||||
memcpy((void *)ctx->daddr, q->payload, q->len);
|
if (store_block(ctx, q->payload, q->len) < 0)
|
||||||
ctx->daddr += q->len;
|
return -1;
|
||||||
ctx->size += q->len;
|
|
||||||
ctx->block_count++;
|
|
||||||
if (ctx->block_count % 10 == 0) {
|
|
||||||
putc('#');
|
|
||||||
if (ctx->block_count % (65 * 10) == 0)
|
|
||||||
puts("\n\t ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user