Compare commits

...

22 Commits

Author SHA1 Message Date
David Brown
4635cd23bb updatehub: Require peer verification with DTLS
DTLS without peer verification offers no security whatsoever (and is
arguably worse than not using DTLS in the first place).

Change the verification option to require this peer verification.  To
use this, it may be necessary to install and use a root certificate.

Signed-off-by: David Brown <david.brown@linaro.org>
2020-06-17 17:12:16 -05:00
Andrew Boie
839bee1eb0 drivers: kscan: fix syscall handlers
No check of the driver object was being performed for two
APIs.

Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
2020-06-17 17:11:18 -05:00
Andrew Boie
7722736184 drivers: gpio: fix syscall handlers
No driver object checks were being performed for 3 APIs.

Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
2020-05-12 09:58:42 -05:00
Johann Fischer
8289dc75dd usb: dfu: check requested length (wLength) during DFU_UPLOAD
During DFU_UPLOAD, the host could requests more data
as stated in wTransferSize. Limit upload length to the
size of the request buffer (USB_REQUEST_BUFFER_SIZE).

Signed-off-by: Johann Fischer <j.fischer@phytec.de>
Signed-off-by: David Brown <david.brown@linaro.org>
2020-05-05 13:06:06 -05:00
Wayne Ren
8fa136d9a9 arch: arc: fix the bug of blt in syscall
blt is signed comparsion, if r6 is a negative number created by
malicious code, it will pass the check, bring a secure risk.

use blo (unsinged comparison) to do the check.

Signed-off-by: Wayne Ren <wei.ren@synopsys.com>
Signed-off-by: David Brown <david.brown@linaro.org>
2020-05-05 13:05:42 -05:00
Flavio Ceolin
9d3186c43a shell: utils: Fix buffer overrun in shell_spaces_trim
The third argument in memmove can possible be greater than remaining
buffer size. Just ensuring that memmove will changes bytes only inside
the string buffer and nothing else.

Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
2020-05-05 13:05:26 -05:00
Flavio Ceolin
2649e4c0be sys: usermode: Document 0 size buffer memory check
Documenting that 0 size buffer has undefined behavior.
See: https://github.com/zephyrproject-rtos/zephyr/pull/23239

Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
2020-05-05 13:04:50 -05:00
Flavio Ceolin
b455ab2213 syscalls: arm: Fix possible overflow in is_in_region function
This function is widely used by functions that validate memory
buffers. Macros used to check permissions, like Z_SYSCALL_MEMORY_READ
and Z_SYSCALL_MEMORY_WRITE, use these functions to check that a
pointers passed by user threads in a syscall.

Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
2020-05-05 13:04:50 -05:00
Gerson Fernando Budke
4c5eabfa92 lib: updatehub: Improve probe security
Improve buffer overflow security on probe_cb. This ensures that socket
buffer have fixed lenght and content received by COAP fills properly on
metadata buffer. After that, ensures that metadata content is a valid
string with length lower than metadata size.

Signed-off-by: Gerson Fernando Budke <gerson.budke@ossystems.com.br>
2020-05-05 13:04:16 -05:00
Gerson Fernando Budke
b26942901b lib: updatehub: Refact to use bin2hex
Use bin2hex instead inline conversion.

Signed-off-by: Gerson Fernando Budke <gerson.budke@ossystems.com.br>
2020-05-05 13:04:16 -05:00
Gerson Fernando Budke
3c506635a2 lib: updatehub: Fix variable-size string copy
A malformed JSON payload that is received from an UpdateHub server
may trigger memory corruption in the Zephyr OS. This could result
in a denial of service in the best case, or code execution in the
worst case.

Signed-off-by: Gerson Fernando Budke <gerson.budke@ossystems.com.br>
2020-05-05 13:04:16 -05:00
Otavio Salvador
2c72ec7432 CODEOWNERS: Update UpdateHub owners
This replaces @chtavares592 with @nandojve as he will contributing to it
from now on.

Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
(cherry picked from commit a3d6b627b7)
2020-05-05 13:04:16 -05:00
Gerson Fernando Budke
2aee49f828 lib: updatehub: Add missing do upgrade request call
After a success image download, UpdateHub needs inform MCUboot that
must test new image and then, on success, commit this new image. This
add missing upgrade request call step and fixes the upgarde flow.

Signed-off-by: Gerson Fernando Budke <gerson.budke@ossystems.com.br>
Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
(cherry picked from commit d1e2d345fb)
2020-05-05 13:04:16 -05:00
Gerson Fernando Budke
53dc84622d lib: updatehub: Fix download block error
The current version aborts update when found last transfer block. Now,
system checks only at end of coap block transfer total size and install
if download is ok.

