Re: [PATCH v1 1/2] xc_core_arch_map_p2m_tree_rw: fix memory leak

2023-02-27 Thread Andrew Cooper
On 27/02/2023 2:42 pm, Juergen Gross wrote:
> On 24.02.23 15:56, Andrew Cooper wrote:
>> On 24/02/2023 1:36 pm, Edwin Török wrote:
>>> From: Edwin Török 
>>>
>>> Prior to bd7a29c3d0 'out' would've always been executed and memory
>>> freed, but that commit changed it such that it returns early and leaks.
>>>
>>> Found using gcc 12.2.1 `-fanalyzer`:
>>> ```
>>> xg_core_x86.c: In function ‘xc_core_arch_map_p2m_tree_rw’:
>>> xg_core_x86.c:300:5: error: leak of ‘p2m_frame_list_list’ [CWE-401]
>>> [-Werror=analyzer-malloc-leak]
>>>    300 | return p2m_frame_list;
>>>    | ^~
>>>    ‘xc_core_arch_map_p2m_writable’: events 1-2
>>>  |
>>>  |  378 | xc_core_arch_map_p2m_writable(xc_interface *xch,
>>> struct domain_info_context *dinfo, xc_dominfo_t *info,
>>>  |  | ^
>>>  |  | |
>>>  |  | (1) entry to ‘xc_core_arch_map_p2m_writable’
>>>  |..
>>>  |  381 | return xc_core_arch_map_p2m_rw(xch, dinfo, info,
>>> live_shinfo, live_p2m, 1);
>>>  |  |   
>>> ~~~
>>>  |  |    |
>>>  |  |    (2) calling ‘xc_core_arch_map_p2m_rw’ from
>>> ‘xc_core_arch_map_p2m_writable’
>>>  |
>>>  +--> ‘xc_core_arch_map_p2m_rw’: events 3-10
>>>     |
>>>     |  319 | xc_core_arch_map_p2m_rw(xc_interface *xch,
>>> struct domain_info_context *dinfo, xc_dominfo_t *info,
>>>     |  | ^~~
>>>     |  | |
>>>     |  | (3) entry to ‘xc_core_arch_map_p2m_rw’
>>>     |..
>>>     |  328 | if ( xc_domain_nr_gpfns(xch, info->domid,
>>> >p2m_size) < 0 )
>>>     |  |    ~
>>>     |  |    |
>>>     |  |    (4) following ‘false’ branch...
>>>     |..
>>>     |  334 | if ( dinfo->p2m_size < info->nr_pages  )
>>>     |  | ~~ ~
>>>     |  | |  |
>>>     |  | |  (6) following ‘false’ branch...
>>>     |  | (5) ...to here
>>>     |..
>>>     |  340 | p2m_cr3 = GET_FIELD(live_shinfo,
>>> arch.p2m_cr3, dinfo->guest_width);
>>>     |  | ~~~
>>>     |  | |
>>>     |  | (7) ...to here
>>>     |  341 |
>>>     |  342 | p2m_frame_list = p2m_cr3 ?
>>> xc_core_arch_map_p2m_list_rw(xch, dinfo, dom, live_shinfo, p2m_cr3)
>>>     |  | 
>>> ~
>>>     |  343 |  :
>>> xc_core_arch_map_p2m_tree_rw(xch, dinfo, dom, live_shinfo);
>>>     |  | 
>>> 
>>>     |  |  | |
>>>     |  |  | (9) ...to here
>>>     |  |  | (10) calling
>>> ‘xc_core_arch_map_p2m_tree_rw’ from ‘xc_core_arch_map_p2m_rw’
>>>     |  |  (8) following
>>> ‘false’ branch...
>>>     |
>>>     +--> ‘xc_core_arch_map_p2m_tree_rw’: events 11-24
>>>    |
>>>    |  228 |
>>> xc_core_arch_map_p2m_tree_rw(xc_interface *xch, struct
>>> domain_info_context *dinfo,
>>>    |  | ^~~~
>>>    |  | |
>>>    |  | (11) entry to
>>> ‘xc_core_arch_map_p2m_tree_rw’
>>>    |..
>>>    |  245 | if ( !live_p2m_frame_list_list )
>>>    |  |    ~
>>>    |  |    |
>>>    |  |    (12) following ‘false’ branch
>>> (when ‘live_p2m_frame_list_list’ is non-NULL)...
>>>    |..
>>>    |  252 | if ( !(p2m_frame_list_list =
>>> malloc(PAGE_SIZE)) )
>>>    |  | ~~ ~
>>> ~
>>>    |  | |  | |
>>>    |  | |  | (14)
>>> allocated here
>>>    |  | |  (15) assuming
>>> ‘p2m_frame_list_list’ is non-NULL
>>>    |  | |  (16) following ‘false’ branch
>>> (when ‘p2m_frame_list_list’ is non-NULL)...
>>>    |  | (13) ...to here
>>>    |..
>>>    |  257 | memcpy(p2m_frame_list_list,
>>> live_p2m_frame_list_list, PAGE_SIZE);
>>>    |  | ~~
>>>    |  | |
>>>    |  | (17) ...to here
>>>    |..
>>>    |  266 | else if ( dinfo->guest_width <
>>> sizeof(unsigned long) )
>>>    

Re: [PATCH v1 1/2] xc_core_arch_map_p2m_tree_rw: fix memory leak

2023-02-27 Thread Juergen Gross

On 24.02.23 15:56, Andrew Cooper wrote:

On 24/02/2023 1:36 pm, Edwin Török wrote:

From: Edwin Török 

Prior to bd7a29c3d0 'out' would've always been executed and memory
freed, but that commit changed it such that it returns early and leaks.

Found using gcc 12.2.1 `-fanalyzer`:
```
xg_core_x86.c: In function ‘xc_core_arch_map_p2m_tree_rw’:
xg_core_x86.c:300:5: error: leak of ‘p2m_frame_list_list’ [CWE-401] 
[-Werror=analyzer-malloc-leak]
   300 | return p2m_frame_list;
   | ^~
   ‘xc_core_arch_map_p2m_writable’: events 1-2
 |
 |  378 | xc_core_arch_map_p2m_writable(xc_interface *xch, struct 
domain_info_context *dinfo, xc_dominfo_t *info,
 |  | ^
 |  | |
 |  | (1) entry to ‘xc_core_arch_map_p2m_writable’
 |..
 |  381 | return xc_core_arch_map_p2m_rw(xch, dinfo, info, live_shinfo, 
live_p2m, 1);
 |  |
~~~
 |  ||
 |  |(2) calling ‘xc_core_arch_map_p2m_rw’ from 
‘xc_core_arch_map_p2m_writable’
 |
 +--> ‘xc_core_arch_map_p2m_rw’: events 3-10
|
|  319 | xc_core_arch_map_p2m_rw(xc_interface *xch, struct 
domain_info_context *dinfo, xc_dominfo_t *info,
|  | ^~~
|  | |
|  | (3) entry to ‘xc_core_arch_map_p2m_rw’
|..
|  328 | if ( xc_domain_nr_gpfns(xch, info->domid, 
>p2m_size) < 0 )
|  |~
|  ||
|  |(4) following ‘false’ branch...
|..
|  334 | if ( dinfo->p2m_size < info->nr_pages  )
|  | ~~ ~
|  | |  |
|  | |  (6) following ‘false’ branch...
|  | (5) ...to here
|..
|  340 | p2m_cr3 = GET_FIELD(live_shinfo, arch.p2m_cr3, 
dinfo->guest_width);
|  | ~~~
|  | |
|  | (7) ...to here
|  341 |
|  342 | p2m_frame_list = p2m_cr3 ? 
xc_core_arch_map_p2m_list_rw(xch, dinfo, dom, live_shinfo, p2m_cr3)
|  |  
~
|  343 |  : 
xc_core_arch_map_p2m_tree_rw(xch, dinfo, dom, live_shinfo);
|  |  

|  |  | |
|  |  | (9) ...to here
|  |  | (10) calling 
‘xc_core_arch_map_p2m_tree_rw’ from ‘xc_core_arch_map_p2m_rw’
|  |  (8) following ‘false’ 
branch...
|
+--> ‘xc_core_arch_map_p2m_tree_rw’: events 11-24
   |
   |  228 | xc_core_arch_map_p2m_tree_rw(xc_interface *xch, 
struct domain_info_context *dinfo,
   |  | ^~~~
   |  | |
   |  | (11) entry to ‘xc_core_arch_map_p2m_tree_rw’
   |..
   |  245 | if ( !live_p2m_frame_list_list )
   |  |~
   |  ||
   |  |(12) following ‘false’ branch (when 
‘live_p2m_frame_list_list’ is non-NULL)...
   |..
   |  252 | if ( !(p2m_frame_list_list = malloc(PAGE_SIZE)) 
)
   |  | ~~ ~ ~
   |  | |  | |
   |  | |  | (14) allocated here
   |  | |  (15) assuming ‘p2m_frame_list_list’ is 
non-NULL
   |  | |  (16) following ‘false’ branch (when 
‘p2m_frame_list_list’ is non-NULL)...
   |  | (13) ...to here
   |..
   |  257 | memcpy(p2m_frame_list_list, 
live_p2m_frame_list_list, PAGE_SIZE);
   |  | ~~
   |  | |
   |  | (17) ...to here
   |..
   |  266 | else if ( dinfo->guest_width < sizeof(unsigned 
long) )
   |  | ~
   |  | |
   |  | (18) following ‘false’ branch...
   |..
   |  270 | live_p2m_frame_list =
   |  | ~~~
   |  | |
   |  | (19) ...to here
   |..
   |  275 | if ( !live_p2m_frame_list )
   

Re: [PATCH v1 1/2] xc_core_arch_map_p2m_tree_rw: fix memory leak

2023-02-27 Thread Edwin Torok



> On 24 Feb 2023, at 14:56, Andrew Cooper  wrote:
> 
> On 24/02/2023 1:36 pm, Edwin Török wrote:
>> From: Edwin Török 
>> 
>> Prior to bd7a29c3d0 'out' would've always been executed and memory
>> freed, but that commit changed it such that it returns early and leaks.
>> 
>> Found using gcc 12.2.1 `-fanalyzer`:
>> ```
>> xg_core_x86.c: In function ‘xc_core_arch_map_p2m_tree_rw’:
>> xg_core_x86.c:300:5: error: leak of ‘p2m_frame_list_list’ [CWE-401] 
>> [-Werror=analyzer-malloc-leak]
>>  300 | return p2m_frame_list;
>>  | ^~
>>  ‘xc_core_arch_map_p2m_writable’: events 1-2
>>|
>>|  378 | xc_core_arch_map_p2m_writable(xc_interface *xch, struct 
>> domain_info_context *dinfo, xc_dominfo_t *info,
>>|  | ^
>>|  | |
>>|  | (1) entry to ‘xc_core_arch_map_p2m_writable’
>>|..
>>|  381 | return xc_core_arch_map_p2m_rw(xch, dinfo, info, 
>> live_shinfo, live_p2m, 1);
>>|  |
>> ~~~
>>|  ||
>>|  |(2) calling ‘xc_core_arch_map_p2m_rw’ from 
>> ‘xc_core_arch_map_p2m_writable’
>>|
>>+--> ‘xc_core_arch_map_p2m_rw’: events 3-10
>>   |
>>   |  319 | xc_core_arch_map_p2m_rw(xc_interface *xch, struct 
>> domain_info_context *dinfo, xc_dominfo_t *info,
>>   |  | ^~~
>>   |  | |
>>   |  | (3) entry to ‘xc_core_arch_map_p2m_rw’
>>   |..
>>   |  328 | if ( xc_domain_nr_gpfns(xch, info->domid, 
>> >p2m_size) < 0 )
>>   |  |~
>>   |  ||
>>   |  |(4) following ‘false’ branch...
>>   |..
>>   |  334 | if ( dinfo->p2m_size < info->nr_pages  )
>>   |  | ~~ ~
>>   |  | |  |
>>   |  | |  (6) following ‘false’ branch...
>>   |  | (5) ...to here
>>   |..
>>   |  340 | p2m_cr3 = GET_FIELD(live_shinfo, arch.p2m_cr3, 
>> dinfo->guest_width);
>>   |  | ~~~
>>   |  | |
>>   |  | (7) ...to here
>>   |  341 |
>>   |  342 | p2m_frame_list = p2m_cr3 ? 
>> xc_core_arch_map_p2m_list_rw(xch, dinfo, dom, live_shinfo, p2m_cr3)
>>   |  |  
>> ~
>>   |  343 |  : 
>> xc_core_arch_map_p2m_tree_rw(xch, dinfo, dom, live_shinfo);
>>   |  |  
>> 
>>   |  |  | |
>>   |  |  | (9) ...to here
>>   |  |  | (10) calling 
>> ‘xc_core_arch_map_p2m_tree_rw’ from ‘xc_core_arch_map_p2m_rw’
>>   |  |  (8) following ‘false’ 
>> branch...
>>   |
>>   +--> ‘xc_core_arch_map_p2m_tree_rw’: events 11-24
>>  |
>>  |  228 | xc_core_arch_map_p2m_tree_rw(xc_interface *xch, 
>> struct domain_info_context *dinfo,
>>  |  | ^~~~
>>  |  | |
>>  |  | (11) entry to ‘xc_core_arch_map_p2m_tree_rw’
>>  |..
>>  |  245 | if ( !live_p2m_frame_list_list )
>>  |  |~
>>  |  ||
>>  |  |(12) following ‘false’ branch (when 
>> ‘live_p2m_frame_list_list’ is non-NULL)...
>>  |..
>>  |  252 | if ( !(p2m_frame_list_list = 
>> malloc(PAGE_SIZE)) )
>>  |  | ~~ ~ ~
>>  |  | |  | |
>>  |  | |  | (14) allocated 
>> here
>>  |  | |  (15) assuming ‘p2m_frame_list_list’ is 
>> non-NULL
>>  |  | |  (16) following ‘false’ branch (when 
>> ‘p2m_frame_list_list’ is non-NULL)...
>>  |  | (13) ...to here
>>  |..
>>  |  257 | memcpy(p2m_frame_list_list, 
>> live_p2m_frame_list_list, PAGE_SIZE);
>>  |  | ~~
>>  |  | |
>>  |  | (17) ...to here
>>  |..
>>  |  266 | else if ( dinfo->guest_width < sizeof(unsigned 
>> long) )
>>  |  | ~
>>  |  | |
>>  |  | (18) following ‘false’ branch...
>>  |..
>>  |  270 | live_p2m_frame_list =
>>  |  | 

Re: [PATCH v1 1/2] xc_core_arch_map_p2m_tree_rw: fix memory leak

2023-02-24 Thread Andrew Cooper
On 24/02/2023 1:36 pm, Edwin Török wrote:
> From: Edwin Török 
>
> Prior to bd7a29c3d0 'out' would've always been executed and memory
> freed, but that commit changed it such that it returns early and leaks.
>
> Found using gcc 12.2.1 `-fanalyzer`:
> ```
> xg_core_x86.c: In function ‘xc_core_arch_map_p2m_tree_rw’:
> xg_core_x86.c:300:5: error: leak of ‘p2m_frame_list_list’ [CWE-401] 
> [-Werror=analyzer-malloc-leak]
>   300 | return p2m_frame_list;
>   | ^~
>   ‘xc_core_arch_map_p2m_writable’: events 1-2
> |
> |  378 | xc_core_arch_map_p2m_writable(xc_interface *xch, struct 
> domain_info_context *dinfo, xc_dominfo_t *info,
> |  | ^
> |  | |
> |  | (1) entry to ‘xc_core_arch_map_p2m_writable’
> |..
> |  381 | return xc_core_arch_map_p2m_rw(xch, dinfo, info, 
> live_shinfo, live_p2m, 1);
> |  |
> ~~~
> |  ||
> |  |(2) calling ‘xc_core_arch_map_p2m_rw’ from 
> ‘xc_core_arch_map_p2m_writable’
> |
> +--> ‘xc_core_arch_map_p2m_rw’: events 3-10
>|
>|  319 | xc_core_arch_map_p2m_rw(xc_interface *xch, struct 
> domain_info_context *dinfo, xc_dominfo_t *info,
>|  | ^~~
>|  | |
>|  | (3) entry to ‘xc_core_arch_map_p2m_rw’
>|..
>|  328 | if ( xc_domain_nr_gpfns(xch, info->domid, 
> >p2m_size) < 0 )
>|  |~
>|  ||
>|  |(4) following ‘false’ branch...
>|..
>|  334 | if ( dinfo->p2m_size < info->nr_pages  )
>|  | ~~ ~
>|  | |  |
>|  | |  (6) following ‘false’ branch...
>|  | (5) ...to here
>|..
>|  340 | p2m_cr3 = GET_FIELD(live_shinfo, arch.p2m_cr3, 
> dinfo->guest_width);
>|  | ~~~
>|  | |
>|  | (7) ...to here
>|  341 |
>|  342 | p2m_frame_list = p2m_cr3 ? 
> xc_core_arch_map_p2m_list_rw(xch, dinfo, dom, live_shinfo, p2m_cr3)
>|  |  
> ~
>|  343 |  : 
> xc_core_arch_map_p2m_tree_rw(xch, dinfo, dom, live_shinfo);
>|  |  
> 
>|  |  | |
>|  |  | (9) ...to here
>|  |  | (10) calling 
> ‘xc_core_arch_map_p2m_tree_rw’ from ‘xc_core_arch_map_p2m_rw’
>|  |  (8) following ‘false’ 
> branch...
>|
>+--> ‘xc_core_arch_map_p2m_tree_rw’: events 11-24
>   |
>   |  228 | xc_core_arch_map_p2m_tree_rw(xc_interface *xch, 
> struct domain_info_context *dinfo,
>   |  | ^~~~
>   |  | |
>   |  | (11) entry to ‘xc_core_arch_map_p2m_tree_rw’
>   |..
>   |  245 | if ( !live_p2m_frame_list_list )
>   |  |~
>   |  ||
>   |  |(12) following ‘false’ branch (when 
> ‘live_p2m_frame_list_list’ is non-NULL)...
>   |..
>   |  252 | if ( !(p2m_frame_list_list = 
> malloc(PAGE_SIZE)) )
>   |  | ~~ ~ ~
>   |  | |  | |
>   |  | |  | (14) allocated 
> here
>   |  | |  (15) assuming ‘p2m_frame_list_list’ is 
> non-NULL
>   |  | |  (16) following ‘false’ branch (when 
> ‘p2m_frame_list_list’ is non-NULL)...
>   |  | (13) ...to here
>   |..
>   |  257 | memcpy(p2m_frame_list_list, 
> live_p2m_frame_list_list, PAGE_SIZE);
>   |  | ~~
>   |  | |
>   |  | (17) ...to here
>   |..
>   |  266 | else if ( dinfo->guest_width < sizeof(unsigned 
> long) )
>   |  | ~
>   |  | |
>   |  | (18) following ‘false’ branch...
>   |..
>   |  270 | live_p2m_frame_list =
>   |  | ~~~
>   |  | |
>   |  | (19) ...to 

[PATCH v1 1/2] xc_core_arch_map_p2m_tree_rw: fix memory leak

2023-02-24 Thread Edwin Török
From: Edwin Török 

Prior to bd7a29c3d0 'out' would've always been executed and memory
freed, but that commit changed it such that it returns early and leaks.

Found using gcc 12.2.1 `-fanalyzer`:
```
xg_core_x86.c: In function ‘xc_core_arch_map_p2m_tree_rw’:
xg_core_x86.c:300:5: error: leak of ‘p2m_frame_list_list’ [CWE-401] 
[-Werror=analyzer-malloc-leak]
  300 | return p2m_frame_list;
  | ^~
  ‘xc_core_arch_map_p2m_writable’: events 1-2
|
|  378 | xc_core_arch_map_p2m_writable(xc_interface *xch, struct 
domain_info_context *dinfo, xc_dominfo_t *info,
|  | ^
|  | |
|  | (1) entry to ‘xc_core_arch_map_p2m_writable’
|..
|  381 | return xc_core_arch_map_p2m_rw(xch, dinfo, info, live_shinfo, 
live_p2m, 1);
|  |
~~~
|  ||
|  |(2) calling ‘xc_core_arch_map_p2m_rw’ from 
‘xc_core_arch_map_p2m_writable’
|
+--> ‘xc_core_arch_map_p2m_rw’: events 3-10
   |
   |  319 | xc_core_arch_map_p2m_rw(xc_interface *xch, struct 
domain_info_context *dinfo, xc_dominfo_t *info,
   |  | ^~~
   |  | |
   |  | (3) entry to ‘xc_core_arch_map_p2m_rw’
   |..
   |  328 | if ( xc_domain_nr_gpfns(xch, info->domid, 
>p2m_size) < 0 )
   |  |~
   |  ||
   |  |(4) following ‘false’ branch...
   |..
   |  334 | if ( dinfo->p2m_size < info->nr_pages  )
   |  | ~~ ~
   |  | |  |
   |  | |  (6) following ‘false’ branch...
   |  | (5) ...to here
   |..
   |  340 | p2m_cr3 = GET_FIELD(live_shinfo, arch.p2m_cr3, 
dinfo->guest_width);
   |  | ~~~
   |  | |
   |  | (7) ...to here
   |  341 |
   |  342 | p2m_frame_list = p2m_cr3 ? 
xc_core_arch_map_p2m_list_rw(xch, dinfo, dom, live_shinfo, p2m_cr3)
   |  |  
~
   |  343 |  : 
xc_core_arch_map_p2m_tree_rw(xch, dinfo, dom, live_shinfo);
   |  |  

   |  |  | |
   |  |  | (9) ...to here
   |  |  | (10) calling 
‘xc_core_arch_map_p2m_tree_rw’ from ‘xc_core_arch_map_p2m_rw’
   |  |  (8) following ‘false’ branch...
   |
   +--> ‘xc_core_arch_map_p2m_tree_rw’: events 11-24
  |
  |  228 | xc_core_arch_map_p2m_tree_rw(xc_interface *xch, 
struct domain_info_context *dinfo,
  |  | ^~~~
  |  | |
  |  | (11) entry to ‘xc_core_arch_map_p2m_tree_rw’
  |..
  |  245 | if ( !live_p2m_frame_list_list )
  |  |~
  |  ||
  |  |(12) following ‘false’ branch (when 
‘live_p2m_frame_list_list’ is non-NULL)...
  |..
  |  252 | if ( !(p2m_frame_list_list = malloc(PAGE_SIZE)) )
  |  | ~~ ~ ~
  |  | |  | |
  |  | |  | (14) allocated here
  |  | |  (15) assuming ‘p2m_frame_list_list’ is 
non-NULL
  |  | |  (16) following ‘false’ branch (when 
‘p2m_frame_list_list’ is non-NULL)...
  |  | (13) ...to here
  |..
  |  257 | memcpy(p2m_frame_list_list, 
live_p2m_frame_list_list, PAGE_SIZE);
  |  | ~~
  |  | |
  |  | (17) ...to here
  |..
  |  266 | else if ( dinfo->guest_width < sizeof(unsigned 
long) )
  |  | ~
  |  | |
  |  | (18) following ‘false’ branch...
  |..
  |  270 | live_p2m_frame_list =
  |  | ~~~
  |  | |
  |  | (19) ...to here
  |..
  |  275 | if ( !live_p2m_frame_list )
  |  |~
  |  ||
  |  |(20) following ‘false’ branch (when 
‘live_p2m_frame_list’ is