`_decimal::CURRENT_CONTEXT`: UAF via borrowed reference across Python callbacks
Chưa có ai nhận issue này.
- Ngôn ngữ chính
- Python
- Star
- 77.2k
- Fork
- 35.9k
- Chỉ số merge pull request
- Chỉ số pull request đang chờ
Mô tả
Crash report
Originally reported by @PidSS as a security advisory
What happened?
The CURRENT_CONTEXT() macro in Modules/_decimal/_decimal.c:1951 obtains a new reference from PyContextVar_Get(), then immediately calls Py_DECREF, leaving a borrowed reference. If Python code executes before the context pointer is next used — via warning handlers, GC finalizers, instancecheck, etc. — and that code calls decimal.setcontext(), the old context is freed while C code still holds a dangling pointer. The macro is used at 20+ call sites covering virtually every decimal operation.
Original reproducer (I will try to make a shorter one):
import decimal, warnings, gc, sys, ctypes
gc.disable()
ctx = decimal.getcontext()
CTX_ID, CTX_SIZE = id(ctx), sys.getsizeof(ctx)
del ctx # refcount = 1, held only by ContextVar HAMT
def evil_warning_handler(message, category, filename, lineno, file=None, line=None):
if 'Format specifier' not in str(message):
return
ctx = decimal.getcontext() # refcount -> 2
decimal.setcontext(decimal.Context(prec=999)) # HAMT ref dropped -> 1
del ctx # refcount -> 0, FREED
spray = [bytearray(b'\xCC' * (CTX_SIZE - 32)) for _ in range(100000)]
warnings.showwarning = evil_warning_handler
warnings.filterwarnings('always', category=DeprecationWarning)
format(decimal.Decimal('123.456'), 'N')
FTR, I saw that we have this macro twice, but it depends on whether we have WITH_DECIMAL_CONTEXTVAR. If I build Python with --without-decimal-contextvar, I also have a crash so it's a bit weird.
Related but not with the same root cause: https://github.com/python/cpython/issues/146011.
CPython versions tested on:
CPython main branch
Operating systems tested on:
No response
Output from running 'python -VV' on the command line:
No response
Hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Hướng nghiên cứu
Bắt đầu trong Modules/_decimal/_decimal.c, tại macro CURRENT_CONTEXT quanh dòng 1951, sau đó kiểm tra hơn 20 vị trí gọi nó và macro thứ hai được sử dụng mà không có WITH_DECIMAL_CONTEXTVAR. Chạy warning-handler reproducer được cung cấp trên một bản build main của CPython. Hoàn tất khi đường dẫn callback được tái hiện không còn sử dụng context đã được giải phóng trong cả hai cấu hình.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Đánh giá
- Công nghệ
- c, python
- Lĩnh vực
- security
- Loại issue
- Lỗi
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức độ hoạt động
- Ít trao đổi
- Độ rõ ràng
- Khá rõ ràng
- Mức phù hợp với người mới
- 45/100