记录一个`ffmpeg`的`swscale`库crash的例子

记录一个ffmpeg的swscale库crash的例子

本质上, 就是simd越界导致, 具体场景如下:

外部api分配了rgb24内存指针ptr, 然后转换为yuv420p, 如果ptr的end不可访问, 则会crash

1. simd越界例子

cpp 复制代码
#include <cstdint>
#include <immintrin.h>
#include <iostream>
#include <memory>

#ifdef _WIN32
#include <windows.h>
#elif __linux__
#include <sys/mman.h>
#include <unistd.h>
#endif

#ifdef _WIN32
void win_crash() {
  constexpr size_t N = 1024;
  constexpr size_t PAGE = 4096;
  std::shared_ptr<uint8_t> base(
      static_cast<uint8_t *>(VirtualAlloc(
          nullptr, PAGE * 2, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE)),
      [](uint8_t *p) { VirtualFree(p, 0, MEM_RELEASE); });
  DWORD old;
  VirtualProtect(base.get() + PAGE, PAGE, PAGE_NOACCESS, &old);
  uint8_t *data = base.get() + PAGE - N;
  for (size_t i = 0; i < N; ++i)
    data[i] = static_cast<uint8_t>(i);

  for (size_t i = 0; i < N; i += 8) {
    __m256i v =
        _mm256_loadu_si256(reinterpret_cast<const __m256i *>(data + 32 + i));
    uint8_t tmp = static_cast<uint8_t>(_mm256_extract_epi8(v, 0));
    std::cout << static_cast<int64_t>(tmp) << "\n";
  }
}
#endif

#ifdef __linux__
// target_compile_options(my_target_name PRIVATE -mavx2)
void linux_crash() {
  constexpr size_t N = 1024;
  constexpr size_t PAGE = 4096;
  void *p = mmap(nullptr, PAGE * 2, PROT_READ | PROT_WRITE,
                 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
  if (p == MAP_FAILED) {
    perror("mmap");
    return;
  }
  std::shared_ptr<uint8_t> base(static_cast<uint8_t *>(p),
                                [](uint8_t *p) { munmap(p, PAGE * 2); });
  if (mprotect(base.get() + PAGE, PAGE, PROT_NONE) != 0) {
    perror("mprotect");
    return;
  }
  uint8_t *data = base.get() + PAGE - N;
  for (size_t i = 0; i < N; ++i)
    data[i] = static_cast<uint8_t>(i);
  for (size_t i = 0; i < N; i += 8) {
    __m256i v = _mm256_loadu_si256(reinterpret_cast<const __m256i *>(data + i));
    uint8_t tmp = static_cast<uint8_t>(_mm256_extract_epi8(v, 0));
    std::cout << static_cast<int64_t>(tmp) << "\n";
  }
}
#endif

int main() {
  win_crash();
  // linux_crash();
  return 0;
}

ffmpeg堆栈错误信息

最终崩溃在函数指针lumToYV12中, 具体汇编代码见libswscale/x86/swscale.c和libswscale/input.asm

reference

相关推荐
可乐鸡翅yeah_6 小时前
网页端 M3U8 播放器性能监控,怎么看播放卡顿指标
javascript·ffmpeg·音视频·safari·m3u8
开开心心就好10 小时前
超市定时播音软件,免费版支持循环播放
智能手机·ffmpeg·ocr·word·vim·音视频·visual studio
企业数字化笔记12 小时前
视频成片怎么稳定导出?编码选择、GPU/CPU降级与媒体交付验收
java·python·ffmpeg
企业数字化笔记13 小时前
视觉智能体怎么选技术?目标检测、跟踪、分割、OpenCV和FFmpeg的职责划分
opencv·目标检测·ffmpeg
企业数字化笔记1 天前
视频字幕如何烧录到成片?硬字幕、软字幕、样式控制与播放验收
java·ffmpeg
AIGC小尼2 天前
MiniMax-H3 8G 显存 AI 漫剧进阶实战|ComfyUI 命令行调参、角色锁定与 FFmpeg 批量脚本全解析
人工智能·ffmpeg·comfyui·ai漫剧
物极必反10242 天前
QT使用FFMpeg编译安卓程序.md
qt·ffmpeg·安卓
胡家伟++3 天前
从一段经文到 5 分半水墨动画短片:全 AI 流水线完整实录(即梦 + TTS 克隆 + ffmpeg + 思维链重构)
人工智能·ffmpeg·aigc
allnlei3 天前
Opus In-Band FEC 详解:原理、实现与开源方案
ffmpeg·音视频·gstreamer
VidDown3 天前
从一堆脚本到能维护的系统:视频处理管道的工程化
服务器·ffmpeg·音视频·视频编解码