Skip to content

Commit c67c523

Browse files
committed
Fix several issues uncovered by CVE-2025-7067
1 parent 26a76ba commit c67c523

File tree

9 files changed

+187
-85
lines changed

9 files changed

+187
-85
lines changed

src/H5FScache.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1024,7 +1024,7 @@ H5FS__cache_sinfo_deserialize(const void *_image, size_t H5_ATTR_NDEBUG_UNUSED l
10241024

10251025
/* Insert section in free space manager, unless requested not to */
10261026
if (!(des_flags & H5FS_DESERIALIZE_NO_ADD))
1027-
if (H5FS_sect_add(udata->f, fspace, new_sect, H5FS_ADD_DESERIALIZING, udata) < 0)
1027+
if (H5FS_sect_add(udata->f, fspace, new_sect, H5FS_ADD_DESERIALIZING, udata, NULL) < 0)
10281028
HGOTO_ERROR(H5E_FSPACE, H5E_CANTINSERT, NULL,
10291029
"can't add section to free space manager");
10301030
} /* end for */

src/H5FSprivate.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ H5_DLL herr_t H5FS_free(H5F_t *f, H5FS_t *fspace, bool free_file_space);
201201

202202
/* Free space section routines */
203203
H5_DLL herr_t H5FS_sect_add(H5F_t *f, H5FS_t *fspace, H5FS_section_info_t *node, unsigned flags,
204-
void *op_data);
204+
void *op_data, bool *merged_or_shrunk);
205205
H5_DLL htri_t H5FS_sect_try_merge(H5F_t *f, H5FS_t *fspace, H5FS_section_info_t *sect, unsigned flags,
206206
void *op_data);
207207
H5_DLL htri_t H5FS_sect_try_extend(H5F_t *f, H5FS_t *fspace, haddr_t addr, hsize_t size,

src/H5FSsection.c

Lines changed: 74 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1297,7 +1297,8 @@ H5FS__sect_merge(H5FS_t *fspace, H5FS_section_info_t **sect, void *op_data)
12971297
*-------------------------------------------------------------------------
12981298
*/
12991299
herr_t
1300-
H5FS_sect_add(H5F_t *f, H5FS_t *fspace, H5FS_section_info_t *sect, unsigned flags, void *op_data)
1300+
H5FS_sect_add(H5F_t *f, H5FS_t *fspace, H5FS_section_info_t *sect, unsigned flags, void *op_data,
1301+
bool *merged_or_shrunk)
13011302
{
13021303
H5FS_section_class_t *cls; /* Section's class */
13031304
bool sinfo_valid = false; /* Whether the section info is valid */
@@ -1318,6 +1319,9 @@ H5FS_sect_add(H5F_t *f, H5FS_t *fspace, H5FS_section_info_t *sect, unsigned flag
13181319
assert(H5_addr_defined(sect->addr));
13191320
assert(sect->size);
13201321

1322+
if (merged_or_shrunk)
1323+
*merged_or_shrunk = false;
1324+
13211325
/* Get a pointer to the section info */
13221326
if (H5FS__sinfo_lock(f, fspace, H5AC__NO_FLAGS_SET) < 0)
13231327
HGOTO_ERROR(H5E_FSPACE, H5E_CANTGET, FAIL, "can't get section info");
@@ -1344,9 +1348,12 @@ H5FS_sect_add(H5F_t *f, H5FS_t *fspace, H5FS_section_info_t *sect, unsigned flag
13441348
/* (If section has been completely merged or shrunk away, 'sect' will
13451349
* be NULL at this point - QAK)
13461350
*/
1347-
if (sect)
1351+
if (sect) {
13481352
if (H5FS__sect_link(fspace, sect, flags) < 0)
13491353
HGOTO_ERROR(H5E_FSPACE, H5E_CANTINSERT, FAIL, "can't insert free space section into skip list");
1354+
}
1355+
else if (merged_or_shrunk)
1356+
*merged_or_shrunk = true;
13501357

13511358
#ifdef H5FS_SINFO_DEBUG
13521359
fprintf(stderr, "%s: fspace->tot_space = %" PRIuHSIZE "\n", __func__, fspace->tot_space);
@@ -2314,11 +2321,15 @@ H5FS_sect_try_shrink_eoa(H5F_t *f, H5FS_t *fspace, void *op_data)
23142321
herr_t
23152322
H5FS_vfd_alloc_hdr_and_section_info_if_needed(H5F_t *f, H5FS_t *fspace, haddr_t *fs_addr_ptr)
23162323
{
2317-
hsize_t hdr_alloc_size;
2318-
hsize_t sinfo_alloc_size;
2319-
haddr_t sect_addr = HADDR_UNDEF; /* address of sinfo */
2320-
haddr_t eoa = HADDR_UNDEF; /* Initial EOA for the file */
2321-
herr_t ret_value = SUCCEED; /* Return value */
2324+
hsize_t hdr_alloc_size = 0;
2325+
hsize_t sinfo_alloc_size = 0;
2326+
haddr_t sect_addr = HADDR_UNDEF; /* address of sinfo */
2327+
haddr_t eoa = HADDR_UNDEF; /* Initial EOA for the file */
2328+
bool allocated_header = false; /* Whether a free space header was allocated */
2329+
bool inserted_header = false; /* Whether a free space header was inserted into the metadata cache */
2330+
bool allocated_section = false; /* Whether a free space section was allocated */
2331+
bool inserted_section = false; /* Whether a free space section was inserted into the metadata cache */
2332+
herr_t ret_value = SUCCEED; /* Return value */
23222333

23232334
FUNC_ENTER_NOAPI_NOINIT
23242335

@@ -2367,10 +2378,12 @@ H5FS_vfd_alloc_hdr_and_section_info_if_needed(H5F_t *f, H5FS_t *fspace, haddr_t
23672378
/* Allocate space for the free space header */
23682379
if (HADDR_UNDEF == (fspace->addr = H5MF_alloc(f, H5FD_MEM_FSPACE_HDR, hdr_alloc_size)))
23692380
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for free space header");
2381+
allocated_header = true;
23702382

23712383
/* Cache the new free space header (pinned) */
23722384
if (H5AC_insert_entry(f, H5AC_FSPACE_HDR, fspace->addr, fspace, H5AC__PIN_ENTRY_FLAG) < 0)
23732385
HGOTO_ERROR(H5E_FSPACE, H5E_CANTINIT, FAIL, "can't add free space header to cache");
2386+
inserted_header = true;
23742387

23752388
*fs_addr_ptr = fspace->addr;
23762389
}
@@ -2396,6 +2409,7 @@ H5FS_vfd_alloc_hdr_and_section_info_if_needed(H5F_t *f, H5FS_t *fspace, haddr_t
23962409
/* allocate space for the section info */
23972410
if (HADDR_UNDEF == (sect_addr = H5MF_alloc(f, H5FD_MEM_FSPACE_SINFO, sinfo_alloc_size)))
23982411
HGOTO_ERROR(H5E_FSPACE, H5E_NOSPACE, FAIL, "file allocation failed for section info");
2412+
allocated_section = true;
23992413

24002414
/* update fspace->alloc_sect_size and fspace->sect_addr to reflect
24012415
* the allocation
@@ -2437,6 +2451,7 @@ H5FS_vfd_alloc_hdr_and_section_info_if_needed(H5F_t *f, H5FS_t *fspace, haddr_t
24372451
*/
24382452
if (H5AC_insert_entry(f, H5AC_FSPACE_SINFO, sect_addr, fspace->sinfo, H5AC__NO_FLAGS_SET) < 0)
24392453
HGOTO_ERROR(H5E_FSPACE, H5E_CANTINIT, FAIL, "can't add free space sinfo to cache");
2454+
inserted_section = true;
24402455

24412456
/* We have changed the sinfo address -- Mark free space header dirty */
24422457
if (H5AC_mark_entry_dirty(fspace) < 0)
@@ -2453,5 +2468,57 @@ H5FS_vfd_alloc_hdr_and_section_info_if_needed(H5F_t *f, H5FS_t *fspace, haddr_t
24532468
} /* end if */
24542469

24552470
done:
2471+
if (ret_value < 0) {
2472+
/* Remove the free space section that was inserted into the metadata cache,
2473+
* making sure to free the file space that was allocated for it as well.
2474+
* Avoid expunging the entry, as the information needs to be kept around
2475+
* until we finish trying to settle the metadata free space manager(s).
2476+
*/
2477+
if (inserted_section || allocated_section) {
2478+
if (allocated_section && (sect_addr == fspace->sect_addr)) {
2479+
assert(H5_addr_defined(fspace->sect_addr));
2480+
2481+
if (H5MF_xfree(f, H5FD_MEM_FSPACE_SINFO, sect_addr, sinfo_alloc_size) < 0)
2482+
HDONE_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to free free space sections");
2483+
fspace->sect_addr = HADDR_UNDEF;
2484+
}
2485+
2486+
if (inserted_section) {
2487+
if (H5AC_remove_entry(fspace->sinfo) < 0)
2488+
HDONE_ERROR(H5E_FSPACE, H5E_CANTEXPUNGE, FAIL,
2489+
"can't remove file free space section from cache");
2490+
}
2491+
}
2492+
2493+
/* Remove the free space header that was inserted into the metadata cache,
2494+
* making sure to free the file space that was allocated for it as well.
2495+
* Avoid expunging the entry, as the information needs to be kept around
2496+
* until we finish trying to settle the metadata free space manager(s).
2497+
*/
2498+
if (inserted_header || allocated_header) {
2499+
assert(H5_addr_defined(fspace->addr));
2500+
2501+
if (allocated_header) {
2502+
/* Free file space before removing entry from cache, as freeing the
2503+
* file space may depend on a valid cache pointer.
2504+
*/
2505+
if (H5MF_xfree(f, H5FD_MEM_FSPACE_HDR, fspace->addr, hdr_alloc_size) < 0)
2506+
HDONE_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to free file free space header");
2507+
fspace->addr = HADDR_UNDEF;
2508+
}
2509+
2510+
if (inserted_header) {
2511+
if (H5AC_mark_entry_clean(fspace) < 0)
2512+
HDONE_ERROR(H5E_FSPACE, H5E_CANTMARKCLEAN, FAIL,
2513+
"can't mark file free space header as clean");
2514+
if (H5AC_unpin_entry(fspace) < 0)
2515+
HDONE_ERROR(H5E_FSPACE, H5E_CANTUNPIN, FAIL, "can't unpin file free space header");
2516+
if (H5AC_remove_entry(fspace) < 0)
2517+
HDONE_ERROR(H5E_FSPACE, H5E_CANTEXPUNGE, FAIL,
2518+
"can't remove file free space header from cache");
2519+
}
2520+
}
2521+
}
2522+
24562523
FUNC_LEAVE_NOAPI(ret_value)
24572524
} /* H5FS_vfd_alloc_hdr_and_section_info_if_needed() */

src/H5HFspace.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ H5HF__space_add(H5HF_hdr_t *hdr, H5HF_free_section_t *node, unsigned flags)
159159
udata.hdr = hdr;
160160

161161
/* Add to the free space for the heap */
162-
if (H5FS_sect_add(hdr->f, hdr->fspace, (H5FS_section_info_t *)node, flags, &udata) < 0)
162+
if (H5FS_sect_add(hdr->f, hdr->fspace, (H5FS_section_info_t *)node, flags, &udata, NULL) < 0)
163163
HGOTO_ERROR(H5E_HEAP, H5E_CANTINSERT, FAIL, "can't add section to heap free space");
164164

165165
done:

src/H5MF.c

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -599,7 +599,8 @@ H5MF__close_fstype(H5F_t *f, H5F_mem_page_t type)
599599
*-------------------------------------------------------------------------
600600
*/
601601
herr_t
602-
H5MF__add_sect(H5F_t *f, H5FD_mem_t alloc_type, H5FS_t *fspace, H5MF_free_section_t *node)
602+
H5MF__add_sect(H5F_t *f, H5FD_mem_t alloc_type, H5FS_t *fspace, H5MF_free_section_t *node,
603+
bool *merged_or_shrunk)
603604
{
604605
H5AC_ring_t orig_ring = H5AC_RING_INV; /* Original ring value */
605606
H5AC_ring_t fsm_ring = H5AC_RING_INV; /* Ring of FSM */
@@ -631,7 +632,8 @@ H5MF__add_sect(H5F_t *f, H5FD_mem_t alloc_type, H5FS_t *fspace, H5MF_free_sectio
631632
__func__, node->sect_info.addr, node->sect_info.size);
632633
#endif /* H5MF_ALLOC_DEBUG_MORE */
633634
/* Add the section */
634-
if (H5FS_sect_add(f, fspace, (H5FS_section_info_t *)node, H5FS_ADD_RETURNED_SPACE, &udata) < 0)
635+
if (H5FS_sect_add(f, fspace, (H5FS_section_info_t *)node, H5FS_ADD_RETURNED_SPACE, &udata,
636+
merged_or_shrunk) < 0)
635637
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINSERT, FAIL, "can't re-add section to file free space");
636638

637639
done:
@@ -711,8 +713,11 @@ H5MF__find_sect(H5F_t *f, H5FD_mem_t alloc_type, hsize_t size, H5FS_t *fspace, h
711713
#endif /* H5MF_ALLOC_DEBUG_MORE */
712714

713715
/* Re-add the section to the free-space manager */
714-
if (H5MF__add_sect(f, alloc_type, fspace, node) < 0)
716+
if (H5MF__add_sect(f, alloc_type, fspace, node, NULL) < 0) {
717+
node->sect_info.addr -= size;
718+
node->sect_info.size += size;
715719
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINSERT, FAIL, "can't re-add section to file free space");
720+
}
716721
} /* end else */
717722
} /* end if */
718723

@@ -852,9 +857,10 @@ H5MF_alloc(H5F_t *f, H5FD_mem_t alloc_type, hsize_t size)
852857
static haddr_t
853858
H5MF__alloc_pagefs(H5F_t *f, H5FD_mem_t alloc_type, hsize_t size)
854859
{
855-
H5F_mem_page_t ptype; /* Free-space manager type */
856-
H5MF_free_section_t *node = NULL; /* Free space section pointer */
857-
haddr_t ret_value = HADDR_UNDEF; /* Return value */
860+
H5F_mem_page_t ptype; /* Free-space manager type */
861+
H5MF_free_section_t *node = NULL; /* Free space section pointer */
862+
bool section_merged_or_shrunk = false; /* Whether free space section was merged or shrunk away */
863+
haddr_t ret_value = HADDR_UNDEF; /* Return value */
858864

859865
FUNC_ENTER_PACKAGE
860866

@@ -900,9 +906,13 @@ H5MF__alloc_pagefs(H5F_t *f, H5FD_mem_t alloc_type, hsize_t size)
900906
"can't initialize free space section");
901907

902908
/* Add the fragment to the large free-space manager */
903-
if (H5MF__add_sect(f, alloc_type, f->shared->fs_man[ptype], node) < 0)
909+
if (H5MF__add_sect(f, alloc_type, f->shared->fs_man[ptype], node, &section_merged_or_shrunk) <
910+
0) {
911+
if (section_merged_or_shrunk)
912+
node = NULL;
904913
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINSERT, HADDR_UNDEF,
905914
"can't re-add section to file free space");
915+
}
906916

907917
node = NULL;
908918
} /* end if */
@@ -931,9 +941,12 @@ H5MF__alloc_pagefs(H5F_t *f, H5FD_mem_t alloc_type, hsize_t size)
931941
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, HADDR_UNDEF, "can't initialize free space section");
932942

