When mounting an OCI image with `mount.erofs -t erofs.nbd` without specifying either `oci.layer=` or `oci.blob=`, a segfault occurs in the `ocierofs_download_blob_range() → ocierofs_find_layer_by_digest()` call path due to an empty `ctx->blob_digest`.
As mounting multi-layer OCI images is not yet supported, let's exit early in `ocierofs_io_open()` with an error in this case. Signed-off-by: Yifan Zhao <[email protected]> --- lib/remotes/oci.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/lib/remotes/oci.c b/lib/remotes/oci.c index f29c344..88c1282 100644 --- a/lib/remotes/oci.c +++ b/lib/remotes/oci.c @@ -1468,7 +1468,7 @@ static struct erofs_vfops ocierofs_io_vfops = { .close = ocierofs_io_close, }; -int ocierofs_io_open(struct erofs_vfile *vfile, const struct ocierofs_config *cfg) +int ocierofs_io_open(struct erofs_vfile *vfile, const struct ocierofs_config *config) { struct ocierofs_ctx *ctx; struct ocierofs_iostream *oci_iostream = NULL; @@ -1478,17 +1478,20 @@ int ocierofs_io_open(struct erofs_vfile *vfile, const struct ocierofs_config *cf if (!ctx) return -ENOMEM; - err = ocierofs_init(ctx, cfg); - if (err) { - free(ctx); - return err; + err = ocierofs_init(ctx, config); + if (err) + goto out; + + if (!ctx->blob_digest) { + erofs_err("please specify exactly one layer (use blob= or layer= option)"); + err = -EINVAL; + goto out; } oci_iostream = calloc(1, sizeof(*oci_iostream)); if (!oci_iostream) { - ocierofs_ctx_cleanup(ctx); - free(ctx); - return -ENOMEM; + err = -ENOMEM; + goto out; } oci_iostream->ctx = ctx; @@ -1496,6 +1499,11 @@ int ocierofs_io_open(struct erofs_vfile *vfile, const struct ocierofs_config *cf *vfile = (struct erofs_vfile){.ops = &ocierofs_io_vfops}; *(struct ocierofs_iostream **)vfile->payload = oci_iostream; return 0; + +out: + ocierofs_ctx_cleanup(ctx); + free(ctx); + return err; } char *ocierofs_encode_userpass(const char *username, const char *password) -- 2.43.0