Signed-off-by: Gerson Fernando Budke <gerson.budke@ossystems.com.br>
Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
(cherry picked from commit 1128eab3f2)
2020-05-05 13:04:16 -05:00
Gerson Fernando Budke
d9420d5b15 lib: updatehub: Extract sha256 final method
Extract finish sha256 calc method.

Signed-off-by: Gerson Fernando Budke <gerson.budke@ossystems.com.br>
Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
(cherry picked from commit 1fe1b0eec6)
2020-05-05 13:04:16 -05:00
Gerson Fernando Budke
a8ab2033c4 lib: updatehub: Fix buffer sizes
The MAX_PAYLOAD_SIZE must reflect the size of COAP_BLOCK_x. This is
necessary becase BLOCK size represents max payload size. The current
value create inconsistencies for coap lib. The same way,
MAX_DOWNLOAD_DATA must allocate sufficient space for MAX_PAYLOAD_SIZE
plus all space for coap header etc.

Signed-off-by: Gerson Fernando Budke <gerson.budke@ossystems.com.br>
Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
(cherry picked from commit 5f5919a900)
2020-05-05 13:04:16 -05:00
Gerson Fernando Budke
28b3a2a020 lib: updatehub: Fix build warnings
Fix all build warnings.

Signed-off-by: Gerson Fernando Budke <gerson.budke@ossystems.com.br>
Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
(cherry picked from commit 92f9cd9f85)
2020-05-05 13:04:16 -05:00
Ioannis Glaropoulos
d4f1e73130 tests: kernel: userspace: extend bad syscall-ID test-case
Extend the bad syscall-ID test case to cover
erroneously supplied larged unsiged syscall-ID
values.

Signed-off-by: Ioannis Glaropoulos <Ioannis.Glaropoulos@nordicsemi.no>
Signed-off-by: David Brown <david.brown@linaro.org>
2020-05-05 12:17:18 -05:00
Ioannis Glaropoulos
f3a459e733 arch: arm: aarch32: userspace: fix syscall ID validation
We need an unsigned comparison when evaluating whether
the supplied syscall ID is lower than the syscall ID limit.

Signed-off-by: Ioannis Glaropoulos <Ioannis.Glaropoulos@nordicsemi.no>
Signed-off-by: David Brown <david.brown@linaro.org>
2020-05-05 12:17:18 -05:00
Johann Fischer
d59ad81708 usb: mass_storage: check LBA range
Check if LBA is in range of the memory size.

Signed-off-by: Johann Fischer <j.fischer@phytec.de>
Signed-off-by: David Brown <david.brown@linaro.org>
2020-05-05 12:16:43 -05:00
Flavio Ceolin
bdb1bc8977 net: coap: Fix possible overflow
Fix possible integer overflow when parsing a CoAP packet.

Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
2020-05-05 12:12:24 -05:00
Flavio Ceolin
a910a7cb31 math: extras: Add overflow functions to u16
Add functions to addition and multiplication for u16_t.

Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
2020-05-05 12:12:24 -05:00
20 changed files with 245 additions and 96 deletions

View File

@@ -299,7 +299,7 @@
/samples/ @nashif
/samples/basic/minimal/ @carlescufi
/samples/basic/servo_motor/*microbit* @jhe
/lib/updatehub/ @chtavares592 @otavio
/lib/updatehub/ @nandojve @otavio
/samples/bluetooth/ @jhedberg @Vudentz @joerchan
/samples/boards/intel_s1000_crb/ @sathishkuttan @dcpleung @nashif
/samples/display/ @vanwinkeljan
@@ -312,7 +312,7 @@
/samples/net/mqtt_publisher/ @jukkar @tbursztyka
/samples/net/sockets/coap_*/ @rveerama1
/samples/net/sockets/ @jukkar @tbursztyka @pfalcon
/samples/net/updatehub/ @chtavares592 @otavio
/samples/net/updatehub/ @nandojve @otavio
/samples/sensor/ @MaureenHelm
/samples/shields/ @avisconti
/samples/subsys/logging/ @nordic-krch @jakub-uC

View File

@@ -208,7 +208,7 @@ SECTION_SUBSEC_FUNC(TEXT,__fault,__ev_trap)
/* do sys_call */
mov_s ilink, K_SYSCALL_LIMIT
cmp r6, ilink
blt valid_syscall_id
blo valid_syscall_id
mov_s r0, r6
mov_s r6, K_SYSCALL_BAD

View File