933943
/* Add the remaining space in the page to the manager */
934-
if (H5MF__add_sect(f, alloc_type, f->shared->fs_man[ptype], node) < 0)
944+
if (H5MF__add_sect(f, alloc_type, f->shared->fs_man[ptype], node, &section_merged_or_shrunk) < 0) {
945+
if (section_merged_or_shrunk)
946+
node = NULL;
935947
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINSERT, HADDR_UNDEF,
936948
"can't re-add section to file free space");
949+
}
937950

938951
node = NULL;
939952

@@ -1154,15 +1167,21 @@ H5MF_xfree(H5F_t *f, H5FD_mem_t alloc_type, haddr_t addr, hsize_t size)
11541167

11551168
/* If size of the freed section is larger than threshold, add it to the free space manager */
11561169
if (size >= f->shared->fs_threshold) {
1170+
bool section_merged_or_shrunk = false; /* Whether free space section was merged or shrunk away */
1171+
11571172
assert(f->shared->fs_man[fs_type]);
11581173

11591174
#ifdef H5MF_ALLOC_DEBUG_MORE
11601175
fprintf(stderr, "%s: Before H5FS_sect_add()\n", __func__);
11611176
#endif /* H5MF_ALLOC_DEBUG_MORE */
11621177

11631178
/* Add to the free space for the file */
1164-
if (H5MF__add_sect(f, alloc_type, f->shared->fs_man[fs_type], node) < 0)
1179+
if (H5MF__add_sect(f, alloc_type, f->shared->fs_man[fs_type], node, &section_merged_or_shrunk) < 0) {
1180+
if (section_merged_or_shrunk)
1181+
node = NULL;
11651182
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINSERT, FAIL, "can't add section to file free space");
1183+
}
1184+
11661185
node = NULL;
11671186

