summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Zern <jzern@google.com>2023-05-05 17:26:11 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2023-05-05 17:26:11 +0000
commite2f217c075707db42ff61b790f7adc63c59f7449 (patch)
tree0c73ecd6b92c621c8b2b48c459de5ab88a087d02
parentb3920105c3758c846aead964e1217b6af4a98c15 (diff)
parent3d6b86e7045481c55b35d0daa4f19202bbe99dc1 (diff)
downloadlibvpx-e2f217c075707db42ff61b790f7adc63c59f7449.tar.gz
Merge changes I8089e90a,I46890224,I1b0e090d into main
* changes: Overwrite cm->error->detail before freeing Have vpx_codec_error take const vpx_codec_ctx_t * Add comments about vpx_codec_enc_init_ver failure
-rw-r--r--vp9/encoder/vp9_encoder.c5
-rw-r--r--vp9/vp9_cx_iface.c2
-rw-r--r--vpx/src/vpx_codec.c6
-rw-r--r--vpx/src/vpx_encoder.c4
-rw-r--r--vpx/vpx_codec.h8
-rw-r--r--vpx/vpx_encoder.h5
6 files changed, 23 insertions, 7 deletions
diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c
index 662ec24b8..f76eec2b5 100644
--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -12,6 +12,7 @@
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include "./vp9_rtcd.h"
#include "./vpx_config.h"
@@ -2873,6 +2874,10 @@ void vp9_remove_compressor(VP9_COMP *cpi) {
vp9_extrc_delete(&cpi->ext_ratectrl);
+ // Help detect use after free of the error detail string.
+ memset(cm->error.detail, 'A', sizeof(cm->error.detail) - 1);
+ cm->error.detail[sizeof(cm->error.detail) - 1] = '\0';
+
vp9_remove_common(cm);
vp9_free_ref_frame_buffers(cm->buffer_pool);
#if CONFIG_VP9_POSTPROC
diff --git a/vp9/vp9_cx_iface.c b/vp9/vp9_cx_iface.c
index e264ae9bd..f067efdf7 100644
--- a/vp9/vp9_cx_iface.c
+++ b/vp9/vp9_cx_iface.c
@@ -129,6 +129,8 @@ struct vpx_codec_alg_priv {
BufferPool *buffer_pool;
};
+// Called by encoder_set_config() and encoder_encode() only. Must not be called
+// by encoder_init().
static vpx_codec_err_t update_error_state(
vpx_codec_alg_priv_t *ctx, const struct vpx_internal_error_info *error) {
const vpx_codec_err_t res = error->error_code;
diff --git a/vpx/src/vpx_codec.c b/vpx/src/vpx_codec.c
index 114b94e19..24528d860 100644
--- a/vpx/src/vpx_codec.c
+++ b/vpx/src/vpx_codec.c
@@ -50,12 +50,12 @@ const char *vpx_codec_err_to_string(vpx_codec_err_t err) {
return "Unrecognized error code";
}
-const char *vpx_codec_error(vpx_codec_ctx_t *ctx) {
+const char *vpx_codec_error(const vpx_codec_ctx_t *ctx) {
return (ctx) ? vpx_codec_err_to_string(ctx->err)
: vpx_codec_err_to_string(VPX_CODEC_INVALID_PARAM);
}
-const char *vpx_codec_error_detail(vpx_codec_ctx_t *ctx) {
+const char *vpx_codec_error_detail(const vpx_codec_ctx_t *ctx) {
if (ctx && ctx->err)
return ctx->priv ? ctx->priv->err_detail : ctx->err_detail;
@@ -82,7 +82,7 @@ vpx_codec_err_t vpx_codec_destroy(vpx_codec_ctx_t *ctx) {
}
vpx_codec_caps_t vpx_codec_get_caps(vpx_codec_iface_t *iface) {
- return (iface) ? iface->caps : 0;
+ return iface ? iface->caps : 0;
}
vpx_codec_err_t vpx_codec_control_(vpx_codec_ctx_t *ctx, int ctrl_id, ...) {
diff --git a/vpx/src/vpx_encoder.c b/vpx/src/vpx_encoder.c
index 846638fe5..0d6e48015 100644
--- a/vpx/src/vpx_encoder.c
+++ b/vpx/src/vpx_encoder.c
@@ -54,6 +54,10 @@ vpx_codec_err_t vpx_codec_enc_init_ver(vpx_codec_ctx_t *ctx,
res = ctx->iface->init(ctx, NULL);
if (res) {
+ // IMPORTANT: ctx->priv->err_detail must be null or point to a string
+ // that remains valid after ctx->priv is destroyed, such as a C string
+ // literal. This makes it safe to call vpx_codec_error_detail() after
+ // vpx_codec_enc_init_ver() failed.
ctx->err_detail = ctx->priv ? ctx->priv->err_detail : NULL;
vpx_codec_destroy(ctx);
}
diff --git a/vpx/vpx_codec.h b/vpx/vpx_codec.h
index 11bf8aaa2..0d61b0738 100644
--- a/vpx/vpx_codec.h
+++ b/vpx/vpx_codec.h
@@ -318,19 +318,21 @@ const char *vpx_codec_err_to_string(vpx_codec_err_t err);
* \param[in] ctx Pointer to this instance's context.
*
*/
-const char *vpx_codec_error(vpx_codec_ctx_t *ctx);
+const char *vpx_codec_error(const vpx_codec_ctx_t *ctx);
/*!\brief Retrieve detailed error information for codec context
*
* Returns a human readable string providing detailed information about
- * the last error.
+ * the last error. The returned string is only valid until the next
+ * vpx_codec_* function call (except vpx_codec_error and
+ * vpx_codec_error_detail) on the codec context.
*
* \param[in] ctx Pointer to this instance's context.
*
* \retval NULL
* No detailed information is available.
*/
-const char *vpx_codec_error_detail(vpx_codec_ctx_t *ctx);
+const char *vpx_codec_error_detail(const vpx_codec_ctx_t *ctx);
/* REQUIRED FUNCTIONS
*
diff --git a/vpx/vpx_encoder.h b/vpx/vpx_encoder.h
index a7f1552de..2de808973 100644
--- a/vpx/vpx_encoder.h
+++ b/vpx/vpx_encoder.h
@@ -877,7 +877,7 @@ typedef struct vpx_svc_parameters {
/*!\brief Initialize an encoder instance
*
- * Initializes a encoder context using the given interface. Applications
+ * Initializes an encoder context using the given interface. Applications
* should call the vpx_codec_enc_init convenience macro instead of this
* function directly, to ensure that the ABI version number parameter
* is properly initialized.
@@ -886,6 +886,9 @@ typedef struct vpx_svc_parameters {
* is not thread safe and should be guarded with a lock if being used
* in a multithreaded context.
*
+ * If vpx_codec_enc_init_ver() fails, it is not necessary to call
+ * vpx_codec_destroy() on the encoder context.
+ *
* \param[in] ctx Pointer to this instance's context.
* \param[in] iface Pointer to the algorithm interface to use.
* \param[in] cfg Configuration to use, if known. May be NULL.