mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2026-06-13 15:03:58 +03:00
Merge tag 'net-20250520' of https://source.denx.de/u-boot/custodians/u-boot-net
Pull request net-20250520. CI: https://source.denx.de/u-boot/custodians/u-boot-net/-/pipelines/26247 net, net-lwip: - Remove wget console output when called by EFI net-lwip: - Add 10 s timeout to TFTP - Add LMB buffer checks
This commit is contained in:
@@ -141,9 +141,9 @@ https://cacerts.digicert.com/DigiCertTLSRSA4096RootG5.crt.
|
||||
Bytes transferred = 1864 (748 hex)
|
||||
# Another server not signed against Digicert will fail
|
||||
=> wget https://www.google.com/
|
||||
Certificate verification failed
|
||||
|
||||
HTTP client error 4
|
||||
Certificate verification failed
|
||||
# Disable authentication to allow the command to proceed anyways
|
||||
=> wget cacert none
|
||||
=> wget https://www.google.com/
|
||||
|
||||
@@ -570,6 +570,7 @@ enum wget_http_method {
|
||||
* Filled by client.
|
||||
* @hdr_cont_len: content length according to headers. Filled by wget
|
||||
* @headers: buffer for headers. Filled by wget.
|
||||
* @silent: do not print anything to the console. Filled by client.
|
||||
*/
|
||||
struct wget_http_info {
|
||||
enum wget_http_method method;
|
||||
@@ -580,6 +581,7 @@ struct wget_http_info {
|
||||
bool check_buffer_size;
|
||||
u32 hdr_cont_len;
|
||||
char *headers;
|
||||
bool silent;
|
||||
};
|
||||
|
||||
extern struct wget_http_info default_wget_info;
|
||||
|
||||
@@ -51,7 +51,7 @@ static int next_dp_entry;
|
||||
static struct wget_http_info efi_wget_info = {
|
||||
.set_bootdev = false,
|
||||
.check_buffer_size = true,
|
||||
|
||||
.silent = true,
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
@@ -60,6 +60,8 @@
|
||||
|
||||
#if LWIP_ALTCP_TLS && LWIP_ALTCP_TLS_MBEDTLS
|
||||
|
||||
#include "lwip/errno.h"
|
||||
|
||||
#include "lwip/altcp.h"
|
||||
#include "lwip/altcp_tls.h"
|
||||
#include "lwip/priv/altcp_priv.h"
|
||||
@@ -299,7 +301,8 @@ altcp_mbedtls_lower_recv_process(struct altcp_pcb *conn, altcp_mbedtls_state_t *
|
||||
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ssl_handshake failed: %d\n", ret));
|
||||
/* handshake failed, connection has to be closed */
|
||||
if (ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) {
|
||||
printf("Certificate verification failed\n");
|
||||
/* provide a cause for why the connection is closed to the called */
|
||||
errno = EPERM;
|
||||
}
|
||||
if (conn->err) {
|
||||
conn->err(conn->arg, ERR_CLSD);
|
||||
@@ -844,9 +847,6 @@ altcp_tls_create_config(int is_server, u8_t cert_count, u8_t pkey_count, int hav
|
||||
altcp_mbedtls_free_config(conf);
|
||||
return NULL;
|
||||
}
|
||||
if (authmode == MBEDTLS_SSL_VERIFY_NONE) {
|
||||
printf("WARNING: no CA certificates, HTTPS connections not authenticated\n");
|
||||
}
|
||||
mbedtls_ssl_conf_authmode(&conf->conf, authmode);
|
||||
|
||||
mbedtls_ssl_conf_rng(&conf->conf, mbedtls_ctr_drbg_random, &altcp_tls_entropy_rng->ctr_drbg);
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <efi_loader.h>
|
||||
#include <image.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/kconfig.h>
|
||||
#include <lwip/apps/tftp_client.h>
|
||||
#include <lwip/timeouts.h>
|
||||
#include <mapmem.h>
|
||||
@@ -15,6 +16,8 @@
|
||||
#include <time.h>
|
||||
|
||||
#define PROGRESS_PRINT_STEP_BYTES (10 * 1024)
|
||||
/* Max time to wait for first data packet from server */
|
||||
#define NO_RSP_TIMEOUT_MS 10000
|
||||
|
||||
enum done_state {
|
||||
NOT_DONE = 0,
|
||||
@@ -31,6 +34,47 @@ struct tftp_ctx {
|
||||
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)
|
||||
{
|
||||
return NULL;
|
||||
@@ -71,17 +115,9 @@ static int tftp_write(void *handle, struct pbuf *p)
|
||||
struct tftp_ctx *ctx = handle;
|
||||
struct pbuf *q;
|
||||
|
||||
for (q = p; q; q = q->next) {
|
||||
memcpy((void *)ctx->daddr, q->payload, q->len);
|
||||
ctx->daddr += q->len;
|
||||
ctx->size += q->len;
|
||||
ctx->block_count++;
|
||||
if (ctx->block_count % 10 == 0) {
|
||||
putc('#');
|
||||
if (ctx->block_count % (65 * 10) == 0)
|
||||
puts("\n\t ");
|
||||
}
|
||||
}
|
||||
for (q = p; q; q = q->next)
|
||||
if (store_block(ctx, q->payload, q->len) < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -106,6 +142,17 @@ static const struct tftp_context tftp_context = {
|
||||
tftp_error
|
||||
};
|
||||
|
||||
static void no_response(void *arg)
|
||||
{
|
||||
struct tftp_ctx *ctx = (struct tftp_ctx *)arg;
|
||||
|
||||
if (ctx->size)
|
||||
return;
|
||||
|
||||
printf("Timeout!\n");
|
||||
ctx->done = FAILURE;
|
||||
}
|
||||
|
||||
static int tftp_loop(struct udevice *udev, ulong addr, char *fname,
|
||||
ip_addr_t srvip, uint16_t srvport)
|
||||
{
|
||||
@@ -150,6 +197,7 @@ static int tftp_loop(struct udevice *udev, ulong addr, char *fname,
|
||||
return -1;
|
||||
}
|
||||
|
||||
sys_timeout(NO_RSP_TIMEOUT_MS, no_response, &ctx);
|
||||
while (!ctx.done) {
|
||||
net_lwip_rx(udev, netif);
|
||||
sys_check_timeouts();
|
||||
@@ -159,6 +207,7 @@ static int tftp_loop(struct udevice *udev, ulong addr, char *fname,
|
||||
break;
|
||||
}
|
||||
}
|
||||
sys_untimeout(no_response, (void *)&ctx);
|
||||
|
||||
tftp_cleanup();
|
||||
|
||||
|
||||
122
net/lwip/wget.c
122
net/lwip/wget.c
@@ -6,8 +6,10 @@
|
||||
#include <display_options.h>
|
||||
#include <efi_loader.h>
|
||||
#include <image.h>
|
||||
#include <linux/kconfig.h>
|
||||
#include <lwip/apps/http_client.h>
|
||||
#include "lwip/altcp_tls.h"
|
||||
#include <lwip/errno.h>
|
||||
#include <lwip/timeouts.h>
|
||||
#include <rng.h>
|
||||
#include <mapmem.h>
|
||||
@@ -201,11 +203,58 @@ static int parse_legacy_arg(char *arg, char *nurl, size_t rem)
|
||||
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,
|
||||
err_t err)
|
||||
{
|
||||
struct wget_ctx *ctx = arg;
|
||||
struct pbuf *buf;
|
||||
err_t ret;
|
||||
|
||||
if (!pbuf)
|
||||
return ERR_BUF;
|
||||
@@ -214,18 +263,17 @@ static err_t httpc_recv_cb(void *arg, struct altcp_pcb *pcb, struct pbuf *pbuf,
|
||||
ctx->start_time = get_timer(0);
|
||||
|
||||
for (buf = pbuf; buf; buf = buf->next) {
|
||||
memcpy((void *)ctx->daddr, buf->payload, buf->len);
|
||||
ctx->daddr += buf->len;
|
||||
ctx->size += buf->len;
|
||||
if (ctx->size - ctx->prevsize > PROGRESS_PRINT_STEP_BYTES) {
|
||||
printf("#");
|
||||
ctx->prevsize = ctx->size;
|
||||
if (store_block(ctx, buf->payload, buf->len) < 0) {
|
||||
altcp_abort(pcb);
|
||||
ret = ERR_BUF;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
altcp_recved(pcb, pbuf->tot_len);
|
||||
ret = ERR_OK;
|
||||
out:
|
||||
pbuf_free(pbuf);
|
||||
return ERR_OK;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void httpc_result_cb(void *arg, httpc_result_t httpc_result,
|
||||
@@ -255,11 +303,15 @@ static void httpc_result_cb(void *arg, httpc_result_t httpc_result,
|
||||
elapsed = get_timer(ctx->start_time);
|
||||
if (!elapsed)
|
||||
elapsed = 1;
|
||||
if (rx_content_len > PROGRESS_PRINT_STEP_BYTES)
|
||||
printf("\n");
|
||||
printf("%u bytes transferred in %lu ms (", rx_content_len, elapsed);
|
||||
print_size(rx_content_len / elapsed * 1000, "/s)\n");
|
||||
printf("Bytes transferred = %lu (%lx hex)\n", ctx->size, ctx->size);
|
||||
if (!wget_info->silent) {
|
||||
if (rx_content_len > PROGRESS_PRINT_STEP_BYTES)
|
||||
printf("\n");
|
||||
printf("%u bytes transferred in %lu ms (", rx_content_len,
|
||||
elapsed);
|
||||
print_size(rx_content_len / elapsed * 1000, "/s)\n");
|
||||
printf("Bytes transferred = %lu (%lx hex)\n", ctx->size,
|
||||
ctx->size);
|
||||
}
|
||||
if (wget_info->set_bootdev)
|
||||
efi_set_bootdev("Http", ctx->server_name, ctx->path, map_sysmem(ctx->saved_daddr, 0),
|
||||
rx_content_len);
|
||||
@@ -339,7 +391,8 @@ static int _set_cacert(const void *addr, size_t sz)
|
||||
mbedtls_x509_crt_init(&crt);
|
||||
ret = mbedtls_x509_crt_parse(&crt, cacert, cacert_size);
|
||||
if (ret) {
|
||||
printf("Could not parse certificates (%d)\n", ret);
|
||||
if (!wget_info->silent)
|
||||
printf("Could not parse certificates (%d)\n", ret);
|
||||
free(cacert);
|
||||
cacert = NULL;
|
||||
cacert_size = 0;
|
||||
@@ -372,13 +425,14 @@ static int set_cacert(char * const saddr, char * const ssz)
|
||||
#endif
|
||||
#endif /* CONFIG_WGET_CACERT || CONFIG_WGET_BUILTIN_CACERT */
|
||||
|
||||
static int wget_loop(struct udevice *udev, ulong dst_addr, char *uri)
|
||||
int wget_do_request(ulong dst_addr, char *uri)
|
||||
{
|
||||
#if CONFIG_IS_ENABLED(WGET_HTTPS)
|
||||
altcp_allocator_t tls_allocator;
|
||||
#endif
|
||||
httpc_connection_t conn;
|
||||
httpc_state_t *state;
|
||||
struct udevice *udev;
|
||||
struct netif *netif;
|
||||
struct wget_ctx ctx;
|
||||
char *path;
|
||||
@@ -394,6 +448,14 @@ static int wget_loop(struct udevice *udev, ulong dst_addr, char *uri)
|
||||
if (parse_url(uri, ctx.server_name, &ctx.port, &path, &is_https))
|
||||
return CMD_RET_USAGE;
|
||||
|
||||
if (net_lwip_eth_start() < 0)
|
||||
return CMD_RET_FAILURE;
|
||||
|
||||
if (!wget_info)
|
||||
wget_info = &default_wget_info;
|
||||
|
||||
udev = eth_get_dev();
|
||||
|
||||
netif = net_lwip_new_netif(udev);
|
||||
if (!netif)
|
||||
return -1;
|
||||
@@ -413,9 +475,10 @@ static int wget_loop(struct udevice *udev, ulong dst_addr, char *uri)
|
||||
|
||||
if (cacert_auth_mode == AUTH_REQUIRED) {
|
||||
if (!ca || !ca_sz) {
|
||||
printf("Error: cacert authentication mode is "
|
||||
"'required' but no CA certificates "
|
||||
"given\n");
|
||||
if (!wget_info->silent)
|
||||
printf("Error: cacert authentication "
|
||||
"mode is 'required' but no CA "
|
||||
"certificates given\n");
|
||||
return CMD_RET_FAILURE;
|
||||
}
|
||||
} else if (cacert_auth_mode == AUTH_NONE) {
|
||||
@@ -430,6 +493,10 @@ static int wget_loop(struct udevice *udev, ulong dst_addr, char *uri)
|
||||
*/
|
||||
}
|
||||
|
||||
if (!ca && !wget_info->silent) {
|
||||
printf("WARNING: no CA certificates, ");
|
||||
printf("HTTPS connections not authenticated\n");
|
||||
}
|
||||
tls_allocator.alloc = &altcp_tls_alloc;
|
||||
tls_allocator.arg =
|
||||
altcp_tls_create_config_client(ca, ca_sz,
|
||||
@@ -454,6 +521,8 @@ static int wget_loop(struct udevice *udev, ulong dst_addr, char *uri)
|
||||
return CMD_RET_FAILURE;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
|
||||
while (!ctx.done) {
|
||||
net_lwip_rx(udev, netif);
|
||||
sys_check_timeouts();
|
||||
@@ -466,23 +535,12 @@ static int wget_loop(struct udevice *udev, ulong dst_addr, char *uri)
|
||||
if (ctx.done == SUCCESS)
|
||||
return 0;
|
||||
|
||||
if (errno == EPERM && !wget_info->silent)
|
||||
printf("Certificate verification failed\n");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int wget_do_request(ulong dst_addr, char *uri)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = net_lwip_eth_start();
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (!wget_info)
|
||||
wget_info = &default_wget_info;
|
||||
|
||||
return wget_loop(eth_get_dev(), dst_addr, uri);
|
||||
}
|
||||
|
||||
int do_wget(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[])
|
||||
{
|
||||
char *end;
|
||||
|
||||
23
net/wget.c
23
net/wget.c
@@ -59,8 +59,10 @@ static inline int store_block(uchar *src, unsigned int offset, unsigned int len)
|
||||
if (CONFIG_IS_ENABLED(LMB) && wget_info->set_bootdev) {
|
||||
if (store_addr < image_load_addr ||
|
||||
lmb_read_check(store_addr, len)) {
|
||||
printf("\nwget error: ");
|
||||
printf("trying to overwrite reserved memory...\n");
|
||||
if (!wget_info->silent) {
|
||||
printf("\nwget error: ");
|
||||
printf("trying to overwrite reserved memory\n");
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -76,6 +78,9 @@ static void show_block_marker(u32 packets)
|
||||
{
|
||||
int cnt;
|
||||
|
||||
if (wget_info->silent)
|
||||
return;
|
||||
|
||||
if (content_length != -1) {
|
||||
if (net_boot_file_size > content_length)
|
||||
content_length = net_boot_file_size;
|
||||
@@ -101,11 +106,15 @@ static void tcp_stream_on_closed(struct tcp_stream *tcp)
|
||||
net_set_state(wget_loop_state);
|
||||
if (wget_loop_state != NETLOOP_SUCCESS) {
|
||||
net_boot_file_size = 0;
|
||||
printf("\nwget: Transfer Fail, TCP status - %d\n", tcp->status);
|
||||
if (!wget_info->silent)
|
||||
printf("\nwget: Transfer Fail, TCP status - %d\n",
|
||||
tcp->status);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("\nPackets received %d, Transfer Successful\n", tcp->rx_packets);
|
||||
if (!wget_info->silent)
|
||||
printf("\nPackets received %d, Transfer Successful\n",
|
||||
tcp->rx_packets);
|
||||
wget_info->file_size = net_boot_file_size;
|
||||
if (wget_info->method == WGET_HTTP_METHOD_GET && wget_info->set_bootdev) {
|
||||
efi_set_bootdev("Http", NULL, image_url,
|
||||
@@ -139,7 +148,8 @@ static void tcp_stream_on_rcv_nxt_update(struct tcp_stream *tcp, u32 rx_bytes)
|
||||
tcp->state == TCP_ESTABLISHED)
|
||||
goto end;
|
||||
|
||||
printf("ERROR: misssed HTTP header\n");
|
||||
if (!wget_info->silent)
|
||||
printf("ERROR: misssed HTTP header\n");
|
||||
tcp_stream_close(tcp);
|
||||
goto end;
|
||||
}
|
||||
@@ -346,7 +356,8 @@ void wget_start(void)
|
||||
tcp_stream_set_on_create_handler(tcp_stream_on_create);
|
||||
tcp = tcp_stream_connect(web_server_ip, server_port);
|
||||
if (!tcp) {
|
||||
printf("No free tcp streams\n");
|
||||
if (!wget_info->silent)
|
||||
printf("No free tcp streams\n");
|
||||
net_set_state(NETLOOP_FAIL);
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user