CVE-2026-33018libsixel是一个SIXEL编码器/解码器实现,其1.8.7及更早版本中存在一个释放后重用(UAF)漏洞。该漏洞源于fromgif.c文件中的load_gif()函数在处理多帧GIF时,错误地重用了sixel_frame_t对象。gif_init_frame()函数在处理新帧时会无条件释放并重新分配frame->pixels内存,而未检查对象的引用计数。当应用程序使用sixel_helper_load_image_file()处理用户提供的动画GIF并使用多帧回调时,回调函数持有的像素指针会在第二帧解码后变为悬空指针。这导致了堆释放后重用,经ASAN确认可导致崩溃,并存在潜在的代码执行风险。
该漏洞的技术细节在于libsixel库在处理GIF动画帧时的内存管理机制存在缺陷。在load_gif()函数中,为了优化资源,同一个sixel_frame_t结构体实例被用于解码GIF的所有帧。每当处理新的一帧时,gif_init_frame()函数会被调用,它会无条件释放当前帧关联的像素缓冲区(frame->pixels)并重新分配内存。尽管库的公共API提供了sixel_frame_ref()函数来增加帧对象的引用计数,以允许用户保留对帧数据的访问,但内部实现完全忽略了这一引用计数机制,直接进行了释放操作。因此,当开发者在回调函数中按照文档建议使用sixel_frame_ref()保留第一帧,并尝试在后续处理中通过sixel_frame_get_pixels()访问像素数据时,实际上访问的是一块已被释放的堆内存。攻击者可以通过精心构造的GIF文件控制内存布局,利用这一悬空指针进行非法内存读写,从而引发拒绝服务或进一步实现任意代码执行。