The MAP_FAILED check for rtable was placed after get_routing_table
and memset had already dereferenced the pointer. If mmap failed
under memory pressure, pfinet would crash. Move the check to
immediately after mmap, release global_lock and return ENOMEM.
Also defer setting *dealloc_data until after confirming mmap
succeeded.
* pfinet/pfinet-ops.c (S_pfinet_getroutes): Check rtable for
MAP_FAILED right after mmap; set *dealloc_data only on success.
---
pfinet/pfinet-ops.c | 20 ++++++++------------
1 file changed, 8 insertions(+), 12 deletions(-)
diff --git a/pfinet/pfinet-ops.c b/pfinet/pfinet-ops.c
index 796d6241..e40ceecb 100644
--- a/pfinet/pfinet-ops.c
+++ b/pfinet/pfinet-ops.c
@@ -158,6 +158,11 @@ S_pfinet_getroutes (io_t port,
{
rtable = (ifrtreq_t *) mmap (0, amount * sizeof(ifrtreq_t),
PROT_READ|PROT_WRITE,
MAP_ANON, 0, 0);
+ if (rtable == MAP_FAILED)
+ {
+ pthread_mutex_unlock (&global_lock);
+ return ENOMEM;
+ }
if (dealloc_data)
*dealloc_data = TRUE;
}
@@ -169,18 +174,9 @@ S_pfinet_getroutes (io_t port,
memset(&rtable[n], 0, (amount - n) * sizeof(ifrtreq_t));
}
- if (rtable == MAP_FAILED)
- {
- /* Should use errno here, but glue headers #undef errno */
- err = ENOMEM;
- *len = 0;
- }
- else
- {
- *len = n * sizeof(ifrtreq_t);
- *routes = (char *)rtable;
- }
+ *len = n * sizeof(ifrtreq_t);
+ *routes = (char *)rtable;
pthread_mutex_unlock (&global_lock);
- return err;
+ return 0;
}
--
2.54.0