]> git.ipfire.org Git - pakfire.git/commitdiff
packager: Don't use an invalid pointer to a freed JSON object
authorMichael Tremer <michael.tremer@ipfire.org>
Thu, 27 Mar 2025 11:15:53 +0000 (11:15 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Thu, 27 Mar 2025 11:15:53 +0000 (11:15 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/pakfire/package.c
src/pakfire/package.h
src/pakfire/packager.c

index 401e18839dac58d0e9500f27dc2c3d18baf5b9b0..0b9107a129ea8f28ed63e387d2b650c0e6eefe94 100644 (file)
@@ -2341,14 +2341,16 @@ static int _pakfire_package_add_json_dependencies(
                struct json_object* json,
                const char* name,
                const enum pakfire_package_key key) {
+       int r;
+
        // Fetch dependencies
        char** dependencies = pakfire_package_get_deps(pkg, key);
        if (!dependencies)
-               return 1;
+               return -errno;
 
        // Add dependencies
-       int r = pakfire_json_add_string_array(json, name, dependencies);
-       if (r)
+       r = pakfire_json_add_string_array(json, name, dependencies);
+       if (r < 0)
                goto ERROR;
 
 ERROR:
@@ -2365,69 +2367,69 @@ static int pakfire_package_add_json_dependencies(
        // Create new dependencies object
        struct json_object* object = json_object_new_object();
        if (!object)
-               return 1;
+               return -errno;
 
        // Pre-requires
        r = _pakfire_package_add_json_dependencies(pkg, object,
                        "prerequires", PAKFIRE_PKG_PREREQUIRES);
-       if (r)
+       if (r < 0)
                goto ERROR;
 
        // Requires
        r = _pakfire_package_add_json_dependencies(pkg, object,
                        "requires", PAKFIRE_PKG_REQUIRES);
-       if (r)
+       if (r < 0)
                goto ERROR;
 
        // Provides
        r = _pakfire_package_add_json_dependencies(pkg, object,
                        "provides", PAKFIRE_PKG_PROVIDES);
-       if (r)
+       if (r < 0)
                goto ERROR;
 
        // Conflicts
        r = _pakfire_package_add_json_dependencies(pkg, object,
                        "conflicts", PAKFIRE_PKG_CONFLICTS);
-       if (r)
+       if (r < 0)
                goto ERROR;
 
        // Obsoletes
        r = _pakfire_package_add_json_dependencies(pkg, object,
                        "obsoletes", PAKFIRE_PKG_OBSOLETES);
-       if (r)
+       if (r < 0)
                goto ERROR;
 
        // Recommends
        r = _pakfire_package_add_json_dependencies(pkg, object,
                        "recommends", PAKFIRE_PKG_RECOMMENDS);
-       if (r)
+       if (r < 0)
                goto ERROR;
 
        // Suggests
        r = _pakfire_package_add_json_dependencies(pkg, object,
                        "suggests", PAKFIRE_PKG_SUGGESTS);
-       if (r)
+       if (r < 0)
                goto ERROR;
 
        // Supplements
        r = _pakfire_package_add_json_dependencies(pkg, object,
                        "supplements", PAKFIRE_PKG_SUPPLEMENTS);
-       if (r)
+       if (r < 0)
                goto ERROR;
 
        // Enhances
        r = _pakfire_package_add_json_dependencies(pkg, object,
                        "enhances", PAKFIRE_PKG_ENHANCES);
-       if (r)
+       if (r < 0)
                goto ERROR;
 
        // Add object
        r = json_object_object_add(md, "dependencies", object);
-       if (r)
+       if (r < 0)
                goto ERROR;
 
 ERROR:
-       if (r)
+       if (r < 0)
                json_object_put(object);
 
        return r;
@@ -2435,20 +2437,22 @@ ERROR:
 
 static int __pakfire_package_add_json_filelist(
                struct pakfire_ctx* ctx, struct pakfire_file* file, void* data) {
-       struct json_object* filelist = (struct json_object*)data;
-       int r = 1;
+       struct json_object* filelist = data;
+       int r;
 
        // Fetch the file path
        const char* path = pakfire_file_get_path(file);
 
        // Create a new JSON string
        struct json_object* object = json_object_new_string(path);
-       if (!object)
+       if (!object) {
+               r = -errno;
                goto ERROR;
+       }
 
        // Append the string
        r = json_object_array_add(filelist, object);
-       if (r)
+       if (r < 0)
                goto ERROR;
 
        return 0;
@@ -2471,34 +2475,35 @@ static int pakfire_package_add_json_filelist(
        filelist = pakfire_package_get_filelist(pkg);
        if (!filelist) {
                ERROR(pkg->ctx, "Could not fetch package filelist\n");
-               r = 1;
+               r = -EINVAL;
                goto ERROR;
        }
 
        // Create a new JSON array
        object = json_object_new_array();
        if (!object) {
-               ERROR(pkg->ctx, "Could not create a JSON array\n");
-               r = 1;
+               ERROR(pkg->ctx, "Could not create a JSON array: %m\n");
+               r = -errno;
                goto ERROR;
        }
 
        // Walk through the filelist
        r = pakfire_filelist_walk(filelist, __pakfire_package_add_json_filelist, object, 0, NULL);
-       if (r)
+       if (r < 0)
                goto ERROR;
 
        // Add object
        r = json_object_object_add(md, "filelist", object);
-       if (r)
+       if (r < 0)
                goto ERROR;
 
 ERROR:
+       if (filelist)
+               pakfire_filelist_unref(filelist);
+
        // Free JSON object on error
        if (r)
                json_object_put(object);
-       if (filelist)
-               pakfire_filelist_unref(filelist);
 
        return r;
 }
@@ -2513,12 +2518,12 @@ static int __pakfire_package_add_build_packages(struct pakfire_ctx* ctx,
 
        if (!name || !evr) {
                ERROR(ctx, "Could not fetch package information: %m\n");
-               return 1;
+               return -ENOTSUP;
        }
 
        // Add package information to the list
        r = pakfire_json_add_string(object, name, evr);
-       if (r) {
+       if (r < 0) {
                ERROR(ctx, "Could not add package to packages list: %m\n");
                return r;
        }
@@ -2536,7 +2541,7 @@ static int pakfire_package_add_build_packages(struct pakfire_package* pkg,
        object = json_object_new_object();
        if (!object) {
                ERROR(pkg->ctx, "Could not create a new JSON object: %m\n");
-               r = 1;
+               r = -errno;
                goto ERROR;
        }
 
@@ -2544,18 +2549,18 @@ static int pakfire_package_add_build_packages(struct pakfire_package* pkg,
        repo = pakfire_get_installed_repo(pkg->pakfire);
        if (!repo) {
                ERROR(pkg->ctx, "Could not fetch the installed repository: %m\n");
-               r = 1;
+               r = -EINVAL;
                goto ERROR;
        }
 
        // Add all packages to the array
        r = pakfire_repo_walk_packages(repo, __pakfire_package_add_build_packages, object, 0);
-       if (r)
+       if (r < 0)
                goto ERROR;
 
        // Add object
        r = json_object_object_add(md, "packages", json_object_get(object));
-       if (r)
+       if (r < 0)
                goto ERROR;
 
 ERROR:
@@ -2574,18 +2579,18 @@ static int pakfire_package_add_build_metadata(struct pakfire_package* pkg,
        // Create a new JSON object
        struct json_object* object = json_object_new_object();
        if (!object)
-               return 1;
+               return -errno;
 
        // Add pakfire version that generated this metadata
        r = pakfire_json_add_string(object, "pakfire", PACKAGE_VERSION);
-       if (r)
+       if (r < 0)
                goto ERROR;
 
        // Write build host
        const char* build_host = pakfire_package_get_string(pkg, PAKFIRE_PKG_BUILD_HOST);
        if (build_host) {
                r = pakfire_json_add_string(object, "host", build_host);
-               if (r)
+               if (r < 0)
                        goto ERROR;
        }
 
@@ -2593,7 +2598,7 @@ static int pakfire_package_add_build_metadata(struct pakfire_package* pkg,
        const char* build_id = pakfire_package_get_string(pkg, PAKFIRE_PKG_BUILD_ID);
        if (build_id) {
                r = pakfire_json_add_string(object, "id", build_id);
-               if (r)
+               if (r < 0)
                        goto ERROR;
        }
 
@@ -2601,7 +2606,7 @@ static int pakfire_package_add_build_metadata(struct pakfire_package* pkg,
        time_t build_time = pakfire_package_get_num(pkg, PAKFIRE_PKG_BUILD_TIME, 0);
        if (build_time) {
                r = pakfire_json_add_int64(object, "time", build_time);
-               if (r)
+               if (r < 0)
                        goto ERROR;
        }
 
@@ -2613,7 +2618,7 @@ static int pakfire_package_add_build_metadata(struct pakfire_package* pkg,
                // Cleanup
                pakfire_strings_free(build_arches);
 
-               if (r)
+               if (r < 0)
                        goto ERROR;
        }
 
@@ -2621,7 +2626,7 @@ static int pakfire_package_add_build_metadata(struct pakfire_package* pkg,
        const char* name = pakfire_package_get_string(pkg, PAKFIRE_PKG_SOURCE_NAME);
        if (name) {
                r = pakfire_json_add_string(object, "source-name", name);
-               if (r)
+               if (r < 0)
                        goto ERROR;
        }
 
@@ -2629,7 +2634,7 @@ static int pakfire_package_add_build_metadata(struct pakfire_package* pkg,
        const char* evr = pakfire_package_get_string(pkg, PAKFIRE_PKG_SOURCE_EVR);
        if (evr) {
                r = pakfire_json_add_string(object, "source-evr", evr);
-               if (r)
+               if (r < 0)
                        goto ERROR;
        }
 
@@ -2637,20 +2642,20 @@ static int pakfire_package_add_build_metadata(struct pakfire_package* pkg,
        const char* arch = pakfire_package_get_string(pkg, PAKFIRE_PKG_SOURCE_ARCH);
        if (arch) {
                r = pakfire_json_add_string(object, "source-arch", arch);
-               if (r)
+               if (r < 0)
                        goto ERROR;
        }
 
        // Build Packages
        if (!pakfire_package_is_source(pkg)) {
                r = pakfire_package_add_build_packages(pkg, object);
-               if (r)
+               if (r < 0)
                        goto ERROR;
        }
 
        // Add object
        r = json_object_object_add(md, "build", object);
-       if (r)
+       if (r < 0)
                goto ERROR;
 
 ERROR:
@@ -2660,15 +2665,22 @@ ERROR:
        return r;
 }
 
-struct json_object* pakfire_package_to_json(struct pakfire_package* pkg) {
-       struct json_object* md = json_object_new_object();
+int pakfire_package_to_json(struct pakfire_package* pkg, struct json_object** json) {
+       struct json_object* md = NULL;
        int r = 0;
 
+       // Allocate a new JSON object
+       md = json_object_new_object();
+       if (!md) {
+               r = -errno;
+               goto ERROR;
+       }
+
        // Name
        const char* name = pakfire_package_get_string(pkg, PAKFIRE_PKG_NAME);
        if (name) {
                r = pakfire_json_add_string(md, "name", name);
-               if (r)
+               if (r < 0)
                        goto ERROR;
        }
 
@@ -2676,7 +2688,7 @@ struct json_object* pakfire_package_to_json(struct pakfire_package* pkg) {
        const char* evr = pakfire_package_get_string(pkg, PAKFIRE_PKG_EVR);
        if (evr) {
                r = pakfire_json_add_string(md, "evr", evr);
-               if (r)
+               if (r < 0)
                        goto ERROR;
        }
 
@@ -2684,7 +2696,7 @@ struct json_object* pakfire_package_to_json(struct pakfire_package* pkg) {
        const char* arch = pakfire_package_get_string(pkg, PAKFIRE_PKG_ARCH);
        if (arch) {
                r = pakfire_json_add_string(md, "arch", arch);
-               if (r)
+               if (r < 0)
                        goto ERROR;
        }
 
@@ -2692,7 +2704,7 @@ struct json_object* pakfire_package_to_json(struct pakfire_package* pkg) {
        const char* vendor = pakfire_package_get_string(pkg, PAKFIRE_PKG_VENDOR);
        if (vendor) {
                r = pakfire_json_add_string(md, "vendor", vendor);
-               if (r)
+               if (r < 0)
                        goto ERROR;
        }
 
@@ -2700,7 +2712,7 @@ struct json_object* pakfire_package_to_json(struct pakfire_package* pkg) {
        const char* distribution = pakfire_package_get_string(pkg, PAKFIRE_PKG_DISTRO);
        if (distribution) {
                r = pakfire_json_add_string(md, "distribution", distribution);
-               if (r)
+               if (r < 0)
                        goto ERROR;
        }
 
@@ -2708,7 +2720,7 @@ struct json_object* pakfire_package_to_json(struct pakfire_package* pkg) {
        const char* uuid = pakfire_package_get_string(pkg, PAKFIRE_PKG_UUID);
        if (uuid) {
                r = pakfire_json_add_string(md, "uuid", uuid);
-               if (r)
+               if (r < 0)
                        goto ERROR;
        }
 
@@ -2720,7 +2732,7 @@ struct json_object* pakfire_package_to_json(struct pakfire_package* pkg) {
                // Cleanup
                pakfire_strings_free(groups);
 
-               if (r)
+               if (r < 0)
                        goto ERROR;
        }
 
@@ -2728,7 +2740,7 @@ struct json_object* pakfire_package_to_json(struct pakfire_package* pkg) {
        const char* packager = pakfire_package_get_string(pkg, PAKFIRE_PKG_PACKAGER);
        if (packager) {
                r = pakfire_json_add_string(md, "packager", packager);
-               if (r)
+               if (r < 0)
                        goto ERROR;
        }
 
@@ -2736,7 +2748,7 @@ struct json_object* pakfire_package_to_json(struct pakfire_package* pkg) {
        const char* url = pakfire_package_get_string(pkg, PAKFIRE_PKG_URL);
        if (url) {
                r = pakfire_json_add_string(md, "url", url);
-               if (r)
+               if (r < 0)
                        goto ERROR;
        }
 
@@ -2744,7 +2756,7 @@ struct json_object* pakfire_package_to_json(struct pakfire_package* pkg) {
        const char* license = pakfire_package_get_string(pkg, PAKFIRE_PKG_LICENSE);
        if (license) {
                r = pakfire_json_add_string(md, "license", license);
-               if (r)
+               if (r < 0)
                        goto ERROR;
        }
 
@@ -2752,7 +2764,7 @@ struct json_object* pakfire_package_to_json(struct pakfire_package* pkg) {
        const char* summary = pakfire_package_get_string(pkg, PAKFIRE_PKG_SUMMARY);
        if (summary) {
                r = pakfire_json_add_string(md, "summary", summary);
-               if (r)
+               if (r < 0)
                        goto ERROR;
        }
 
@@ -2760,7 +2772,7 @@ struct json_object* pakfire_package_to_json(struct pakfire_package* pkg) {
        const char* description = pakfire_package_get_string(pkg, PAKFIRE_PKG_DESCRIPTION);
        if (description) {
                r = pakfire_json_add_string(md, "description", description);
-               if (r)
+               if (r < 0)
                        goto ERROR;
        }
 
@@ -2768,29 +2780,34 @@ struct json_object* pakfire_package_to_json(struct pakfire_package* pkg) {
        unsigned long long installsize = pakfire_package_get_num(pkg, PAKFIRE_PKG_INSTALLSIZE, 0);
 
        r = pakfire_json_add_uint64(md, "size", installsize);
-       if (r)
+       if (r < 0)
                goto ERROR;
 
        // Generate dependency metadata
        r = pakfire_package_add_json_dependencies(pkg, md);
-       if (r)
+       if (r < 0)
                goto ERROR;
 
        // Generate filelist
        r = pakfire_package_add_json_filelist(pkg, md);
-       if (r)
+       if (r < 0)
                goto ERROR;
 
        // Generate build metadata
        r = pakfire_package_add_build_metadata(pkg, md);
-       if (r)
+       if (r < 0)
                goto ERROR;
 
+       // Return the JSON metadata object
+       *json = md;
+
+       return 0;
+
 ERROR:
-       if (r)
+       if (md)
                json_object_put(md);
 
-       return md;
+       return r;
 }
 
 int pakfire_package_installcheck(struct pakfire_package* pkg,
index 935e95cb465d36fd5f1ad80a707fe0112f04f5e7..1c67d2e968cc5e05b57e47d0c03ba49e67af0d91 100644 (file)
@@ -191,6 +191,6 @@ int pakfire_package_has_rich_deps(struct pakfire_package* pkg);
 int pakfire_package_matches_dep(struct pakfire_package* pkg,
        const enum pakfire_package_key key, const char* dep);
 
-struct json_object* pakfire_package_to_json(struct pakfire_package* pkg);
+int pakfire_package_to_json(struct pakfire_package* pkg, struct json_object** json);
 
 #endif /* PAKFIRE_PACKAGE_H */
index 372a2b9291ea52f1b8e03943c5ec34c1a27c9171..506aeeb276607ffe7d8f8fd7fa4f02dc5eb7bba3 100644 (file)
@@ -262,9 +262,9 @@ static int pakfire_packager_write_metadata(struct pakfire_packager* packager,
        int r;
 
        // Convert all package metadata to JSON
-       md = pakfire_package_to_json(packager->pkg);
-       if (!md) {
-               r = -errno;
+       r = pakfire_package_to_json(packager->pkg, &md);
+       if (r < 0) {
+               ERROR(packager->ctx, "Failed to create package metadata: %s\n", strerror(-r));
                goto ERROR;
        }