11681187
#ifdef H5MF_ALLOC_DEBUG_MORE
@@ -1316,7 +1335,7 @@ H5MF_try_extend(H5F_t *f, H5FD_mem_t alloc_type, haddr_t addr, hsize_t size, hsi
13161335
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't initialize free space section");
13171336

13181337
/* Add the fragment to the large-sized free-space manager */
1319-
if (H5MF__add_sect(f, alloc_type, f->shared->fs_man[fs_type], node) < 0)
1338+
if (H5MF__add_sect(f, alloc_type, f->shared->fs_man[fs_type], node, NULL) < 0)
13201339
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINSERT, FAIL, "can't re-add section to file free space");
13211340

13221341
node = NULL;
@@ -3059,8 +3078,13 @@ H5MF_settle_meta_data_fsm(H5F_t *f, bool *fsm_settled)
30593078
assert(sm_fssinfo_fs_type > H5F_MEM_PAGE_DEFAULT);
30603079
assert(sm_fssinfo_fs_type < H5F_MEM_PAGE_LARGE_SUPER);
30613080

3062-
assert(!H5_addr_defined(f->shared->fs_addr[sm_fshdr_fs_type]));
3063-
assert(!H5_addr_defined(f->shared->fs_addr[sm_fssinfo_fs_type]));
3081+
if (H5_addr_defined(f->shared->fs_addr[sm_fshdr_fs_type]))
3082+
HGOTO_ERROR(H5E_FSPACE, H5E_BADVALUE, FAIL,
3083+
"small free space header block manager should not have had file space allocated");
3084+
if (H5_addr_defined(f->shared->fs_addr[sm_fssinfo_fs_type]))
3085+
HGOTO_ERROR(
3086+
H5E_FSPACE, H5E_BADVALUE, FAIL,
3087+
"small free space serialized section manager should not have had file space allocated");
30643088

