[하루한줄] CVE-2021-3492: Ubuntu Shiftfs driver double free vulnerability
URL
EXPLOITATION OF A DOUBLE FREE VULNERABILITY IN UBUNTU SHIFTFS DRIVER (CVE-2021-3492)
Target
- Ubuntu Groovy (20.10, kernel 5.8.0-50.56 이전 버전)
- Ubuntu Focal (20.04, kernel 5.4.0-72.80 이전 버전)
Explain
Pwn2Own Vancouver 2021에서 Ubuntu Groovy (20.10)과 Ubuntu Focal (20.04)의 Shiftfs 드라이버에서 double free 버그가 발견되었습니다.
shiftfs는 파일 시스템 드라이버로 디렉터리를 bind-mount 하고 마운트한 user namespace owner의 맵을 통해 UID와 GID를 shift 할 수 있는 overlay 종류의 파일 시스템입니다. shiftfs는 특정 ioctl로 핸들링되며 허용된 ioctl을 전달받을 시 shiftfs_real_ioctl
을 호출합니다. BTRFS_IOC_SNAP_CREATE
ioctl이 사용되면 shiftfs_btrfs_ioctl_fd_replace
함수는 userspace에서 kernel space로 구조체를 복사하여 btrfs_ioctl_vol_args
구조체에 포함된 파일 디스크립터를 bottom 파일 시스템의 inode에 연결된 새 디스크립터로 교체하여 legacy btrfs ioctl을 래핑합니다.
이 ioctl이 shiftfs 파일에서 수행되면 핸들링 코드는 btrfs_ioctl_vol_args
를 userpsace에서 kernel space로 복사합니다. 이 구조체에서 fd
를 교체한 후 다시 userspace로 복사됩니다. 복사가 실패할 경우, copy_to_user
함수는 남아있는 바이트를 반환하여 양수 값을 반환합니다. 해당 함수를 호출하는 shiftfs_real_ioctl
은 음수 값인지 확인하여 오류가 났는지 확인하여 오류가 발생하더라도 shiftfs_btrfs_ioctl_fd_restore
를 호출하여 다른 copy_to_user
를 실행하고 btrfs_ioctl_vol_args
구조체를 userpace로 보낸 다음 free 합니다.
shiftfs_btrfs_ioctl_fd_restore
를 두 번 호출하면 같은 fd를 두 번 닫고 같은 구조체가 두 번 free 됩니다. 해당 구조체는 userspace에서 복사되는 동안 shiftfs_btrfs_ioctl_fd_replace
에 할당되며 커널 함수 memdup_user
는 copy_from_user
와 동시에 할당합니다.
shiftfs_btrfs_ioctl_fd_replace
함수에서 memdup_user
가 할당에 성공하고 copy_to_user
는 실패하면 shiftfs_btrfs_ioctl_fd_restore
에서 kfree
를 호출하여 첫 번째 free를 진행하고 shiftfs_real_ioctl
에서 다시 shiftfs_btrfs_ioctl_fd_restore
를 호출하여 Potential leak과 kfree
를 통한 두 번째 free가 가능하여 double free bug가 발생합니다.
본 글은 CC BY-SA 4.0 라이선스로 배포됩니다. 공유 또는 변경 시 반드시 출처를 남겨주시기 바랍니다.