From f82055f8247478d9e2c00f2a442248e42188b8d1 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 4 Oct 2024 14:02:13 +0200 Subject: diagnostic, pch: Fix up the new diagnostic PCH methods for ubsan checking [PR116936] The PR notes that the new pch_save/pch_restore methods I've added recently invoke UB if either m_classification_history.address () or m_push_list.address () is NULL (which can happen if those vectors are empty (and in the pch_save case nothing has been pushed into them before either). While the corresponding length is necessarily 0, fwrite (NULL, something, 0, f) or fread (NULL, something, 0, f) still invoke UB. The following patch fixes that by not calling fwrite/fread if the corresponding length is 0. 2024-10-04 Jakub Jelinek PR pch/116936 * diagnostic.cc (diagnostic_option_classifier::pch_save): Only call fwrite if corresponding length is non-zero. (diagnostic_option_classifier::pch_restore): Only call fread if corresponding length is non-zero. --- gcc/diagnostic.cc | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) (limited to 'gcc') diff --git a/gcc/diagnostic.cc b/gcc/diagnostic.cc index 73ed2ea..27ac2bd 100644 --- a/gcc/diagnostic.cc +++ b/gcc/diagnostic.cc @@ -167,11 +167,13 @@ diagnostic_option_classifier::pch_save (FILE *f) unsigned int lengths[2] = { m_classification_history.length (), m_push_list.length () }; if (fwrite (lengths, sizeof (lengths), 1, f) != 1 - || fwrite (m_classification_history.address (), - sizeof (diagnostic_classification_change_t), - lengths[0], f) != lengths[0] - || fwrite (m_push_list.address (), sizeof (int), - lengths[1], f) != lengths[1]) + || (lengths[0] + && fwrite (m_classification_history.address (), + sizeof (diagnostic_classification_change_t), + lengths[0], f) != lengths[0]) + || (lengths[1] + && fwrite (m_push_list.address (), sizeof (int), + lengths[1], f) != lengths[1])) return -1; return 0; } @@ -189,11 +191,13 @@ diagnostic_option_classifier::pch_restore (FILE *f) gcc_checking_assert (m_push_list.is_empty ()); m_classification_history.safe_grow (lengths[0]); m_push_list.safe_grow (lengths[1]); - if (fread (m_classification_history.address (), - sizeof (diagnostic_classification_change_t), - lengths[0], f) != lengths[0] - || fread (m_push_list.address (), sizeof (int), - lengths[1], f) != lengths[1]) + if ((lengths[0] + && fread (m_classification_history.address (), + sizeof (diagnostic_classification_change_t), + lengths[0], f) != lengths[0]) + || (lengths[1] + && fread (m_push_list.address (), sizeof (int), + lengths[1], f) != lengths[1])) return -1; return 0; } -- cgit v1.1