示例#1
0
static int read_data(ZipArchive *zip, const ZipEntry *entry,
        char** ppData, int* pLength) {
    int len = (int)mzGetZipEntryUncompLen(entry);
    if (len <= 0) {
        LOGE("Bad data length %d\n", len);
        return -1;
    }
    char *data = malloc(len + 1);
    if (data == NULL) {
        LOGE("Can't allocate %d bytes for data\n", len + 1);
        return -2;
    }
    bool ok = mzReadZipEntry(zip, entry, data, len);
    if (!ok) {
        LOGE("Error while reading data\n");
        free(data);
        return -3;
    }
    data[len] = '\0';     // not necessary, but just to be safe
    *ppData = data;
    if (pLength) {
        *pLength = len;
    }
    return 0;
}
/* write_radio_image <src-image>
 * write_hboot_image <src-image>
 * Doesn't actually take effect until the rest of installation finishes.
 */
static int
cmd_write_firmware_image(const char *name, void *cookie,
        int argc, const char *argv[])
{
    UNUSED(cookie);
    CHECK_WORDS();

    if (argc != 1) {
        LOGE("Command %s requires exactly one argument\n", name);
        return 1;
    }

    const char *type;
    if (!strcmp(name, "write_radio_image")) {
        type = "radio";
    } else if (!strcmp(name, "write_hboot_image")) {
        type = "hboot";
    } else {
        LOGE("Unknown firmware update command %s\n", name);
        return 1;
    }

    if (!is_package_root_path(argv[0])) {
        LOGE("Command %s: non-package image file \"%s\" not supported\n",
                name, argv[0]);
        return 1;
    }

    ui_print("Extracting %s image...\n", type);
    char path[PATH_MAX];
    const ZipArchive *package;
    if (!translate_package_root_path(argv[0], path, sizeof(path), &package)) {
        LOGE("Command %s: bad source path \"%s\"\n", name, argv[0]);
        return 1;
    }

    const ZipEntry *entry = mzFindZipEntry(package, path);
    if (entry == NULL) {
        LOGE("Can't find %s\n", path);
        return 1;
    }

    // Load the update image into RAM.
    struct FirmwareContext context;
    context.total_bytes = mzGetZipEntryUncompLen(entry);
    context.done_bytes = 0;
    context.data = malloc(context.total_bytes);
    if (context.data == NULL) {
        LOGE("Can't allocate %d bytes for %s\n", context.total_bytes, argv[0]);
        return 1;
    }

    if (!mzProcessZipEntryContents(package, entry, firmware_fn, &context) ||
        context.done_bytes != context.total_bytes) {
        LOGE("Can't read %s\n", argv[0]);
        free(context.data);
        return 1;
    }

    if (remember_firmware_update(type, context.data, context.total_bytes)) {
        LOGE("Can't store %s image\n", type);
        free(context.data);
        return 1;
    }

    return 0;
}
示例#3
0
// package_extract_file(package_path, destination_path)
//   or
// package_extract_file(package_path)
//   to return the entire contents of the file as the result of this
//   function (the char* returned is actually a FileContents*).
Value* PackageExtractFileFn(const char* name, State* state,
                           int argc, Expr* argv[]) {
    if (argc != 1 && argc != 2) {
        return ErrorAbort(state, "%s() expects 1 or 2 args, got %d",
                          name, argc);
    }
    bool success = false;
    if (argc == 2) {
        // The two-argument version extracts to a file.

        char* zip_path;
        char* dest_path;
        if (ReadArgs(state, argv, 2, &zip_path, &dest_path) < 0) return NULL;

        ZipArchive* za = ((UpdaterInfo*)(state->cookie))->package_zip;
        const ZipEntry* entry = mzFindZipEntry(za, zip_path);
        if (entry == NULL) {
            fprintf(stderr, "%s: no %s in package\n", name, zip_path);
            goto done2;
        }

        FILE* f = fopen(dest_path, "wb");
        if (f == NULL) {
            fprintf(stderr, "%s: can't open %s for write: %s\n",
                    name, dest_path, strerror(errno));
            goto done2;
        }
        success = mzExtractZipEntryToFile(za, entry, fileno(f));
        fclose(f);

      done2:
        free(zip_path);
        free(dest_path);
        return StringValue(strdup(success ? "t" : ""));
    } else {
        // The one-argument version returns the contents of the file
        // as the result.

        char* zip_path;
        Value* v = malloc(sizeof(Value));
        v->type = VAL_BLOB;
        v->size = -1;
        v->data = NULL;

        if (ReadArgs(state, argv, 1, &zip_path) < 0) return NULL;

        ZipArchive* za = ((UpdaterInfo*)(state->cookie))->package_zip;
        const ZipEntry* entry = mzFindZipEntry(za, zip_path);
        if (entry == NULL) {
            fprintf(stderr, "%s: no %s in package\n", name, zip_path);
            goto done1;
        }

        v->size = mzGetZipEntryUncompLen(entry);
        v->data = malloc(v->size);
        if (v->data == NULL) {
            fprintf(stderr, "%s: failed to allocate %ld bytes for %s\n",
                    name, (long)v->size, zip_path);
            goto done1;
        }

        success = mzExtractZipEntryToBuffer(za, entry,
                                            (unsigned char *)v->data);

      done1:
        free(zip_path);
        if (!success) {
            free(v->data);
            v->data = NULL;
            v->size = -1;
        }
        return v;
    }
}
Value *FlashIfwiOrBomFn(enum flash_option_type flash_option, const char *name, State * state, int argc,
			Expr * argv[])
{
	Value *ret = NULL;
	char *filename = NULL;
	int err, i, num, buffsize;
	char ifwi_name[128];
	ZipArchive ifwi_za;
	const ZipEntry *ifwi_entry;
	unsigned char *buffer;
	unsigned char *file_buf = NULL;
	size_t file_size;
#ifdef TEE_FRAMEWORK
	char bom_token_name[128];
	const ZipEntry *bom_token_entry;
	int bom_token_buffsize;
	unsigned char *bom_token_buffer;
#endif

	if (ReadArgs(state, argv, 1, &filename) < 0) {
		return NULL;
	}

	if (filename == NULL || strlen(filename) == 0) {
		ErrorAbort(state, "filename argument to %s can't be empty", name);
		goto done;
	}

	err = file_read(filename, (void **)&file_buf, &file_size);
	if (err) {
		ErrorAbort(state, "Failed to open zip archive file %s\n", filename);
		goto done;
	}

	err = mzOpenZipArchive(file_buf, file_size, &ifwi_za);
	if (err) {
		ErrorAbort(state, "Failed to open zip archive\n");
		goto done;
	}

	num = mzZipEntryCount(&ifwi_za);
	for (i = 0; i < num; i++) {
		ifwi_entry = mzGetZipEntryAt(&ifwi_za, i);
		if ((ifwi_entry->fileNameLen + 1) < sizeof(ifwi_name)) {
			strncpy(ifwi_name, ifwi_entry->fileName, ifwi_entry->fileNameLen);
			ifwi_name[ifwi_entry->fileNameLen] = '\0';
		} else {
			ErrorAbort(state, "ifwi file name is too big. Size max is:%zd.\n", sizeof(ifwi_name));
			goto error;
		}
		if (strncmp(ifwi_name, IFWI_NAME, strlen(IFWI_NAME)))
			continue;
		buffsize = mzGetZipEntryUncompLen(ifwi_entry);
		if (buffsize <= 0) {
			ErrorAbort(state, "Bad ifwi_entry size : %d.\n", buffsize);
			goto error;
		}
		buffer = (unsigned char *)malloc(sizeof(unsigned char) * buffsize);
		if (buffer == NULL) {
			ErrorAbort(state, "Unable to alloc ifwi buffer of %d bytes.\n", buffsize);
			goto error;
		}
		err = mzExtractZipEntryToBuffer(&ifwi_za, ifwi_entry, buffer);
		if (!err) {
			ErrorAbort(state, "Failed to unzip %s\n", IFWI_BIN_PATH);
			free(buffer);
			goto error;
		}

		if (check_ifwi_file(buffer, buffsize) < 1) {
			free(buffer);
			continue;
		}

		if (flash_option == FLASH_BOM_TOKEN_BINARY) {
#ifdef TEE_FRAMEWORK
			strcpy(bom_token_name, BOM_TOKEN_NAME);
			strncat(bom_token_name, &(ifwi_name[strlen(IFWI_NAME)]),
				sizeof(bom_token_name) - strlen(BOM_TOKEN_NAME) - 1);
			bom_token_entry = mzFindZipEntry(&ifwi_za, bom_token_name);

			if (bom_token_entry != NULL) {
				bom_token_buffsize = mzGetZipEntryUncompLen(bom_token_entry);
				if (bom_token_buffsize <= 0) {
					ErrorAbort(state, "Bad bom_token_entry size : %d.\n",
						   bom_token_buffsize);
					free(buffer);
					goto error;
				}
				bom_token_buffer =
				    (unsigned char *)malloc(sizeof(unsigned char) * bom_token_buffsize);
				if (bom_token_buffer == NULL) {
					ErrorAbort(state, "Unable to alloc bom token buffer of %d bytes.\n",
						   bom_token_buffsize);
					free(buffer);
					goto error;
				}
				err = mzExtractZipEntryToBuffer(&ifwi_za, bom_token_entry, bom_token_buffer);
				if (!err) {
					ErrorAbort(state, "Failed to unzip %s.\n", IFWI_BIN_PATH);
					free(bom_token_buffer);
					free(buffer);
					goto error;
				}
				if (write_token(bom_token_buffer, bom_token_buffsize) == 0) {
					printf("BOM token written\n");
				} else {
					printf("Unable to write BOM token.\n");
					cancel_update(0, NULL);
					free(bom_token_buffer);
					free(buffer);
					ret = StringValue(strdup("fail"));
					goto error;
				}
				free(bom_token_buffer);
			}
#else
			printf("BOM token flashing not supported\n");
#endif
		} else if (flash_option == FLASH_IFWI_BINARY) {
			printf("Flashing IFWI\n");
			update_ifwi_file(buffer, buffsize);
		} else {
			ErrorAbort(state, "Don't know what to do with option %d\n", flash_option);
			free(buffer);
			goto error;
		}
		free(buffer);
	}

	ret = StringValue(strdup("t"));

error:
	mzCloseZipArchive(&ifwi_za);

done:
	free(file_buf);
	if (filename)
		free(filename);

	return ret;
}