30653089
/* Note that in most cases, sm_hdr_fspace will equal sm_sinfo_fspace. */
30663090
sm_hdr_fspace = f->shared->fs_man[sm_fshdr_fs_type];
@@ -3078,8 +3102,13 @@ H5MF_settle_meta_data_fsm(H5F_t *f, bool *fsm_settled)
30783102
assert(lg_fssinfo_fs_type >= H5F_MEM_PAGE_LARGE_SUPER);
30793103
assert(lg_fssinfo_fs_type < H5F_MEM_PAGE_NTYPES);
30803104

3081-
assert(!H5_addr_defined(f->shared->fs_addr[lg_fshdr_fs_type]));
3082-
assert(!H5_addr_defined(f->shared->fs_addr[lg_fssinfo_fs_type]));
3105+
if (H5_addr_defined(f->shared->fs_addr[lg_fshdr_fs_type]))
3106+
HGOTO_ERROR(H5E_FSPACE, H5E_BADVALUE, FAIL,
3107+
"large free space header block manager should not have had file space allocated");
3108+
if (H5_addr_defined(f->shared->fs_addr[lg_fssinfo_fs_type]))
3109+
HGOTO_ERROR(
3110+
H5E_FSPACE, H5E_BADVALUE, FAIL,
3111+
"large free space serialized section manager should not have had file space allocated");
30833112

