Commit message: None
CVE: CVE-2017-13194
CWE: CWE-20
Vulnerability description: A vulnerability in the Android media framework (libvpx) related to odd frame width. Product: Android. Versions: 7.0, 7.1.1, 7.1.2, 8.0, 8.1. Android ID: A-64710201.

Project: Android

vpx_image_t *vpx_img_alloc(vpx_image_t *img, vpx_img_fmt_t fmt,
 unsigned int d_w, unsigned int d_h,
 unsigned int align) {
 return img_alloc_helper(img, fmt, d_w, d_h, align, align, NULL);
}

Project: Android

void vpx_img_flip(vpx_image_t *img) {
 /* Note: In the calculation pointer adjustment calculation, we want the
   * rhs to be promoted to a signed type. Section 6.3.1.8 of the ISO C99
   * standard indicates that if the adjustment parameter is unsigned, the
   * stride parameter will be promoted to unsigned, causing errors when
   * the lhs is a larger type than the rhs.
   */
  img->planes[VPX_PLANE_Y] += (signed)(img->d_h - 1) * img->stride[VPX_PLANE_Y];
  img->stride[VPX_PLANE_Y] = -img->stride[VPX_PLANE_Y];

  img->planes[VPX_PLANE_U] += (signed)((img->d_h >> img->y_chroma_shift) - 1) *
                              img->stride[VPX_PLANE_U];
  img->stride[VPX_PLANE_U] = -img->stride[VPX_PLANE_U];

  img->planes[VPX_PLANE_V] += (signed)((img->d_h >> img->y_chroma_shift) - 1) *
                              img->stride[VPX_PLANE_V];
  img->stride[VPX_PLANE_V] = -img->stride[VPX_PLANE_V];

  img->planes[VPX_PLANE_ALPHA] +=
 (signed)(img->d_h - 1) * img->stride[VPX_PLANE_ALPHA];
  img->stride[VPX_PLANE_ALPHA] = -img->stride[VPX_PLANE_ALPHA];
}

Project: Android

void vpx_img_free(vpx_image_t *img) {
 if (img) {
 if (img->img_data && img->img_data_owner) vpx_free(img->img_data);

 if (img->self_allocd) free(img);
 }
}

Project: Android

int vpx_img_set_rect(vpx_image_t *img, unsigned int x, unsigned int y,
 unsigned int w, unsigned int h) {
 unsigned char *data;

 if (x + w <= img->w && y + h <= img->h) {
    img->d_w = w;
    img->d_h = h;

 /* Calculate plane pointers */
 if (!(img->fmt & VPX_IMG_FMT_PLANAR)) {
      img->planes[VPX_PLANE_PACKED] =
          img->img_data + x * img->bps / 8 + y * img->stride[VPX_PLANE_PACKED];
 } else {
 const int bytes_per_sample =
 (img->fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? 2 : 1;
      data = img->img_data;

 if (img->fmt & VPX_IMG_FMT_HAS_ALPHA) {
        img->planes[VPX_PLANE_ALPHA] =
            data + x * bytes_per_sample + y * img->stride[VPX_PLANE_ALPHA];
        data += img->h * img->stride[VPX_PLANE_ALPHA];
 }

      img->planes[VPX_PLANE_Y] =
          data + x * bytes_per_sample + y * img->stride[VPX_PLANE_Y];
      data += img->h * img->stride[VPX_PLANE_Y];

 if (!(img->fmt & VPX_IMG_FMT_UV_FLIP)) {
        img->planes[VPX_PLANE_U] =
            data + (x >> img->x_chroma_shift) * bytes_per_sample +
 (y >> img->y_chroma_shift) * img->stride[VPX_PLANE_U];
        data += (img->h >> img->y_chroma_shift) * img->stride[VPX_PLANE_U];
        img->planes[VPX_PLANE_V] =
            data + (x >> img->x_chroma_shift) * bytes_per_sample +
 (y >> img->y_chroma_shift) * img->stride[VPX_PLANE_V];
 } else {
        img->planes[VPX_PLANE_V] =
            data + (x >> img->x_chroma_shift) * bytes_per_sample +
 (y >> img->y_chroma_shift) * img->stride[VPX_PLANE_V];
        data += (img->h >> img->y_chroma_shift) * img->stride[VPX_PLANE_V];
        img->planes[VPX_PLANE_U] =
            data + (x >> img->x_chroma_shift) * bytes_per_sample +
 (y >> img->y_chroma_shift) * img->stride[VPX_PLANE_U];
 }
 }
 return 0;
 }
 return -1;
}

Project: Android

vpx_image_t *vpx_img_wrap(vpx_image_t *img, vpx_img_fmt_t fmt, unsigned int d_w,
 unsigned int d_h, unsigned int stride_align,
 unsigned char *img_data) {
 /* By setting buf_align = 1, we don't change buffer alignment in this
   * function. */
 return img_alloc_helper(img, fmt, d_w, d_h, 1, stride_align, img_data);
}