@@ -9,6 +9,8 @@
#define ZEPHYR_ARCH_ARM_CORE_CORTEX_M_MPU_ARM_MPU_V7_INTERNAL_H_
#include <sys/math_extras.h>
#define LOG_LEVEL CONFIG_MPU_LOG_LEVEL
#include <logging/log.h>
@@ -184,6 +186,7 @@ static inline int is_in_region(u32_t r_index, u32_t start, u32_t size)
u32_t r_addr_start;
u32_t r_size_lshift;
u32_t r_addr_end;
u32_t end;
MPU->RNR = r_index;
r_addr_start = MPU->RBAR & MPU_RBAR_ADDR_Msk;
@@ -191,7 +194,12 @@ static inline int is_in_region(u32_t r_index, u32_t start, u32_t size)
MPU_RASR_SIZE_Pos) + 1;
r_addr_end = r_addr_start + (1UL << r_size_lshift) - 1;
if (start >= r_addr_start && (start + size - 1) <= r_addr_end) {
size = size == 0 ? 0 : size - 1;
if (u32_add_overflow(start, size, &end)) {
return 0;
}
if ((start >= r_addr_start) && (end <= r_addr_end)) {
return 1;
}

View File

@@ -10,6 +10,7 @@
#include <soc.h>
#include "arm_core_mpu_dev.h"
#include <sys/__assert.h>
#include <sys/math_extras.h>
#include <linker/linker-defs.h>
#define LOG_LEVEL CONFIG_MPU_LOG_LEVEL
@@ -428,11 +429,17 @@ static inline int is_in_region(u32_t r_index, u32_t start, u32_t size)
{
u32_t r_addr_start;
u32_t r_addr_end;
u32_t end;
r_addr_start = SYSMPU->WORD[r_index][0];
r_addr_end = SYSMPU->WORD[r_index][1];
if (start >= r_addr_start && (start + size - 1) <= r_addr_end) {
size = size == 0 ? 0 : size - 1;
if (u32_add_overflow(start, size, &end)) {
return 0;
}
if ((start >= r_addr_start) && (end <= r_addr_end)) {
return 1;
}

View File

@@ -514,7 +514,10 @@ _do_syscall:
ldr ip, =K_SYSCALL_LIMIT
cmp r6, ip
#endif
blt valid_syscall_id
/* The supplied syscall_id must be lower than the limit
* (Requires unsigned integer comparison)
*/
blo valid_syscall_id
/* bad syscall id. Set arg1 to bad id and set call_id to SYSCALL_BAD */
str r6, [r0]

View File

@@ -36,6 +36,8 @@ static inline int z_vrfy_gpio_read(struct device *port, int access_op,
static inline int z_vrfy_gpio_enable_callback(struct device *port,
int access_op, u32_t pin)
{
Z_OOPS(Z_SYSCALL_DRIVER_GPIO(port, enable_callback));
return z_impl_gpio_enable_callback((struct device *)port, access_op,
pin);
}
@@ -44,6 +46,8 @@ static inline int z_vrfy_gpio_enable_callback(struct device *port,
static inline int z_vrfy_gpio_disable_callback(struct device *port,
int access_op, u32_t pin)
{
Z_OOPS(Z_SYSCALL_DRIVER_GPIO(port, disable_callback));
return z_impl_gpio_disable_callback((struct device *)port, access_op,
pin);
}
@@ -51,6 +55,8 @@ static inline int z_vrfy_gpio_disable_callback(struct device *port,
static inline int z_vrfy_gpio_get_pending_int(struct device *dev)
{
Z_OOPS(Z_SYSCALL_DRIVER_GPIO(dev, get_pending_int));
return z_impl_gpio_get_pending_int((struct device *)dev);
}
#include <syscalls/gpio_get_pending_int_mrsh.c>

View File

@@ -19,12 +19,16 @@ static inline int z_vrfy_kscan_config(struct device *dev,
static inline int z_vrfy_kscan_disable_callback(struct device *dev);
{
Z_OOPS(Z_SYSCALL_DRIVER_KSCAN(dev, disable_callback));
return z_impl_kscan_disable_callback((struct device *)dev);
}
#include <syscalls/kscan_disable_callback_mrsh.c>
static int z_vrfy_kscan_enable_callback(struct device *dev);
{
Z_OOPS(Z_SYSCALL_DRIVER_KSCAN(dev, enable_callback));
return z_impl_kscan_enable_callback((struct device *)dev);
}
#include <syscalls/kscan_enable_callback_mrsh.c>

View File

@@ -572,6 +572,8 @@ void arch_mem_domain_destroy(struct k_mem_domain *domain);
* if the supplied memory buffer spans multiple enabled memory management
* regions (even if all such regions permit user access).
*
* @warning 0 size buffer has undefined behavior.
*
* @param addr start address of the buffer
* @param size the size of the buffer
* @param write If nonzero, additionally check if the area is writable.

View File

@@ -28,6 +28,7 @@
* true if the operation overflowed.
*/
/**@{*/
static bool u16_add_overflow(u16_t a, u16_t b, u16_t *result);
static bool u32_add_overflow(u32_t a, u32_t b, u32_t *result);
static bool u64_add_overflow(u64_t a, u64_t b, u64_t *result);
static bool size_add_overflow(size_t a, size_t b, size_t *result);
@@ -40,6 +41,7 @@ static bool size_add_overflow(size_t a, size_t b, size_t *result);
* true if the operation overflowed.
*/
/**@{*/
static bool u16_mul_overflow(u16_t a, u16_t b, u16_t *result);
static bool u32_mul_overflow(u32_t a, u32_t b, u32_t *result);
static bool u64_mul_overflow(u64_t a, u64_t b, u64_t *result);
static bool size_mul_overflow(size_t a, size_t b, size_t *result);

View File

@@ -29,6 +29,11 @@
#endif
#if use_builtin(__builtin_add_overflow)
static inline bool u16_add_overflow(u16_t a, u16_t b, u16_t *result)
{
return __builtin_add_overflow(a, b, result);
}
static inline bool u32_add_overflow(u32_t a, u32_t b, u32_t *result)
{
return __builtin_add_overflow(a, b, result);
@@ -44,6 +49,15 @@ static inline bool size_add_overflow(size_t a, size_t b, size_t *result)
return __builtin_add_overflow(a, b, result);
}
#else /* !use_builtin(__builtin_add_overflow) */
static inline bool u16_add_overflow(u16_t a, u16_t b, u16_t *result)
{
u16_t c = a + b;
*result = c;
return c < a;
}
static inline bool u32_add_overflow(u32_t a, u32_t b, u32_t *result)
{
u32_t c = a + b;
@@ -73,6 +87,11 @@ static inline bool size_add_overflow(size_t a, size_t b, size_t *result)
#endif /* use_builtin(__builtin_add_overflow) */
#if use_builtin(__builtin_mul_overflow)
static inline bool u16_mul_overflow(u16_t a, u16_t b, u16_t *result)
{
return __builtin_mul_overflow(a, b, result);
}
static inline bool u32_mul_overflow(u32_t a, u32_t b, u32_t *result)
{
return __builtin_mul_overflow(a, b, result);
@@ -88,6 +107,15 @@ static inline bool size_mul_overflow(size_t a, size_t b, size_t *result)
return __builtin_mul_overflow(a, b, result);
}
#else /* !use_builtin(__builtin_mul_overflow) */
static inline bool u16_mul_overflow(u16_t a, u16_t b, u16_t *result)
{
u16_t c = a * b;
*result = c;
return a != 0 && (c / a) != b;
}
static inline bool u32_mul_overflow(u32_t a, u32_t b, u32_t *result)
{
u32_t c = a * b;

View File

@@ -55,11 +55,11 @@ static int cmd_info(const struct shell *shell, size_t argc, char **argv)
ARG_UNUSED(argc);
ARG_UNUSED(argv);
char *device_id = k_malloc(DEVICE_ID_MAX_SIZE);
char *device_id = k_malloc(DEVICE_ID_HEX_MAX_SIZE);
char *firmware_version = k_malloc(BOOT_IMG_VER_STRLEN_MAX);
updatehub_get_device_identity(device_id, DEVICE_ID_HEX_MAX_SIZE);
updatehub_get_firmware_version(firmware_version, BOOT_IMG_VER_STRLEN_MAX);
updatehub_get_device_identity(device_id, DEVICE_ID_MAX_SIZE);
shell_fprintf(shell, SHELL_NORMAL, "Unique device id: %s\n",
device_id);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2019 O.S.Systems
* Copyright (c) 2018-2020 O.S.Systems
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -35,11 +35,18 @@ LOG_MODULE_REGISTER(updatehub);
#define NETWORK_TIMEOUT K_SECONDS(2)
#define UPDATEHUB_POLL_INTERVAL K_MINUTES(CONFIG_UPDATEHUB_POLL_INTERVAL)
#define MAX_PATH_SIZE 255
#define MAX_PAYLOAD_SIZE 500
#define MAX_DOWNLOAD_DATA 1100
/* MAX_PAYLOAD_SIZE must reflect size COAP_BLOCK_x option */
#define MAX_PAYLOAD_SIZE 1024
/* MAX_DOWNLOAD_DATA must be equal or bigger than:
* MAX_PAYLOAD_SIZE + (len + header + options)
* otherwise download size will be less than real size.
*/
#define MAX_DOWNLOAD_DATA (MAX_PAYLOAD_SIZE + 32)
#define COAP_MAX_RETRY 3
#define MAX_IP_SIZE 30
#define SHA256_HEX_DIGEST_SIZE ((TC_SHA256_DIGEST_SIZE * 2) + 1)
#if defined(CONFIG_UPDATEHUB_CE)
#define UPDATEHUB_SERVER CONFIG_UPDATEHUB_SERVER
#else
@@ -61,11 +68,31 @@ static struct updatehub_context {
} ctx;
static struct update_info {
char package_uid[TC_SHA256_BLOCK_SIZE + 1];
char sha256sum_image[TC_SHA256_BLOCK_SIZE + 1];
char package_uid[SHA256_HEX_DIGEST_SIZE];
char sha256sum_image[SHA256_HEX_DIGEST_SIZE];
int image_size;
} update_info;
static struct k_delayed_work updatehub_work_handle;
static int bin2hex_str(u8_t *bin, size_t bin_len, char *str, size_t str_buf_len)
{
if (bin == NULL || str == NULL) {
return -1;
}
/* ensures at least an empty string */
if (str_buf_len < 1) {
return -2;
}
memset(str, 0, str_buf_len);
/* str_buf_len - 1 ensure space for \0 */
bin2hex(bin, bin_len, str, str_buf_len - 1);
return 0;
}
static void wait_fds(void)
{
if (poll(ctx.fds, ctx.nfds, NETWORK_TIMEOUT) < 0) {
@@ -76,7 +103,7 @@ static void wait_fds(void)
static void prepare_fds(void)
{
ctx.fds[ctx.nfds].fd = ctx.sock;
ctx.fds[ctx.nfds].events = 1;
ctx.fds[ctx.nfds].events = POLLIN;
ctx.nfds++;
}
@@ -84,8 +111,6 @@ static int metadata_hash_get(char *metadata)
{
struct tc_sha256_state_struct sha256sum;
unsigned char hash[TC_SHA256_DIGEST_SIZE];
char buffer[3];
int buffer_len = 0;
if (tc_sha256_init(&sha256sum) == 0) {
return -1;
@@ -99,13 +124,9 @@ static int metadata_hash_get(char *metadata)
return -1;
}
memset(update_info.package_uid, 0, TC_SHA256_BLOCK_SIZE + 1);
for (int i = 0; i < TC_SHA256_DIGEST_SIZE; i++) {
snprintk(buffer, sizeof(buffer), "%02x",
hash[i]);
buffer_len = buffer_len + strlen(buffer);
strncat(&update_info.package_uid[i], buffer,
MIN(TC_SHA256_BLOCK_SIZE, buffer_len));
if (bin2hex_str(hash, TC_SHA256_DIGEST_SIZE,
update_info.package_uid, SHA256_HEX_DIGEST_SIZE)) {
return -1;
}
return 0;
@@ -141,7 +162,7 @@ static bool start_coap_client(void)
}
#if defined(CONFIG_UPDATEHUB_DTLS)
int verify = 0;
int verify = 1;
sec_tag_t sec_list[] = { CA_CERTIFICATE_TAG };
int protocol = IPPROTO_DTLS_1_2;
char port[] = "5684";
@@ -288,7 +309,7 @@ static int send_request(enum coap_msgtype msgtype, enum coap_method method,
}
ret = coap_packet_append_payload(&request_packet,
&ctx.payload,
ctx.payload,
strlen(ctx.payload));
if (ret < 0) {
LOG_ERR("Not able to append payload");
@@ -315,12 +336,36 @@ error:
return ret;
}
static bool install_update_cb_sha256(void)
{
u8_t hash[TC_SHA256_DIGEST_SIZE];
char sha256[SHA256_HEX_DIGEST_SIZE];
if (tc_sha256_final(hash, &ctx.sha256sum) < 1) {
LOG_ERR("Could not finish sha256sum");
return false;
}
if (bin2hex_str(hash, TC_SHA256_DIGEST_SIZE,
sha256, SHA256_HEX_DIGEST_SIZE)) {
LOG_ERR("Could not create sha256sum hex representation");
return false;
}
if (strncmp(sha256, update_info.sha256sum_image,
SHA256_HEX_DIGEST_SIZE) != 0) {
LOG_ERR("SHA256SUM of image are not the same");
ctx.code_status = UPDATEHUB_DOWNLOAD_ERROR;
return false;
}
return true;
}
static void install_update_cb(void)
{
struct coap_packet response_packet;
char buffer[3], sha256_image_dowloaded[TC_SHA256_BLOCK_SIZE + 1];
u8_t *data = k_malloc(MAX_DOWNLOAD_DATA);
int i, buffer_len = 0;
int rcvd = -1;
if (data == NULL) {
@@ -370,32 +415,15 @@ static void install_update_cb(void)
}
if (coap_next_block(&response_packet, &ctx.block) == 0) {
LOG_ERR("Could not get the next");
ctx.code_status = UPDATEHUB_DOWNLOAD_ERROR;
goto cleanup;
}
if (ctx.downloaded_size == ctx.block.total_size) {
u8_t image_hash[TC_SHA256_DIGEST_SIZE];
if (tc_sha256_final(image_hash, &ctx.sha256sum) < 1) {
LOG_ERR("Could not finish sha256sum");
if (ctx.downloaded_size != ctx.block.total_size) {
LOG_ERR("Could not get the next coap block");
ctx.code_status = UPDATEHUB_DOWNLOAD_ERROR;
goto cleanup;
}
memset(&sha256_image_dowloaded, 0, TC_SHA256_BLOCK_SIZE + 1);
for (i = 0; i < TC_SHA256_DIGEST_SIZE; i++) {
snprintk(buffer, sizeof(buffer), "%02x", image_hash[i]);
buffer_len = buffer_len + strlen(buffer);
strncat(&sha256_image_dowloaded[i], buffer,
MIN(TC_SHA256_BLOCK_SIZE, buffer_len));
}
if (strncmp(sha256_image_dowloaded,
update_info.sha256sum_image,
strlen(update_info.sha256sum_image)) != 0) {
LOG_ERR("SHA256SUM of image are not the same");
LOG_INF("Firmware downloaded successfully");
if (!install_update_cb_sha256()) {
LOG_ERR("Firmware validation has failed");
ctx.code_status = UPDATEHUB_DOWNLOAD_ERROR;
goto cleanup;
}
@@ -479,7 +507,7 @@ static int report(enum updatehub_state state)
struct report report;
int ret = -1;
const char *exec = state_name(state);
char *device_id = k_malloc(DEVICE_ID_MAX_SIZE);
char *device_id = k_malloc(DEVICE_ID_HEX_MAX_SIZE);
char *firmware_version = k_malloc(BOOT_IMG_VER_STRLEN_MAX);
if (device_id == NULL || firmware_version == NULL) {
@@ -487,7 +515,7 @@ static int report(enum updatehub_state state)
goto error;
}
if (!updatehub_get_device_identity(device_id, DEVICE_ID_MAX_SIZE)) {
if (!updatehub_get_device_identity(device_id, DEVICE_ID_HEX_MAX_SIZE)) {
goto error;
}
@@ -559,22 +587,23 @@ error:
return ret;
}
static void probe_cb(char *metadata)
static void probe_cb(char *metadata, size_t metadata_size)
{
struct coap_packet reply;
char tmp[MAX_PAYLOAD_SIZE];
char tmp[MAX_DOWNLOAD_DATA];
size_t tmp_len;
int rcvd = -1;
wait_fds();
rcvd = recv(ctx.sock, metadata, MAX_PAYLOAD_SIZE, MSG_DONTWAIT);
rcvd = recv(ctx.sock, tmp, MAX_DOWNLOAD_DATA, MSG_DONTWAIT);
if (rcvd <= 0) {
LOG_ERR("Could not receive data");
ctx.code_status = UPDATEHUB_NETWORKING_ERROR;
return;
}
if (coap_packet_parse(&reply, metadata, rcvd, NULL, 0) < 0) {
if (coap_packet_parse(&reply, tmp, rcvd, NULL, 0) < 0) {
LOG_ERR("Invalid data received");
ctx.code_status = UPDATEHUB_DOWNLOAD_ERROR;
return;
@@ -586,10 +615,25 @@ static void probe_cb(char *metadata)
return;
}
memset(&tmp, 0, MAX_PAYLOAD_SIZE);
memcpy(tmp, reply.data + reply.offset, reply.max_len - reply.offset);
memset(metadata, 0, MAX_PAYLOAD_SIZE);
memcpy(metadata, tmp, strlen(tmp));
/* check if we have buffer space to receive payload */
if (metadata_size < (reply.max_len - reply.offset)) {
LOG_ERR("There is no buffer available");
ctx.code_status = UPDATEHUB_METADATA_ERROR;
return;
}
memcpy(metadata, reply.data + reply.offset,
reply.max_len - reply.offset);
/* ensures payload have a valid string with size lower
* than metadata_size
*/
tmp_len = strlen(metadata);
if (tmp_len >= metadata_size) {
LOG_ERR("Invalid metadata data received");
ctx.code_status = UPDATEHUB_METADATA_ERROR;
return;
}
ctx.code_status = UPDATEHUB_OK;
@@ -602,11 +646,13 @@ enum updatehub_response updatehub_probe(void)
struct resp_probe_some_boards metadata_some_boards;
struct resp_probe_any_boards metadata_any_boards;
char *metadata = k_malloc(MAX_PAYLOAD_SIZE);
char *metadata_copy = k_malloc(MAX_PAYLOAD_SIZE);
char *device_id = k_malloc(DEVICE_ID_MAX_SIZE);
char *metadata = k_malloc(MAX_DOWNLOAD_DATA);
char *metadata_copy = k_malloc(MAX_DOWNLOAD_DATA);
char *device_id = k_malloc(DEVICE_ID_HEX_MAX_SIZE);
char *firmware_version = k_malloc(BOOT_IMG_VER_STRLEN_MAX);
size_t sha256size;
if (device_id == NULL || firmware_version == NULL ||
metadata == NULL || metadata_copy == NULL) {
LOG_ERR("Could not alloc probe memory");
@@ -614,8 +660,6 @@ enum updatehub_response updatehub_probe(void)
goto error;
}
k_sem_init(&ctx.semaphore, 0, 1);
if (!boot_is_img_confirmed()) {
LOG_ERR("The current image is not confirmed");
ctx.code_status = UPDATEHUB_UNCONFIRMED_IMAGE;
@@ -627,7 +671,7 @@ enum updatehub_response updatehub_probe(void)
goto error;
}
if (!updatehub_get_device_identity(device_id, DEVICE_ID_MAX_SIZE)) {
if (!updatehub_get_device_identity(device_id, DEVICE_ID_HEX_MAX_SIZE)) {
ctx.code_status = UPDATEHUB_METADATA_ERROR;
goto error;
}
@@ -658,8 +702,7 @@ enum updatehub_response updatehub_probe(void)
goto cleanup;
}
memset(metadata, 0, MAX_PAYLOAD_SIZE);
probe_cb(metadata);
probe_cb(metadata, MAX_DOWNLOAD_DATA);
if (ctx.code_status != UPDATEHUB_OK) {
goto cleanup;
@@ -687,9 +730,18 @@ enum updatehub_response updatehub_probe(void)
goto cleanup;
}
sha256size = strlen(
metadata_any_boards.objects[1].objects.sha256sum) + 1;
if (sha256size != SHA256_HEX_DIGEST_SIZE) {
LOG_ERR("SHA256 size is invalid");
ctx.code_status = UPDATEHUB_METADATA_ERROR;
goto cleanup;
}
memcpy(update_info.sha256sum_image,
metadata_any_boards.objects[1].objects.sha256sum,
strlen(metadata_any_boards.objects[1].objects.sha256sum));
SHA256_HEX_DIGEST_SIZE);
update_info.image_size = metadata_any_boards.objects[1].objects.size;
} else {
if (!is_compatible_hardware(&metadata_some_boards)) {
@@ -698,10 +750,19 @@ enum updatehub_response updatehub_probe(void)
UPDATEHUB_INCOMPATIBLE_HARDWARE;
goto cleanup;
}
sha256size = strlen(
metadata_any_boards.objects[1].objects.sha256sum) + 1;
if (sha256size != SHA256_HEX_DIGEST_SIZE) {
LOG_ERR("SHA256 size is invalid");
ctx.code_status = UPDATEHUB_METADATA_ERROR;
goto cleanup;
}
memcpy(update_info.sha256sum_image,
metadata_some_boards.objects[1].objects.sha256sum,
strlen(metadata_some_boards.objects[1]
.objects.sha256sum));
SHA256_HEX_DIGEST_SIZE);
update_info.image_size =
metadata_some_boards.objects[1].objects.size;
}
@@ -741,6 +802,12 @@ enum updatehub_response updatehub_update(void)
goto error;
}
if (boot_request_upgrade(BOOT_UPGRADE_TEST)) {
LOG_ERR("Could not reporting downloaded state");
ctx.code_status = UPDATEHUB_INSTALL_ERROR;
goto error;
}
if (report(UPDATEHUB_STATE_INSTALLED) < 0) {
LOG_ERR("Could not reporting installed state");
goto error;
@@ -765,7 +832,7 @@ error:
return ctx.code_status;
}
static void autohandler(struct k_delayed_work *work)
static void autohandler(struct k_work *work)
{
switch (updatehub_probe()) {
case UPDATEHUB_UNCONFIRMED_IMAGE:
@@ -794,14 +861,12 @@ static void autohandler(struct k_delayed_work *work)
break;
}
k_delayed_work_submit(work, UPDATEHUB_POLL_INTERVAL);
k_delayed_work_submit(&updatehub_work_handle, UPDATEHUB_POLL_INTERVAL);
}
void updatehub_autohandler(void)
{
static struct k_delayed_work work;
k_delayed_work_init(&work, autohandler);
k_delayed_work_submit(&work, K_NO_WAIT);
k_delayed_work_init(&updatehub_work_handle, autohandler);
k_delayed_work_submit(&updatehub_work_handle, K_NO_WAIT);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018 O.S.Systems
* Copyright (c) 2018-2020 O.S.Systems
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -7,23 +7,16 @@
bool updatehub_get_device_identity(char *id, int id_max_len)
{
int i, id_len = 0, buf_len = 0;
char buf[3];
u8_t hwinfo_id[id_max_len];
u8_t hwinfo_id[DEVICE_ID_BIN_MAX_SIZE];
size_t length;
length = hwinfo_get_device_id(hwinfo_id, sizeof(hwinfo_id) - 1);
length = hwinfo_get_device_id(hwinfo_id, DEVICE_ID_BIN_MAX_SIZE);
if (length <= 0) {
return false;
}
memset(id, 0, id_max_len);
length = bin2hex(hwinfo_id, length, id, id_max_len - 1);
for (i = 0; i < length; i++) {
snprintk(buf, sizeof(buf), "%02x", hwinfo_id[i]);
id_len = strlen(id);
strncat(id, buf, id_max_len - id_len);
}
return true;
return length > 0;
}

View File

@@ -10,7 +10,8 @@
#include <zephyr.h>
#include <drivers/hwinfo.h>
#define DEVICE_ID_MAX_SIZE 65
#define DEVICE_ID_BIN_MAX_SIZE 64
#define DEVICE_ID_HEX_MAX_SIZE ((DEVICE_ID_BIN_MAX_SIZE * 2) + 1)
bool updatehub_get_device_identity(char *id, int id_max_len);

View File

@@ -2,7 +2,7 @@
CONFIG_UPDATEHUB=y
#Minimal Heap mem pool size for the updatehub working
CONFIG_HEAP_MEM_POOL_SIZE=2048
CONFIG_HEAP_MEM_POOL_SIZE=8192
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048
CONFIG_NET_IPV4=y

View File

@@ -17,6 +17,7 @@ LOG_MODULE_REGISTER(net_coap, CONFIG_COAP_LOG_LEVEL);
#include <zephyr/types.h>
#include <sys/byteorder.h>
#include <sys/math_extras.h>
#include <net/net_ip.h>
#include <net/net_core.h>
@@ -469,7 +470,9 @@ static int parse_option(u8_t *data, u16_t offset, u16_t *pos,
return -EINVAL;
}
*opt_len += hdr_len;
if (u16_add_overflow(*opt_len, hdr_len, opt_len)) {
return -EINVAL;
}
}
if (len > COAP_OPTION_NO_EXT) {
@@ -480,11 +483,15 @@ static int parse_option(u8_t *data, u16_t offset, u16_t *pos,
return -EINVAL;
}
*opt_len += hdr_len;
if (u16_add_overflow(*opt_len, hdr_len, opt_len)) {
return -EINVAL;
}
}
*opt_delta += delta;
*opt_len += len;
if (u16_add_overflow(*opt_delta, delta, opt_delta) ||
u16_add_overflow(*opt_len, len, opt_len)) {
return -EINVAL;
}
if (r == 0) {
if (len == 0U) {
@@ -519,7 +526,10 @@ static int parse_option(u8_t *data, u16_t offset, u16_t *pos,
return -EINVAL;
}
} else {
*pos += len;
if (u16_add_overflow(*pos, len, pos)) {
return -EINVAL;
}
r = max_len - *pos;
}

View File

@@ -413,7 +413,7 @@ void shell_spaces_trim(char *str)
/* +1 for EOS */
memmove(&str[i + 1],
&str[j],
len - shift + 1);
len - j + 1);
len -= shift;
shift = 0U;
}

View File

@@ -433,6 +433,13 @@ static bool infoTransfer(void)
(cbw.CB[5] << 0);
LOG_DBG("LBA (block) : 0x%x ", n);
if ((n * BLOCK_SIZE) >= memory_size) {
LOG_ERR("LBA out of range");
csw.Status = CSW_FAILED;
sendCSW();
return false;
}
addr = n * BLOCK_SIZE;
/* Number of Blocks to transfer */

View File

@@ -509,6 +509,15 @@ static int dfu_class_handle_req(struct usb_setup_packet *pSetup,
len = pSetup->wLength;
}
if (len > USB_DFU_MAX_XFER_SIZE) {
/*
* The host could requests more data as stated
* in wTransferSize. Limit upload length to the
* size of the request-buffer.
*/
len = USB_DFU_MAX_XFER_SIZE;
}
if (len) {
const struct flash_area *fa;

View File

@@ -1083,6 +1083,10 @@ void test_bad_syscall(void)
arch_syscall_invoke0(INT_MAX);
expect_fault = true;
expected_reason = K_ERR_KERNEL_OOPS;
arch_syscall_invoke0(UINT_MAX);
}
static struct k_sem recycle_sem;