30843113
/* Note that in most cases, lg_hdr_fspace will equal lg_sinfo_fspace. */
30853114
lg_hdr_fspace = f->shared->fs_man[lg_fshdr_fs_type];

src/H5MFpkg.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,8 @@ H5_DLLVAR const H5FS_section_class_t H5MF_FSPACE_SECT_CLS_LARGE[1];
176176
H5_DLL herr_t H5MF__open_fstype(H5F_t *f, H5F_mem_page_t type);
177177
H5_DLL herr_t H5MF__start_fstype(H5F_t *f, H5F_mem_page_t type);
178178
H5_DLL htri_t H5MF__find_sect(H5F_t *f, H5FD_mem_t alloc_type, hsize_t size, H5FS_t *fspace, haddr_t *addr);
179-
H5_DLL herr_t H5MF__add_sect(H5F_t *f, H5FD_mem_t alloc_type, H5FS_t *fspace, H5MF_free_section_t *node);
179+
H5_DLL herr_t H5MF__add_sect(H5F_t *f, H5FD_mem_t alloc_type, H5FS_t *fspace, H5MF_free_section_t *node,
180+
bool *merged_or_shrunk);
180181
H5_DLL void H5MF__alloc_to_fs_type(H5F_shared_t *f_sh, H5FD_mem_t alloc_type, hsize_t size,
181182
H5F_mem_page_t *fs_type);
182183

