...
 
Commits (9)
......@@ -4,7 +4,7 @@
-include config.mk
PACKAGE := apk-tools
VERSION := 2.6.8
VERSION := 2.6.10
##
# Default directories
......
......@@ -587,5 +587,8 @@ err:
free(ctx);
fetchConnectionCacheClose();
if (r < 0) r = 250;
if (r > 99) r = 99;
return r;
}
......@@ -28,7 +28,8 @@ int apk_tar_write_entry(struct apk_ostream *, const struct apk_file_info *ae,
int apk_tar_write_padding(struct apk_ostream *, const struct apk_file_info *ae);
int apk_archive_entry_extract(int atfd, const struct apk_file_info *ae,
const char *suffix, struct apk_istream *is,
const char *extract_name, const char *hardlink_name,
struct apk_istream *is,
apk_progress_cb cb, void *cb_ctx);
#endif
......@@ -96,11 +96,11 @@ struct apk_istream *apk_istream_from_file(int atfd, const char *file);
struct apk_istream *apk_istream_from_file_gz(int atfd, const char *file);
struct apk_istream *apk_istream_from_fd_url_if_modified(int atfd, const char *url, time_t since);
struct apk_istream *apk_istream_from_url_gz(const char *url);
size_t apk_istream_skip(struct apk_istream *istream, size_t size);
ssize_t apk_istream_skip(struct apk_istream *istream, size_t size);
#define APK_SPLICE_ALL 0xffffffff
size_t apk_istream_splice(void *stream, int fd, size_t size,
apk_progress_cb cb, void *cb_ctx);
ssize_t apk_istream_splice(void *stream, int fd, size_t size,
apk_progress_cb cb, void *cb_ctx);
static inline struct apk_istream *apk_istream_from_fd(int fd)
{
......
......@@ -59,7 +59,7 @@ struct apk_tar_digest_info {
#define GET_OCTAL(s) get_octal(s, sizeof(s))
#define PUT_OCTAL(s,v) put_octal(s, sizeof(s), v)
static int get_octal(char *s, size_t l)
static unsigned int get_octal(char *s, size_t l)
{
apk_blob_t b = APK_BLOB_PTR_LEN(s, l);
return apk_blob_pull_uint(&b, 8);
......@@ -105,12 +105,17 @@ static ssize_t tar_entry_read(void *stream, void *ptr, size_t size)
if (size > teis->bytes_left)
size = teis->bytes_left;
if (size == 0)
return 0;
if (size == 0)
return 0;
r = teis->tar_is->read(teis->tar_is, ptr, size);
if (r < 0)
if (r <= 0) {
/* If inner stream returned zero (end-of-stream), we
* are getting short read, because tar header indicated
* more was to be expected. */
if (r == 0) return -ECONNABORTED;
return r;
}
teis->bytes_left -= r;
if (teis->csum == NULL)
......@@ -128,7 +133,7 @@ static void tar_entry_close(void *stream)
{
}
static int blob_realloc(apk_blob_t *b, int newsize)
static int blob_realloc(apk_blob_t *b, size_t newsize)
{
char *tmp;
if (b->len >= newsize) return 0;
......@@ -228,6 +233,8 @@ int apk_tar_parse(struct apk_istream *is, apk_archive_entry_parser parser,
teis.mtime = entry.mtime;
apk_xattr_array_resize(&entry.xattrs, 0);
if (entry.size >= SSIZE_MAX-512) goto err;
if (paxlen) {
handle_extended_header(&entry, APK_BLOB_PTR_LEN(pax.ptr, paxlen));
apk_fileinfo_hash_xattr(&entry);
......@@ -235,9 +242,10 @@ int apk_tar_parse(struct apk_istream *is, apk_archive_entry_parser parser,
switch (buf.typeflag) {
case 'L': /* GNU long name extension */
if (blob_realloc(&longname, entry.size+1)) goto err_nomem;
if ((r = blob_realloc(&longname, entry.size+1)) != 0 ||
(r = is->read(is, longname.ptr, entry.size)) != entry.size)
goto err;
entry.name = longname.ptr;
is->read(is, entry.name, entry.size);
entry.name[entry.size] = 0;
offset += entry.size;
entry.size = 0;
......@@ -279,19 +287,29 @@ int apk_tar_parse(struct apk_istream *is, apk_archive_entry_parser parser,
case '5': /* directory */
entry.mode |= S_IFDIR;
break;
case '6': /* fifo */
entry.mode |= S_IFIFO;
break;
case 'g': /* global pax header */
break;
case 'x': /* file specific pax header */
paxlen = entry.size;
entry.size = 0;
if (blob_realloc(&pax, (paxlen + 511) & -512)) goto err_nomem;
is->read(is, pax.ptr, paxlen);
if ((r = blob_realloc(&pax, (paxlen + 511) & -512)) != 0 ||
(r = is->read(is, pax.ptr, paxlen)) != paxlen)
goto err;
offset += paxlen;
break;
default:
break;
}
if (strnlen(entry.name, PATH_MAX) >= PATH_MAX-10 ||
(entry.link_target && strnlen(entry.link_target, PATH_MAX) >= PATH_MAX-10)) {
r = -ENAMETOOLONG;
goto err;
}
teis.bytes_left = entry.size;
if (entry.mode & S_IFMT) {
/* callback parser function */
......@@ -311,8 +329,10 @@ int apk_tar_parse(struct apk_istream *is, apk_archive_entry_parser parser,
if ((offset + toskip) & 511)
toskip += 512 - ((offset + toskip) & 511);
offset += toskip;
if (toskip != 0)
is->read(is, NULL, toskip);
if (toskip != 0) {
if ((r = is->read(is, NULL, toskip)) != toskip)
goto err;
}
}
/* Read remaining end-of-archive records, to ensure we read all of
......@@ -322,20 +342,16 @@ int apk_tar_parse(struct apk_istream *is, apk_archive_entry_parser parser,
if (buf.name[0] != 0) break;
}
}
/* Check that there was no partial (or non-zero) record */
if (r > 0) r = -EBADMSG;
if (r == 0) goto ok;
err:
/* Check that there was no partial (or non-zero) record */
if (r >= 0) r = -EBADMSG;
ok:
EVP_MD_CTX_cleanup(&teis.mdctx);
free(pax.ptr);
free(longname.ptr);
apk_fileinfo_free(&entry);
return r;
err_nomem:
r = -ENOMEM;
goto err;
}
int apk_tar_write_entry(struct apk_ostream *os, const struct apk_file_info *ae,
......@@ -405,23 +421,15 @@ int apk_tar_write_padding(struct apk_ostream *os, const struct apk_file_info *ae
}
int apk_archive_entry_extract(int atfd, const struct apk_file_info *ae,
const char *suffix, struct apk_istream *is,
const char *extract_name, const char *link_target,
struct apk_istream *is,
apk_progress_cb cb, void *cb_ctx)
{
struct apk_xattr *xattr;
char *fn = ae->name;
const char *fn = extract_name ?: ae->name;
int fd, r = -1, atflags = 0, ret = 0;
if (suffix != NULL) {
fn = alloca(PATH_MAX);
snprintf(fn, PATH_MAX, "%s%s", ae->name, suffix);
}
if ((!S_ISDIR(ae->mode) && !S_ISREG(ae->mode)) ||
(ae->link_target != NULL)) {
/* non-standard entries need to be deleted first */
unlinkat(atfd, fn, 0);
}
if (unlinkat(atfd, fn, 0) != 0 && errno != ENOENT) return -errno;
switch (ae->mode & S_IFMT) {
case S_IFDIR:
......@@ -431,7 +439,7 @@ int apk_archive_entry_extract(int atfd, const struct apk_file_info *ae,
break;
case S_IFREG:
if (ae->link_target == NULL) {
int flags = O_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC;
int flags = O_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC | O_EXCL;
fd = openat(atfd, fn, flags, ae->mode & 07777);
if (fd < 0) {
......@@ -442,26 +450,19 @@ int apk_archive_entry_extract(int atfd, const struct apk_file_info *ae,
if (r != ae->size) ret = r < 0 ? r : -ENOSPC;
close(fd);
} else {
char *link_target = ae->link_target;
if (suffix != NULL) {
link_target = alloca(PATH_MAX);
snprintf(link_target, PATH_MAX, "%s%s",
ae->link_target, suffix);
}
r = linkat(atfd, link_target, atfd, fn, 0);
r = linkat(atfd, link_target ?: ae->link_target, atfd, fn, 0);
if (r < 0) ret = -errno;
}
break;
case S_IFLNK:
r = symlinkat(ae->link_target, atfd, fn);
r = symlinkat(link_target ?: ae->link_target, atfd, fn);
if (r < 0) ret = -errno;
atflags |= AT_SYMLINK_NOFOLLOW;
break;
case S_IFSOCK:
case S_IFBLK:
case S_IFCHR:
case S_IFIFO:
r = mknodat(atfd, fn, ae->mode & 07777, ae->device);
r = mknodat(atfd, fn, ae->mode, ae->device);
if (r < 0) ret = -errno;
break;
}
......
......@@ -815,8 +815,9 @@ int apk_db_index_read(struct apk_database *db, struct apk_bstream *bs, int repo)
case 'F':
if (diri) apk_db_dir_apply_diri_permissions(diri);
if (pkg->name == NULL) goto bad_entry;
diri = apk_db_diri_new(db, pkg, l, &diri_node);
file_diri_node = &diri->owned_files.first;
diri = find_diri(ipkg, l, NULL, &diri_node);
if (!diri) diri = apk_db_diri_new(db, pkg, l, &diri_node);
file_diri_node = hlist_tail_ptr(&diri->owned_files);
break;
case 'a':
if (file == NULL) goto bad_entry;
......@@ -2291,6 +2292,31 @@ static struct apk_db_dir_instance *apk_db_install_directory_entry(struct install
return diri;
}
#define TMPNAME_MAX (PATH_MAX + 64)
static const char *format_tmpname(struct apk_package *pkg, struct apk_db_file *f, char tmpname[static TMPNAME_MAX])
{
EVP_MD_CTX mdctx;
unsigned char md[EVP_MAX_MD_SIZE];
apk_blob_t b = APK_BLOB_PTR_LEN(tmpname, TMPNAME_MAX);
if (!f) return NULL;
EVP_DigestInit(&mdctx, EVP_sha256());
EVP_DigestUpdate(&mdctx, pkg->name->name, strlen(pkg->name->name) + 1);
EVP_DigestUpdate(&mdctx, f->diri->dir->name, f->diri->dir->namelen);
EVP_DigestUpdate(&mdctx, "/", 1);
EVP_DigestUpdate(&mdctx, f->name, f->namelen);
EVP_DigestFinal(&mdctx, md, NULL);
apk_blob_push_blob(&b, APK_BLOB_PTR_LEN(f->diri->dir->name, f->diri->dir->namelen));
apk_blob_push_blob(&b, APK_BLOB_STR("/.apk."));
apk_blob_push_hexdump(&b, APK_BLOB_PTR_LEN((char *)md, 24));
apk_blob_push_blob(&b, APK_BLOB_PTR_LEN("", 1));
return tmpname;
}
static int apk_db_install_archive_entry(void *_ctx,
const struct apk_file_info *ae,
struct apk_istream *is)
......@@ -2302,8 +2328,9 @@ static int apk_db_install_archive_entry(void *_ctx,
struct apk_installed_package *ipkg = pkg->ipkg;
apk_blob_t name = APK_BLOB_STR(ae->name), bdir, bfile;
struct apk_db_dir_instance *diri = ctx->diri;
struct apk_db_file *file;
struct apk_db_file *file, *link_target_file = NULL;
int ret = 0, r, type = APK_SCRIPT_INVALID;
char tmpname_file[TMPNAME_MAX], tmpname_link_target[TMPNAME_MAX];
r = apk_sign_ctx_process_file(&ctx->sctx, ae, is);
if (r <= 0)
......@@ -2370,6 +2397,40 @@ static int apk_db_install_archive_entry(void *_ctx,
diri = apk_db_install_directory_entry(ctx, bdir);
}
/* Check hard link target to exist in this package */
if (S_ISREG(ae->mode) && ae->link_target) {
do {
struct apk_db_file *lfile;
struct apk_db_dir_instance *ldiri;
struct hlist_node *n;
apk_blob_t hldir, hlfile;
if (!apk_blob_rsplit(APK_BLOB_STR(ae->link_target),
'/', &hldir, &hlfile))
break;
ldiri = find_diri(ipkg, hldir, diri, NULL);
if (ldiri == NULL)
break;
hlist_for_each_entry(lfile, n, &ldiri->owned_files,
diri_files_list) {
if (apk_blob_compare(APK_BLOB_PTR_LEN(lfile->name, lfile->namelen),
hlfile) == 0) {
link_target_file = lfile;
break;
}
}
} while (0);
if (!link_target_file) {
apk_error(PKG_VER_FMT": "BLOB_FMT": no hard link target (%s) in archive",
PKG_VER_PRINTF(pkg), BLOB_PRINTF(name), ae->link_target);
ipkg->broken_files = 1;
return 0;
}
}
opkg = NULL;
file = apk_db_file_query(db, bdir, bfile);
if (file != NULL) {
......@@ -2428,41 +2489,21 @@ static int apk_db_install_archive_entry(void *_ctx,
if (apk_verbosity >= 3)
apk_message("%s", ae->name);
/* Extract the file as name.apk-new */
/* Extract the file with temporary name */
file->acl = apk_db_acl_atomize(ae->mode, ae->uid, ae->gid, &ae->xattr_csum);
r = apk_archive_entry_extract(db->root_fd, ae, ".apk-new", is,
extract_cb, ctx);
r = apk_archive_entry_extract(
db->root_fd, ae,
format_tmpname(pkg, file, tmpname_file),
format_tmpname(pkg, link_target_file, tmpname_link_target),
is, extract_cb, ctx);
switch (r) {
case 0:
/* Hardlinks need special care for checksum */
if (ae->csum.type == APK_CHECKSUM_NONE &&
ae->link_target != NULL) {
do {
struct apk_db_file *lfile;
struct apk_db_dir_instance *ldiri;
struct hlist_node *n;
if (!apk_blob_rsplit(APK_BLOB_STR(ae->link_target),
'/', &bdir, &bfile))
break;
ldiri = find_diri(ipkg, bdir, diri, NULL);
if (ldiri == NULL)
break;
hlist_for_each_entry(lfile, n, &ldiri->owned_files,
diri_files_list) {
if (apk_blob_compare(APK_BLOB_PTR_LEN(lfile->name, lfile->namelen),
bfile) == 0) {
memcpy(&file->csum, &lfile->csum,
sizeof(file->csum));
break;
}
}
} while (0);
} else
memcpy(&file->csum, &ae->csum, sizeof(file->csum));
if (link_target_file)
memcpy(&file->csum, &link_target_file->csum, sizeof file->csum);
else
memcpy(&file->csum, &ae->csum, sizeof file->csum);
break;
case -ENOTSUP:
ipkg->broken_xattr = 1;
......@@ -2480,8 +2521,11 @@ static int apk_db_install_archive_entry(void *_ctx,
if (name.ptr[name.len-1] == '/')
name.len--;
diri = apk_db_install_directory_entry(ctx, name);
apk_db_dir_prepare(db, diri->dir, ae->mode);
diri = ctx->diri = find_diri(ipkg, name, NULL, &ctx->file_diri_node);
if (!diri) {
diri = apk_db_install_directory_entry(ctx, name);
apk_db_dir_prepare(db, diri->dir, ae->mode);
}
apk_db_diri_set(diri, apk_db_acl_atomize(ae->mode, ae->uid, ae->gid, &ae->xattr_csum));
}
ctx->installed_size += ctx->current_file_size;
......@@ -2491,7 +2535,7 @@ static int apk_db_install_archive_entry(void *_ctx,
static void apk_db_purge_pkg(struct apk_database *db,
struct apk_installed_package *ipkg,
const char *exten)
int is_installed)
{
struct apk_db_dir_instance *diri;
struct apk_db_file *file;
......@@ -2499,17 +2543,16 @@ static void apk_db_purge_pkg(struct apk_database *db,
struct apk_file_info fi;
struct hlist_node *dc, *dn, *fc, *fn;
unsigned long hash;
char name[PATH_MAX];
char name[TMPNAME_MAX];
hlist_for_each_entry_safe(diri, dc, dn, &ipkg->owned_dirs, pkg_dirs_list) {
if (exten == NULL)
diri->dir->modified = 1;
if (is_installed) diri->dir->modified = 1;
hlist_for_each_entry_safe(file, fc, fn, &diri->owned_files, diri_files_list) {
snprintf(name, sizeof(name),
DIR_FILE_FMT "%s",
DIR_FILE_PRINTF(diri->dir, file),
exten ?: "");
if (is_installed)
snprintf(name, sizeof name, DIR_FILE_FMT, DIR_FILE_PRINTF(diri->dir, file));
else
format_tmpname(ipkg->pkg, file, name);
key = (struct apk_db_file_hash_key) {
.dirname = APK_BLOB_PTR_LEN(diri->dir->name, diri->dir->namelen),
......@@ -2525,7 +2568,7 @@ static void apk_db_purge_pkg(struct apk_database *db,
if (apk_verbosity >= 3)
apk_message("%s", name);
__hlist_del(fc, &diri->owned_files.first);
if (exten == NULL) {
if (is_installed) {
apk_hash_delete_hashed(&db->installed.files, APK_BLOB_BUF(&key), hash);
db->installed.stats.files--;
}
......@@ -2546,7 +2589,7 @@ static void apk_db_migrate_files(struct apk_database *db,
struct apk_file_info fi;
struct hlist_node *dc, *dn, *fc, *fn;
unsigned long hash;
char name[PATH_MAX], tmpname[PATH_MAX];
char name[PATH_MAX], tmpname[TMPNAME_MAX];
int cstype, r;
hlist_for_each_entry_safe(diri, dc, dn, &ipkg->owned_dirs, pkg_dirs_list) {
......@@ -2554,10 +2597,8 @@ static void apk_db_migrate_files(struct apk_database *db,
dir->modified = 1;
hlist_for_each_entry_safe(file, fc, fn, &diri->owned_files, diri_files_list) {
snprintf(name, sizeof(name), DIR_FILE_FMT,
DIR_FILE_PRINTF(diri->dir, file));
snprintf(tmpname, sizeof(tmpname), DIR_FILE_FMT ".apk-new",
DIR_FILE_PRINTF(diri->dir, file));
snprintf(name, sizeof(name), DIR_FILE_FMT, DIR_FILE_PRINTF(diri->dir, file));
format_tmpname(ipkg->pkg, file, tmpname);
key = (struct apk_db_file_hash_key) {
.dirname = APK_BLOB_PTR_LEN(dir->name, dir->namelen),
......@@ -2598,8 +2639,21 @@ static void apk_db_migrate_files(struct apk_database *db,
APK_FI_NOFOLLOW | file->csum.type, &fi);
if ((apk_flags & APK_CLEAN_PROTECTED) ||
(file->csum.type != APK_CHECKSUM_NONE &&
apk_checksum_compare(&file->csum, &fi.csum) == 0))
apk_checksum_compare(&file->csum, &fi.csum) == 0)) {
unlinkat(db->root_fd, tmpname, 0);
} else {
snprintf(name, sizeof name,
DIR_FILE_FMT ".apk-new",
DIR_FILE_PRINTF(diri->dir, file));
if (renameat(db->root_fd, tmpname,
db->root_fd, name) != 0) {
apk_error(PKG_VER_FMT": failed to rename %s to %s.",
PKG_VER_PRINTF(ipkg->pkg),
tmpname, name);
ipkg->broken_files = 1;
}
}
} else {
/* Overwrite the old file */
renameat(db->root_fd, tmpname,
......@@ -2728,7 +2782,7 @@ int apk_db_install_pkg(struct apk_database *db, struct apk_package *oldpkg,
if (ipkg == NULL)
goto ret_r;
apk_ipkg_run_script(ipkg, db, APK_SCRIPT_PRE_DEINSTALL, script_args);
apk_db_purge_pkg(db, ipkg, NULL);
apk_db_purge_pkg(db, ipkg, TRUE);
apk_ipkg_run_script(ipkg, db, APK_SCRIPT_POST_DEINSTALL, script_args);
apk_pkg_uninstall(db, oldpkg);
goto ret_r;
......@@ -2751,7 +2805,7 @@ int apk_db_install_pkg(struct apk_database *db, struct apk_package *oldpkg,
cb, cb_ctx, script_args);
if (r != 0) {
if (oldpkg != newpkg)
apk_db_purge_pkg(db, ipkg, ".apk-new");
apk_db_purge_pkg(db, ipkg, FALSE);
apk_pkg_uninstall(db, newpkg);
goto ret_r;
}
......@@ -2759,7 +2813,7 @@ int apk_db_install_pkg(struct apk_database *db, struct apk_package *oldpkg,
}
if (oldpkg != NULL && oldpkg != newpkg && oldpkg->ipkg != NULL) {
apk_db_purge_pkg(db, oldpkg->ipkg, NULL);
apk_db_purge_pkg(db, oldpkg->ipkg, TRUE);
apk_pkg_uninstall(db, oldpkg);
}
......
......@@ -37,6 +37,16 @@ static void gzi_get_meta(void *stream, struct apk_file_meta *meta)
gis->bs->get_meta(gis->bs, meta);
}
static int gzi_boundary_change(struct apk_gzip_istream *gis)
{
int r;
r = gis->cb(gis->cbctx, gis->err ? APK_MPART_END : APK_MPART_BOUNDARY, gis->cbarg);
if (r > 0) r = -ECANCELED;
if (r != 0) gis->err = r;
return r;
}
static ssize_t gzi_read(void *stream, void *ptr, size_t size)
{
struct apk_gzip_istream *gis =
......@@ -57,15 +67,8 @@ static ssize_t gzi_read(void *stream, void *ptr, size_t size)
while (gis->zs.avail_out != 0 && gis->err == 0) {
if (!APK_BLOB_IS_NULL(gis->cbarg)) {
r = gis->cb(gis->cbctx,
gis->err ? APK_MPART_END : APK_MPART_BOUNDARY,
gis->cbarg);
if (r > 0)
r = -ECANCELED;
if (r != 0) {
gis->err = r;
if (gzi_boundary_change(gis))
goto ret;
}
gis->cbarg = APK_BLOB_NULL;
}
if (gis->zs.avail_in == 0) {
......@@ -86,14 +89,8 @@ static ssize_t gzi_read(void *stream, void *ptr, size_t size)
goto ret;
} else if (gis->zs.avail_in == 0) {
gis->err = 1;
if (gis->cb != NULL) {
r = gis->cb(gis->cbctx, APK_MPART_END,
APK_BLOB_NULL);
if (r > 0)
r = -ECANCELED;
if (r != 0)
gis->err = r;
}
gis->cbarg = APK_BLOB_NULL;
gzi_boundary_change(gis);
goto ret;
}
}
......@@ -115,11 +112,7 @@ static ssize_t gzi_read(void *stream, void *ptr, size_t size)
* For boundaries it should be postponed to not
* be called until next gzip read is started. */
if (gis->err) {
r = gis->cb(gis->cbctx,
gis->err ? APK_MPART_END : APK_MPART_BOUNDARY,
gis->cbarg);
if (r > 0)
r = -ECANCELED;
gzi_boundary_change(gis);
goto ret;
}
inflateEnd(&gis->zs);
......
......@@ -21,6 +21,7 @@
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/xattr.h>
#include <sys/param.h>
#include <pwd.h>
#include <grp.h>
......@@ -144,27 +145,22 @@ struct apk_istream *apk_istream_from_file(int atfd, const char *file)
return apk_istream_from_fd(fd);
}
size_t apk_istream_skip(struct apk_istream *is, size_t size)
ssize_t apk_istream_skip(struct apk_istream *is, size_t size)
{
unsigned char buf[2048];
size_t done = 0, r, togo;
while (done < size) {
togo = size - done;
if (togo > sizeof(buf))
togo = sizeof(buf);
togo = MIN(size - done, sizeof buf);
r = is->read(is, buf, togo);
if (r < 0)
return r;
if (r <= 0) return r ?: -EIO;
done += r;
if (r != togo)
break;
}
return done;
}
size_t apk_istream_splice(void *stream, int fd, size_t size,
apk_progress_cb cb, void *cb_ctx)
ssize_t apk_istream_splice(void *stream, int fd, size_t size,
apk_progress_cb cb, void *cb_ctx)
{
static void *splice_buffer = NULL;
struct apk_istream *is = (struct apk_istream *) stream;
......@@ -181,32 +177,29 @@ size_t apk_istream_splice(void *stream, int fd, size_t size,
else if (r == EBADF || r == EFBIG || r == ENOSPC || r == EIO)
return -r;
}
if (bufsz > 2*1024*1024)
bufsz = 2*1024*1024;
bufsz = MIN(bufsz, 2*1024*1024);
buf = mmapbase;
}
if (mmapbase == MAP_FAILED) {
if (splice_buffer == NULL)
splice_buffer = malloc(256*1024);
if (!splice_buffer) splice_buffer = malloc(256*1024);
buf = splice_buffer;
if (buf == NULL)
return -ENOMEM;
if (bufsz > 256*1024)
bufsz = 256*1024;
if (!buf) return -ENOMEM;
bufsz = MIN(bufsz, 256*1024);
}
while (done < size) {
if (cb != NULL)
cb(cb_ctx, done);
if (cb != NULL) cb(cb_ctx, done);
togo = size - done;
if (togo > bufsz)
togo = bufsz;
togo = MIN(size - done, bufsz);
r = is->read(is, buf, togo);
if (r < 0)
goto err;
if (r == 0)
if (r <= 0) {
if (r) goto err;
if (size != APK_SPLICE_ALL && done != size) {
r = -EBADMSG;
goto err;
}
break;
}
if (mmapbase == MAP_FAILED) {
if (write(fd, buf, r) != r) {
......@@ -218,8 +211,6 @@ size_t apk_istream_splice(void *stream, int fd, size_t size,
buf += r;
done += r;
if (r != togo)
break;
}
r = done;
err:
......
......@@ -470,13 +470,7 @@ void apk_sign_ctx_init(struct apk_sign_ctx *ctx, int action,
ctx->md = EVP_md_null();
break;
case APK_SIGN_VERIFY_IDENTITY:
if (identity->type == APK_CHECKSUM_MD5) {
ctx->md = EVP_md5();
ctx->control_started = 1;
ctx->data_started = 1;
} else {
ctx->md = EVP_sha1();
}
ctx->md = EVP_sha1();
memcpy(&ctx->identity, identity, sizeof(ctx->identity));
break;
case APK_SIGN_GENERATE:
......@@ -534,6 +528,9 @@ int apk_sign_ctx_process_file(struct apk_sign_ctx *ctx,
* style .PKGINFO */
if (ctx->has_data_checksum)
return -ENOMSG;
/* Error out early if identity part is missing */
if (ctx->action == APK_SIGN_VERIFY_IDENTITY)
return -EKEYREJECTED;
ctx->data_started = 1;
ctx->control_started = 1;
r = check_signing_key_trust(ctx);
......