RISC-V: Fix use-after-free error in `parse_multiletter_ext'

Message ID alpine.DEB.2.20.2201181602131.11348@tpp.orcam.me.uk
State Committed
Commit dad495e30135904b0d0305eab8c0ce5f838440d4
Headers
Series RISC-V: Fix use-after-free error in `parse_multiletter_ext' |

Commit Message

Maciej W. Rozycki Jan. 18, 2022, 4:58 p.m. UTC
  Avoid undefined arithmetic involving a pointer to a heap allocation that 
has been freed and move a problematic calculation ahead of the following 
call to `free' in `riscv_subset_list::parse_multiletter_ext', removing a 
compilation error:

.../gcc/common/config/riscv/riscv-common.cc: In member function 'const char* riscv_subset_list::parse_multiletter_ext(const char*, const char*, const char*)':
.../gcc/common/config/riscv/riscv-common.cc:905:27: error: pointer 'subset' used after 'void free(void*)' [-Werror=use-after-free]
  905 |       p += end_of_version - subset;
      |            ~~~~~~~~~~~~~~~^~~~~~~~
.../gcc/common/config/riscv/riscv-common.cc:904:12: note: call to 'void free(void*)' here
  904 |       free (subset);
      |       ~~~~~^~~~~~~~
cc1plus: all warnings being treated as errors
make[2]: *** [Makefile:2428: riscv-common.o] Error 1

and a build regression from commit 671a283636de ("Add -Wuse-after-free 
[PR80532].").

	gcc/
	* common/config/riscv/riscv-common.cc 
	(riscv_subset_list::parse_multiletter_ext): Move pointer 
	arithmetic ahead of `free'.
---
 gcc/common/config/riscv/riscv-common.cc |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

gcc-riscv-parse-multiletter-ext-free.diff
  

Comments

Kito Cheng Jan. 18, 2022, 5:04 p.m. UTC | #1
LGTM, thanks :)

On Wed, Jan 19, 2022 at 12:59 AM Maciej W. Rozycki <macro@embecosm.com> wrote:
>
> Avoid undefined arithmetic involving a pointer to a heap allocation that
> has been freed and move a problematic calculation ahead of the following
> call to `free' in `riscv_subset_list::parse_multiletter_ext', removing a
> compilation error:
>
> .../gcc/common/config/riscv/riscv-common.cc: In member function 'const char* riscv_subset_list::parse_multiletter_ext(const char*, const char*, const char*)':
> .../gcc/common/config/riscv/riscv-common.cc:905:27: error: pointer 'subset' used after 'void free(void*)' [-Werror=use-after-free]
>   905 |       p += end_of_version - subset;
>       |            ~~~~~~~~~~~~~~~^~~~~~~~
> .../gcc/common/config/riscv/riscv-common.cc:904:12: note: call to 'void free(void*)' here
>   904 |       free (subset);
>       |       ~~~~~^~~~~~~~
> cc1plus: all warnings being treated as errors
> make[2]: *** [Makefile:2428: riscv-common.o] Error 1
>
> and a build regression from commit 671a283636de ("Add -Wuse-after-free
> [PR80532].").
>
>         gcc/
>         * common/config/riscv/riscv-common.cc
>         (riscv_subset_list::parse_multiletter_ext): Move pointer
>         arithmetic ahead of `free'.
> ---
>  gcc/common/config/riscv/riscv-common.cc |    2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> gcc-riscv-parse-multiletter-ext-free.diff
> Index: gcc/gcc/common/config/riscv/riscv-common.cc
> ===================================================================
> --- gcc.orig/gcc/common/config/riscv/riscv-common.cc
> +++ gcc/gcc/common/config/riscv/riscv-common.cc
> @@ -901,8 +901,8 @@ riscv_subset_list::parse_multiletter_ext
>         }
>
>        add (subset, major_version, minor_version, explicit_version_p, false);
> -      free (subset);
>        p += end_of_version - subset;
> +      free (subset);
>
>        if (*p != '\0' && *p != '_')
>         {
  
Maciej W. Rozycki Jan. 18, 2022, 7:40 p.m. UTC | #2
On Wed, 19 Jan 2022, Kito Cheng wrote:

> LGTM, thanks :)
> 
> > Avoid undefined arithmetic involving a pointer to a heap allocation that
> > has been freed and move a problematic calculation ahead of the following
> > call to `free' in `riscv_subset_list::parse_multiletter_ext', removing a
> > compilation error:

 Committed, thanks!

  Maciej
  

Patch

Index: gcc/gcc/common/config/riscv/riscv-common.cc
===================================================================
--- gcc.orig/gcc/common/config/riscv/riscv-common.cc
+++ gcc/gcc/common/config/riscv/riscv-common.cc
@@ -901,8 +901,8 @@  riscv_subset_list::parse_multiletter_ext
 	}
 
       add (subset, major_version, minor_version, explicit_version_p, false);
-      free (subset);
       p += end_of_version - subset;
+      free (subset);
 
       if (*p != '\0' && *p != '_')
 	{