[3.13] gh-142571: Check for errors before calling each syscall in PyUnstable_CopyPerfMapFile() (GH-142460) (#142602)

Co-authored-by: AZero13 <gfunni234@gmail.com>
Co-authored-by: Victor Stinner <vstinner@python.org>
Co-authored-by: Pablo Galindo Salgado <Pablogsal@gmail.com>
This commit is contained in:
Stan Ulbrych 2025-12-11 22:08:08 +00:00 committed by GitHub
parent 60980eeded
commit 9b24418867
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 20 additions and 8 deletions

View file

@ -0,0 +1 @@
:c:func:`!PyUnstable_CopyPerfMapFile` now checks that opening the file succeeded before flushing.

View file

@ -2609,20 +2609,31 @@ PyAPI_FUNC(int) PyUnstable_CopyPerfMapFile(const char* parent_filename) {
}
char buf[4096];
PyThread_acquire_lock(perf_map_state.map_lock, 1);
int fflush_result = 0, result = 0;
int result = 0;
while (1) {
size_t bytes_read = fread(buf, 1, sizeof(buf), from);
size_t bytes_written = fwrite(buf, 1, bytes_read, perf_map_state.perf_map);
fflush_result = fflush(perf_map_state.perf_map);
if (fflush_result != 0 || bytes_read == 0 || bytes_written < bytes_read) {
result = -1;
goto close_and_release;
if (bytes_read == 0) {
if (ferror(from)) {
result = -1;
}
break;
}
size_t bytes_written = fwrite(buf, 1, bytes_read, perf_map_state.perf_map);
if (bytes_written < bytes_read) {
result = -1;
break;
}
if (fflush(perf_map_state.perf_map) != 0) {
result = -1;
break;
}
if (bytes_read < sizeof(buf) && feof(from)) {
goto close_and_release;
break;
}
}
close_and_release:
fclose(from);
PyThread_release_lock(perf_map_state.map_lock);
return result;