mirror of https://github.com/hak5/openwrt.git
mtd: detect image format when writing
Recently TRX checking code was changed to detect Seama format and don't abort whole writing operation because of it. This isn't a good long-term solution. It's a poor idea to teach every format handler recognizing all possible formats. Instead it should be handled in a generic code which should run check depending on the detected format. This will also allow further improvements like fixing formats other than TRX after replacing JFFS2. Signed-off-by: Rafał Miłecki <zajec5@gmail.com> SVN-Revision: 48639lede-17.01
parent
18bcbbfd45
commit
b5c41ad28c
|
@ -22,6 +22,7 @@
|
|||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <byteswap.h>
|
||||
#include <limits.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -50,8 +51,32 @@
|
|||
#define MAX_ARGS 8
|
||||
#define JFFS2_DEFAULT_DIR "" /* directory name without /, empty means root dir */
|
||||
|
||||
#define TRX_MAGIC 0x48445230 /* "HDR0" */
|
||||
#define SEAMA_MAGIC 0x5ea3a417
|
||||
|
||||
#if !defined(__BYTE_ORDER)
|
||||
#error "Unknown byte order"
|
||||
#endif
|
||||
|
||||
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||
#define cpu_to_be32(x) (x)
|
||||
#define be32_to_cpu(x) (x)
|
||||
#elif __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
#define cpu_to_be32(x) bswap_32(x)
|
||||
#define be32_to_cpu(x) bswap_32(x)
|
||||
#else
|
||||
#error "Unsupported endianness"
|
||||
#endif
|
||||
|
||||
enum mtd_image_format {
|
||||
MTD_IMAGE_FORMAT_UNKNOWN,
|
||||
MTD_IMAGE_FORMAT_TRX,
|
||||
MTD_IMAGE_FORMAT_SEAMA,
|
||||
};
|
||||
|
||||
static char *buf = NULL;
|
||||
static char *imagefile = NULL;
|
||||
static enum mtd_image_format imageformat = MTD_IMAGE_FORMAT_UNKNOWN;
|
||||
static char *jffs2file = NULL, *jffs2dir = JFFS2_DEFAULT_DIR;
|
||||
static int buflen = 0;
|
||||
int quiet;
|
||||
|
@ -149,13 +174,39 @@ int mtd_write_buffer(int fd, const char *buf, int offset, int length)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
image_check(int imagefd, const char *mtd)
|
||||
{
|
||||
uint32_t magic;
|
||||
int ret = 1;
|
||||
if (trx_check) {
|
||||
ret = trx_check(imagefd, mtd, buf, &buflen);
|
||||
|
||||
if (buflen < sizeof(magic)) {
|
||||
buflen += read(imagefd, buf + buflen, sizeof(magic) - buflen);
|
||||
if (buflen < sizeof(magic)) {
|
||||
fprintf(stdout, "Could not get image magic\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
magic = ((uint32_t *)buf)[0];
|
||||
|
||||
if (be32_to_cpu(magic) == TRX_MAGIC)
|
||||
imageformat = MTD_IMAGE_FORMAT_TRX;
|
||||
else if (be32_to_cpu(magic) == SEAMA_MAGIC)
|
||||
imageformat = MTD_IMAGE_FORMAT_SEAMA;
|
||||
|
||||
switch (imageformat) {
|
||||
case MTD_IMAGE_FORMAT_TRX:
|
||||
if (trx_check)
|
||||
ret = trx_check(imagefd, mtd, buf, &buflen);
|
||||
break;
|
||||
case MTD_IMAGE_FORMAT_SEAMA:
|
||||
break;
|
||||
default:
|
||||
#ifdef target_brcm
|
||||
if (!strcmp(mtd, "firmware"))
|
||||
ret = 0;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef target_brcm47xx
|
||||
#if defined(target_brcm47xx) || defined(target_bcm53xx)
|
||||
#define target_brcm 1
|
||||
#endif
|
||||
|
||||
|
|
|
@ -44,8 +44,6 @@ struct trx_header {
|
|||
uint32_t offsets[3]; /* Offsets of partitions from start of header */
|
||||
};
|
||||
|
||||
#define SEAMA_MAGIC 0x17a4a35e
|
||||
|
||||
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||
#define STORE32_LE(X) ((((X) & 0x000000FF) << 24) | (((X) & 0x0000FF00) << 8) | (((X) & 0x00FF0000) >> 8) | (((X) & 0xFF000000) >> 24))
|
||||
#elif __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
|
@ -114,16 +112,14 @@ trx_check(int imagefd, const char *mtd, char *buf, int *len)
|
|||
if (strcmp(mtd, "firmware") != 0)
|
||||
return 1;
|
||||
|
||||
*len = read(imagefd, buf, 32);
|
||||
if (*len < 32) {
|
||||
fprintf(stdout, "Could not get image header, file too small (%d bytes)\n", *len);
|
||||
return 0;
|
||||
*len += read(imagefd, buf + *len, 32 - *len);
|
||||
if (*len < 32) {
|
||||
fprintf(stdout, "Could not get image header, file too small (%d bytes)\n", *len);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Allow writing Seama files to firmware without an extra validation */
|
||||
if (trx->magic == SEAMA_MAGIC)
|
||||
return 1;
|
||||
|
||||
if (trx->magic != TRX_MAGIC || trx->len < sizeof(struct trx_header)) {
|
||||
if (quiet < 2) {
|
||||
fprintf(stderr, "Bad trx header\n");
|
||||
|
|
Loading…
Reference in New Issue