src/H5MFsection.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,6 @@ H5MF__sect_simple_can_merge(const H5FS_section_info_t *_sect1, const H5FS_sectio
360360
assert(sect1);
361361
assert(sect2);
362362
assert(sect1->sect_info.type == sect2->sect_info.type); /* Checks "MERGE_SYM" flag */
363-
assert(H5_addr_lt(sect1->sect_info.addr, sect2->sect_info.addr));
364363

365364
/* Check if second section adjoins first section */
366365
ret_value = H5_addr_eq(sect1->sect_info.addr + sect1->sect_info.size, sect2->sect_info.addr);
@@ -663,7 +662,6 @@ H5MF__sect_small_can_merge(const H5FS_section_info_t *_sect1, const H5FS_section
663662
assert(sect1);
664663
assert(sect2);
665664
assert(sect1->sect_info.type == sect2->sect_info.type); /* Checks "MERGE_SYM" flag */
666-
assert(H5_addr_lt(sect1->sect_info.addr, sect2->sect_info.addr));
667665

668666
/* Check if second section adjoins first section */
669667
ret_value = H5_addr_eq(sect1->sect_info.addr + sect1->sect_info.size, sect2->sect_info.addr);
@@ -769,7 +767,6 @@ H5MF__sect_large_can_merge(const H5FS_section_info_t *_sect1, const H5FS_section
769767
assert(sect1);
770768
assert(sect2);
771769
assert(sect1->sect_info.type == sect2->sect_info.type); /* Checks "MERGE_SYM" flag */
772-
assert(H5_addr_lt(sect1->sect_info.addr, sect2->sect_info.addr));
773770

774771
ret_value = H5_addr_eq(sect1->sect_info.addr + sect1->sect_info.size, sect2->sect_info.addr);
775772

0 commit comments

Comments
 (0)