ITADN

Bug: Memory Leak in `zip_source_layered`

#512OpenMicroMilo 创建于 2025-11-06
M
MicroMilocommented
In the file `zip_source_crc`, it will return the value of the function call `zip_source_layered_create`. However, `ctx` is a local variable; it is passed as an argument to `zip_source_layered_create`. Also, the function `crc_read` is the callback function passed as an argument. ```c zip_source_t * zip_source_crc_create(zip_source_t *src, int validate, zip_error_t *error) { struct crc_context *ctx; if (src == NULL) { zip_error_set(error, ZIP_ER_INVAL, 0); return NULL; } if ((ctx = (struct crc_context *)malloc(sizeof(*ctx))) == NULL) { zip_error_set(error, ZIP_ER_MEMORY, 0); return NULL; } // .. return zip_source_layered_create(src, crc_read, ctx, error); } ``` However, the function may failed! ```c zip_source_t * zip_source_layered_create(zip_source_t *src, zip_source_layered_callback cb, void *ud, zip_error_t *error) { zip_source_t *zs; zip_int64_t lower_supports, supports; lower_supports = zip_source_supports(src); supports = cb(src, ud, &lower_supports, sizeof(lower_supports), ZIP_SOURCE_SUPPORTS); if (supports < 0) { zip_error_set(error,ZIP_ER_INVAL, 0); /* Initialize in case cb doesn't return valid error. */ // ================= the callback will free ud only if the last argu is ZIP_SOURCE_FREE // leak at here ========== cb(src, ud, error, sizeof(*error), ZIP_SOURCE_ERROR); return NULL; } if ((zs = _zip_source_new(error)) == NULL) { // ================= the callback will free ud only if the last argu is ZIP_SOURCE_FREE // leak at here ========== return NULL; } // .. /* Layered sources can't support writing, since we currently have no use case. If we want to revisit this, we have to define how the two sources interact. */ zs->supports &= ~(ZIP_SOURCE_SUPPORTS_WRITABLE & ~ZIP_SOURCE_SUPPORTS_SEEKABLE); return zs; } ```
1 条评论