Hello, On Fri, 31 Jul 2026 01:41:29 Samuel Thibault wrote:
> I guess that when we are returning an error code to other source code, > we should be returning ENOMEM, so that other source code can possibly > behave properly, faced to something that is similar to memory exhaustion > anyway. When we know that we are handling the error ourself in the code > by printing it to the user, better keep the real errno, to tell the user > the real reason. It seems to me that we can replace ENOMEM with errno in the vast majority of cases. Let's say the third-party code that calls our code only checks for the return of an error, then there's no problem with us returning errno. If it specifically checks for the return of ENOMEM, then it's likely that other possible errors are also checked. Perhaps it's worth further researching this topic to be sure there are no pitfalls. I would also like to thank Alperen Erkan, who provided some very important comments on the patches via private messages. Thanks, -- Mikhail Karpov
From e1d57b56eed383a4be2d473d9acf09f5bd24af65 Mon Sep 17 00:00:00 2001 From: Mikhail Karpov <[email protected]> Date: Tue, 1 Sep 2026 19:30:51 +0700 Subject: [PATCH] Added checks for alloc return value in several place --- defpager/backing.c | 5 ++++ defpager/defpager.c | 23 ++++++++++++---- eth-multiplexer/netfs_impl.c | 24 +++++++++++++--- ext2fs/dir.c | 27 +++++++++++++++++- fatfs/fat.c | 3 ++ fatfs/pager.c | 3 ++ libbpf/bpf_impl.c | 4 +++ libdiskfs/file-chg.c | 8 ++++++ libpager/lock-object.c | 1 + libpager/object-init.c | 8 ++++++ libpager/pager-attr.c | 1 + libps/proclist.c | 6 +++- libps/procstat.c | 6 ++++ libstore/remap.c | 9 +++++- lwip/lwip-util.c | 9 +++++- lwip/pfinet-ops.c | 8 ++++++ lwip/port/netif/ifcommon.c | 3 ++ lwip/socket-ops.c | 3 ++ mach-defpager/default_pager.c | 44 ++++++++++++++++++++++++++++++ nfs/ops.c | 7 ++++- nfsd/cache.c | 6 ++++ nfsd/fsys.c | 18 +++++++++++- nfsd/loop.c | 3 ++ nfsd/xdr.c | 2 ++ pfinet/glue-include/linux/kernel.h | 3 ++ pfinet/socket-ops.c | 3 ++ proc/mgt.c | 1 + procfs/dircat.c | 16 ++++++++++- startup/startup.c | 11 +++++++- term/main.c | 3 ++ term/munge.c | 2 ++ term/users.c | 14 ++++++++++ trans/magic.c | 4 ++- trans/new-fifo.c | 1 + trans/remap.c | 3 ++ utils/msgport.c | 9 ++++++ utils/ps.c | 3 ++ utils/settrans.c | 6 ++-- 38 files changed, 289 insertions(+), 21 deletions(-) diff --git a/defpager/backing.c b/defpager/backing.c index 56fe655..d261dcc 100644 --- a/defpager/backing.c +++ b/defpager/backing.c @@ -50,6 +50,9 @@ init_backing (char *name) bmap_len = backing_store->size / vm_page_size / NBBY; bmap = malloc (bmap_len); + if (!bmap) + return errno; + for (i = 0; i < bmap_len; i++) bmap[i] = 0xff; bmap_rotor = bmap; @@ -60,6 +63,8 @@ init_backing (char *name) sure we don't tromp on the misfeature in Linux of using the first page for permanent data. */ *bmap_rotor |= 1; + + return 0; } int diff --git a/defpager/defpager.c b/defpager/defpager.c index 3b3cda1..02589a2 100644 --- a/defpager/defpager.c +++ b/defpager/defpager.c @@ -33,7 +33,7 @@ struct user_pager_info /* Expand the P->map as necessary to handle an incoming request of the page at ADDR. */ -static inline void +static inline error_t expand_map (struct user_pager_info *p, vm_offset_t addr) { /* See if this is beyond the current extent */ @@ -44,11 +44,16 @@ expand_map (struct user_pager_info *p, vm_offset_t addr) newsize = page + vm_page_size; newmap = realloc (pager->map, size / vm_page_size * sizeof (off_t)); + if (!newmap) + return errno; - memset (pager->map + pager->size / vm_page_size * sizeof(off_t), 0, (newsize - pager->size) / vm_page_size * sizeof(off_t)); + memset (pager->map + pager->size / vm_page_size * sizeof(off_t), + 0, (newsize - pager->size) / vm_page_size * sizeof(off_t)); pager->size = newsize; pager->map = newmap; } + + return 0; } error_t @@ -63,10 +68,16 @@ pager_read_page (struct user_pager_info *pager, /* We never request write locks. */ *write_lock = 0; - expand_map (pager, page); + error_t err = expand_map (pager, page); + if (err) + return err; if (!pager->map[pfn]) - vm_allocate (mach_task_self (), buf, vm_page_size, 1); + { + err = vm_allocate (mach_task_self (), buf, vm_page_size, 1); + if (err) + return err; + } else { store_read (backing_store, pager->map[pfn], vm_page_size, @@ -89,7 +100,9 @@ pager_write_page (struct user_pager_info *pager, int pfn = page / vm_page_size; size_t nwritten; - expand_map (pager, page); + error_t err = expand_map (pager, page); + if (err) + return err; if (!pager->map[pfn]) pager->map[pfn] = allocate_backing_page (); diff --git a/eth-multiplexer/netfs_impl.c b/eth-multiplexer/netfs_impl.c index 83a2313..e4a03d4 100644 --- a/eth-multiplexer/netfs_impl.c +++ b/eth-multiplexer/netfs_impl.c @@ -65,13 +65,13 @@ new_node (struct lnode *ln, struct node **np) struct node *node; if (nn == 0) - return ENOMEM; + return errno; node = netfs_make_node (nn); if (node == 0) { free (nn); *np = NULL; - return ENOMEM; + return errno; } if (ln) ln->n = node; @@ -86,17 +86,27 @@ lookup (const char *name) struct lnode *ln = (struct lnode *) lookup_dev_by_name (name); char *copied_name = malloc (strlen (name) + 1); + if (!copied_name) + return NULL; + strcpy (copied_name, name); + error_t err; if (ln) { - new_node (ln, &ln->n); + err = new_node (ln, &ln->n); + if (err) + return NULL; + ln->n->nn->name = copied_name; return ln->n; } else { struct node *n; - new_node (ln, &n); + err = new_node (ln, &n); + if (err) + return NULL; + n->nn->name = copied_name; return n; } @@ -305,6 +315,12 @@ error_t netfs_attempt_lookup (struct iouser *user, struct node *dir, } *node = lookup (name); + if (!*node) + { + pthread_mutex_unlock (&dir->lock); + return errno; + } + pthread_mutex_lock (&(*node)->lock); pthread_mutex_unlock (&dir->lock); return 0; diff --git a/ext2fs/dir.c b/ext2fs/dir.c index 55f2657..74a9ea2 100644 --- a/ext2fs/dir.c +++ b/ext2fs/dir.c @@ -493,6 +493,12 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, { diskfs_node_disknode (dp)->dirents = malloc ((dp->dn_stat.st_size / DIRBLKSIZ) * sizeof (int)); + if (!diskfs_node_disknode (dp)->dirents) + { + ext2_warning ("Failed to allocate memory for dirents"); + return ENOENT; + } + for (i = 0; i < dp->dn_stat.st_size/DIRBLKSIZ; i++) diskfs_node_disknode (dp)->dirents[i] = -1; } @@ -687,9 +693,16 @@ diskfs_direnter_hard (struct node *dp, const char *name, struct node *np, anything at all. */ if (diskfs_node_disknode (dp)->dirents) { - diskfs_node_disknode (dp)->dirents = + int *new_dirents = realloc (diskfs_node_disknode (dp)->dirents, (dp->dn_stat.st_size / DIRBLKSIZ * sizeof (int))); + if (!new_dirents) + { + ext2_warning ("Failed to reallocate memory for new_dirents"); + return ENOENT; + } + + diskfs_node_disknode (dp)->dirents = new_dirents; for (i = oldsize / DIRBLKSIZ; i < dp->dn_stat.st_size / DIRBLKSIZ; i++) @@ -701,6 +714,12 @@ diskfs_direnter_hard (struct node *dp, const char *name, struct node *np, { diskfs_node_disknode (dp)->dirents = malloc (dp->dn_stat.st_size / DIRBLKSIZ * sizeof (int)); + if (!diskfs_node_disknode (dp)->dirents) + { + ext2_warning ("Failed to allocate memory for dirents"); + return ENOENT; + } + for (i = 0; i < dp->dn_stat.st_size / DIRBLKSIZ; i++) diskfs_node_disknode (dp)->dirents[i] = -1; diskfs_node_disknode (dp)->dirents[ds->idx] = 1; @@ -907,6 +926,12 @@ diskfs_get_directs (struct node *dp, if (!diskfs_node_disknode (dp)->dirents) { diskfs_node_disknode (dp)->dirents = malloc (nblks * sizeof (int)); + if (!diskfs_node_disknode (dp)->dirents) + { + ext2_warning ("Failed to allocate memory for dirents"); + return ENOENT; + } + for (i = 0; i < nblks; i++) diskfs_node_disknode (dp)->dirents[i] = -1; } diff --git a/fatfs/fat.c b/fatfs/fat.c index e765376..b97cff3 100644 --- a/fatfs/fat.c +++ b/fatfs/fat.c @@ -72,6 +72,9 @@ fat_read_sblock (void) size_t read = sizeof(struct boot_sector); sblock = malloc (read); + if (!sblock) + error (1, errno, "Failed to allocate memory for superblock."); + err = store_read (store, 0, read, (void **) &sblock, &read); if (err) error (1, err, "Could not read superblock"); diff --git a/fatfs/pager.c b/fatfs/pager.c index e2302ce..88e014d 100644 --- a/fatfs/pager.c +++ b/fatfs/pager.c @@ -776,6 +776,9 @@ create_fat_pager (void) /* The disk pager. */ struct user_pager_info *upi = malloc (sizeof (struct user_pager_info)); + if (!upi) + error (2, errno, "Failed to allocate memory for user_pager_info."); + upi->type = FAT; disk_pager_bucket = ports_create_bucket (); diskfs_start_disk_pager (upi, disk_pager_bucket, MAY_CACHE, 0, diff --git a/libbpf/bpf_impl.c b/libbpf/bpf_impl.c index c78176c..38d71ab 100644 --- a/libbpf/bpf_impl.c +++ b/libbpf/bpf_impl.c @@ -612,6 +612,8 @@ net_set_filter(if_filter_list_t *ifp, mach_port_t rcv_port, int priority, * a normal packet filter structure. */ my_infp = (net_rcv_port_t) calloc(1, sizeof(struct net_rcv_port)); + if (!my_infp) + return (D_NO_MEMORY); my_infp->rcv_port = rcv_port; is_new_infp = TRUE; } else { @@ -622,6 +624,8 @@ net_set_filter(if_filter_list_t *ifp, mach_port_t rcv_port, int priority, */ my_infp = 0; hash_entp = (net_hash_entry_t) calloc(1, sizeof(struct net_hash_entry)); + if (!hash_entp) + return (D_NO_MEMORY); is_new_infp = FALSE; } diff --git a/libdiskfs/file-chg.c b/libdiskfs/file-chg.c index 18170c2..8883381 100644 --- a/libdiskfs/file-chg.c +++ b/libdiskfs/file-chg.c @@ -43,7 +43,15 @@ diskfs_S_file_notice_changes (struct protid *cred, mach_port_t notify) pthread_mutex_unlock (&np->lock); return err; } + req = malloc (sizeof (struct modreq)); + if (!req) + { + err = errno; + pthread_mutex_unlock (&np->lock); + return err; + } + req->port = notify; req->next = np->filemod_reqs; np->filemod_reqs = req; diff --git a/libpager/lock-object.c b/libpager/lock-object.c index d8a4c1f..01114ee 100644 --- a/libpager/lock-object.c +++ b/libpager/lock-object.c @@ -52,6 +52,7 @@ _pager_lock_object (struct pager *p, if (!lr) { lr = malloc (sizeof (struct lock_request)); + assert_backtrace (lr); lr->start = offset; lr->end = offset + size; lr->pending_writes = 0; diff --git a/libpager/object-init.c b/libpager/object-init.c index 619d28f..9b7e8b0 100644 --- a/libpager/object-init.c +++ b/libpager/object-init.c @@ -43,6 +43,14 @@ _pager_S_memory_object_init (struct pager *p, { #ifdef KERNEL_INIT_RACE struct pending_init *i = malloc (sizeof (struct pending_init)); + if (!i) + { + error_t err = errno; + printf ("failed to allocate memory for pending_init"); + pthread_mutex_unlock (&p->interlock); + return err; + } + printf ("pager out-of-sequence init\n"); i->control = control; i->name = name; diff --git a/libpager/pager-attr.c b/libpager/pager-attr.c index 4280e26..66c9b61 100644 --- a/libpager/pager-attr.c +++ b/libpager/pager-attr.c @@ -65,6 +65,7 @@ pager_change_attributes (struct pager *p, if (!ar) { ar = malloc (sizeof (struct attribute_request)); + assert_backtrace (ar); ar->may_cache = may_cache; ar->copy_strategy = copy_strategy; ar->attrs_pending = 1; diff --git a/libps/proclist.c b/libps/proclist.c index e1ce4c1..f9d408a 100644 --- a/libps/proclist.c +++ b/libps/proclist.c @@ -124,7 +124,11 @@ proc_stat_list_add_pids (struct proc_stat_list *pp, struct proc_stat **end = pp->proc_stats + pp->num_procs; if (proc_stats) - *proc_stats = NEWVEC (struct proc_stat *, num_procs); + { + *proc_stats = NEWVEC (struct proc_stat *, num_procs); + if (!*proc_stats) + return errno; + } for (i = 0; i < num_procs; i++) { diff --git a/libps/procstat.c b/libps/procstat.c index 4de4216..a34da63 100644 --- a/libps/procstat.c +++ b/libps/procstat.c @@ -204,6 +204,12 @@ merge_procinfo (struct proc_stat *ps, ps_flags_t need, ps_flags_t have) ps->thread_waits = malloc (WAITS_MALLOC_SIZE); ps->thread_waits_len = WAITS_MALLOC_SIZE; ps->thread_waits_vm_alloced = 0; + if (! ps->thread_waits) + { + if (! (have & PSTAT_PROCINFO)) + free (new_pi); + return ENOMEM; + } } new_waits = ps->thread_waits; new_waits_len = ps->thread_waits_len; diff --git a/libstore/remap.c b/libstore/remap.c index bbe7850..18fc78e 100644 --- a/libstore/remap.c +++ b/libstore/remap.c @@ -317,7 +317,14 @@ store_remap_runs (const struct store_run *runs, size_t num_runs, } if (xruns_alloced > *num_xruns) - *xruns = realloc (*xruns, *num_xruns * sizeof (struct store_run)); + { + void *new_xruns = realloc (*xruns, *num_xruns + * sizeof (struct store_run)); + if (!new_xruns) + return 0; + + *xruns = new_xruns; + } return 0; } diff --git a/lwip/lwip-util.c b/lwip/lwip-util.c index 4a83b8f..5dee35d 100644 --- a/lwip/lwip-util.c +++ b/lwip/lwip-util.c @@ -150,7 +150,10 @@ init_ifs (void *arg) int i; if (netif_list == 0) - netif_list = calloc (1, sizeof (struct netif)); + { + netif_list = calloc (1, sizeof (struct netif)); + assert_backtrace (netif_list); + } if (netif_list->next == 0) init_loopback (); @@ -186,6 +189,7 @@ init_ifs (void *arg) continue; netif = calloc (1, sizeof (struct netif)); + assert_backtrace (netif); create_netif_state (in->dev_name, &ifc); @@ -366,6 +370,9 @@ configure_device (struct netif *netif, ip4_addr_t addr, ip4_addr_t netmask, { /* Call update_if() inside the tcpip_thread */ struct update_if_args *arg = calloc (1, sizeof (struct update_if_args)); + if (!arg) + return errno; + arg->netif = netif; arg->addr = addr; arg->netmask = netmask; diff --git a/lwip/pfinet-ops.c b/lwip/pfinet-ops.c index 0755fcb..b9d2ef2 100644 --- a/lwip/pfinet-ops.c +++ b/lwip/pfinet-ops.c @@ -106,6 +106,9 @@ lwip_S_pfinet_siocgifconf (io_t port, void *buf = mmap (0, amount, PROT_READ | PROT_WRITE, MAP_ANON, 0, 0); if (buf == MAP_FAILED) + /* Should check whether errno is indeed ENOMEM -- + but this can't be done in a straightforward way, + because the glue headers #undef errno. */ return ENOMEM; ifc.ifc_buf = buf; @@ -209,6 +212,8 @@ lwip_S_pfinet_getroutes (io_t port, *dealloc_data = FALSE; rtable = calloc (MAX_ROUTES, sizeof (ifrtreq_t)); + if (!rtable) + return ENOMEM; available_count = get_routes (rtable); @@ -231,6 +236,9 @@ lwip_S_pfinet_getroutes (io_t port, if (*routes == MAP_FAILED) { + /* Should check whether errno is indeed ENOMEM -- + but this can't be done in a straightforward way, + because the glue headers #undef errno. */ *len = 0; return ENOMEM; } diff --git a/lwip/port/netif/ifcommon.c b/lwip/port/netif/ifcommon.c index cc4290a..3dac5d1 100644 --- a/lwip/port/netif/ifcommon.c +++ b/lwip/port/netif/ifcommon.c @@ -156,6 +156,9 @@ if_change_flags (struct netif * netif, uint16_t flags) */ struct if_change_flags_args *args = calloc (1, sizeof (struct if_change_flags_args)); + if (!args) + return errno; + args->netif = netif; args->flags = flags; err = tcpip_callback_wait(_if_change_flags, args); diff --git a/lwip/socket-ops.c b/lwip/socket-ops.c index 55f5a60..b422f28 100644 --- a/lwip/socket-ops.c +++ b/lwip/socket-ops.c @@ -291,6 +291,9 @@ lwip_S_socket_whatis_address (struct sock_addr * addr, void *buf = mmap (0, addr->address.sa.sa_len, PROT_READ | PROT_WRITE, MAP_ANON, 0, 0); if (buf == MAP_FAILED) + /* Should check whether errno is indeed ENOMEM -- + but this can't be done in a straightforward way, + because the glue headers #undef errno. */ return ENOMEM; *data = buf; diff --git a/mach-defpager/default_pager.c b/mach-defpager/default_pager.c index e55fa64..813a0a5 100644 --- a/mach-defpager/default_pager.c +++ b/mach-defpager/default_pager.c @@ -188,13 +188,20 @@ new_partition (const char *name, struct file_direct *fdp, bmsize = howmany(size, NB_BM) * sizeof(bm_entry_t); part = (partition_t) malloc(sizeof(struct part)); + if (!part) + panic("(default pager): failed to allocate memory for part"); pthread_mutex_init(&part->p_lock, NULL); part->name = (char*) malloc(n + 1); + if (!part->name) + panic("(default pager): failed to allocate memory for part->name"); strcpy(part->name, name); part->total_size = size; part->free = size; part->id = id; part->bitmap = (bm_entry_t *)malloc(bmsize); + if (!part->bitmap) + panic("(default pager): " + "failed to allocate memory for part->bitmap"); part->going_away= FALSE; part->file = fdp; @@ -633,6 +640,8 @@ dp_map_t pager_get_direct_map(dpager_t pager) } mapptr = (dp_map_t) malloc(alloc_size); + if (!mapptr) + panic("(default pager): failed to allocate memory for mapptr"); for (emapptr = &mapptr[(alloc_size-1) / sizeof(vm_offset_t)]; emapptr >= mapptr; emapptr--) @@ -683,10 +692,16 @@ pager_alloc(dpager_t pager, if (INDIRECT_PAGEMAP(size)) { mapptr = (vm_offset_t *) malloc(INDIRECT_PAGEMAP_SIZE(size)); + if (!mapptr) + panic("(default pager): " + "failed to allocate memory for mapptr"); for (i = INDIRECT_PAGEMAP_ENTRIES(size); --i >= 0;) mapptr[i] = 0; } else { mapptr = (vm_offset_t *) malloc(PAGEMAP_SIZE(size)); + if (!mapptr) + panic("(default pager): " + "failed to allocate memory for mapptr"); for (i = 0; i < size; i++) mapptr[i] = NO_CHECKSUM; } @@ -828,6 +843,9 @@ pager_extend(dpager_t pager, */ new_mapptr = (dp_map_t) malloc(INDIRECT_PAGEMAP_SIZE(new_size)); + if (!new_mapptr) + panic("(default pager): " + "failed to allocate memory for new_mapptr"); old_mapptr = pager_get_direct_map(pager); for (i = 0; i < INDIRECT_PAGEMAP_ENTRIES(old_size); i++) new_mapptr[i] = old_mapptr[i]; @@ -839,6 +857,9 @@ pager_extend(dpager_t pager, #ifdef CHECKSUM new_mapptr = (vm_offset_t *) malloc(INDIRECT_PAGEMAP_SIZE(new_size)); + if (!new_mapptr) + panic("(default pager): " + "failed to allocate memory for new_mapptr"); old_mapptr = pager->checksum; for (i = 0; i < INDIRECT_PAGEMAP_ENTRIES(old_size); i++) new_mapptr[i] = old_mapptr[i]; @@ -873,6 +894,9 @@ pager_extend(dpager_t pager, * Allocate new second-level map first. */ new_mapptr = (dp_map_t) malloc(PAGEMAP_SIZE(PAGEMAP_ENTRIES)); + if (!new_mapptr) + panic("(default pager): " + "failed to allocate memory for new_mapptr"); old_mapptr = pager_get_direct_map(pager); for (i = 0; i < old_size; i++) new_mapptr[i] = old_mapptr[i]; @@ -894,6 +918,9 @@ pager_extend(dpager_t pager, */ new_mapptr = (dp_map_t) malloc(INDIRECT_PAGEMAP_SIZE(new_size)); + if (!new_mapptr) + panic("(default pager): " + "failed to allocate memory for new_mapptr"); new_mapptr[0].indirect = old_mapptr; for (i = 1; i < INDIRECT_PAGEMAP_ENTRIES(new_size); i++) new_mapptr[i].indirect = 0; @@ -904,6 +931,9 @@ pager_extend(dpager_t pager, * Allocate new second-level map first. */ new_mapptr = (vm_offset_t *)malloc(PAGEMAP_SIZE(PAGEMAP_ENTRIES)); + if (!new_mapptr) + panic("(default pager): " + "failed to allocate memory for new_mapptr"); old_mapptr = pager->checksum; for (i = 0; i < old_size; i++) new_mapptr[i] = old_mapptr[i]; @@ -917,6 +947,9 @@ pager_extend(dpager_t pager, */ new_mapptr = (vm_offset_t *) malloc(INDIRECT_PAGEMAP_SIZE(new_size)); + if (!new_mapptr) + panic("(default pager): " + "failed to allocate memory for new_mapptr"); new_mapptr[0] = (vm_offset_t) old_mapptr; for (i = 1; i < INDIRECT_PAGEMAP_ENTRIES(new_size); i++) new_mapptr[i] = 0; @@ -932,6 +965,9 @@ pager_extend(dpager_t pager, * Enlarging a direct block. */ new_mapptr = (dp_map_t) malloc(PAGEMAP_SIZE(new_size)); + if (!new_mapptr) + panic("(default pager): " + "failed to allocate memory for new_mapptr"); old_mapptr = pager_get_direct_map(pager); for (i = 0; i < old_size; i++) new_mapptr[i] = old_mapptr[i]; @@ -943,6 +979,9 @@ pager_extend(dpager_t pager, #ifdef CHECKSUM new_mapptr = (vm_offset_t *) malloc(PAGEMAP_SIZE(new_size)); + if (!new_mapptr) + panic("(default pager): " + "failed to allocate memory for new_mapptr"); old_mapptr = pager->checksum; for (i = 0; i < old_size; i++) new_mapptr[i] = old_mapptr[i]; @@ -1021,6 +1060,9 @@ pager_truncate(dpager_t pager, vm_size_t new_size) /* in pages */ { const dp_map_t old_mapptr = pager->map; pager->map = (dp_map_t) malloc (INDIRECT_PAGEMAP_SIZE(new_size)); + if (!pager->map) + panic("(default pager): " + "failed to allocate memory for pager->map"); memcpy (pager->map, old_mapptr, INDIRECT_PAGEMAP_SIZE(new_size)); free ((char *) old_mapptr); } @@ -1042,6 +1084,8 @@ pager_truncate(dpager_t pager, vm_size_t new_size) /* in pages */ /* Now reduce the size of the direct map itself. */ const dp_map_t old_mapptr = pager->map; pager->map = (dp_map_t) malloc (PAGEMAP_SIZE (new_size)); + if (!pager->map) + panic("(default pager): failed to allocate memory for pager->map"); memcpy (pager->map, old_mapptr, PAGEMAP_SIZE (new_size)); free ((char *) old_mapptr); } diff --git a/nfs/ops.c b/nfs/ops.c index affdd93..c87ec72 100644 --- a/nfs/ops.c +++ b/nfs/ops.c @@ -2086,10 +2086,15 @@ netfs_attempt_mksymlink (struct iouser *cred, if (np->nn->dtrans == NOT_POSSIBLE) return EOPNOTSUPP; + char *name = malloc (strlen (arg) + 1); + if (!name) + return errno; + if (np->nn->dtrans == SYMLINK) free (np->nn->transarg.name); - np->nn->transarg.name = malloc (strlen (arg) + 1); + np->nn->transarg.name = name; + strcpy (np->nn->transarg.name, arg); np->nn->dtrans = SYMLINK; np->nn->stat_updated = 0; diff --git a/nfsd/cache.c b/nfsd/cache.c index 864739c..f13a8ca 100644 --- a/nfsd/cache.c +++ b/nfsd/cache.c @@ -106,10 +106,13 @@ idspec_lookup (int nuids, int ngids, int *uids, int *gids) assert_backtrace (sizeof (uid_t) == sizeof (int)); i = malloc (sizeof (struct idspec)); + assert_backtrace (i); i->nuids = nuids; i->ngids = ngids; i->uids = malloc (nuids * sizeof (uid_t)); i->gids = malloc (ngids * sizeof (gid_t)); + assert_backtrace (i->uids); + assert_backtrace (i->gids); memcpy (i->uids, uids, nuids * sizeof (uid_t)); memcpy (i->gids, gids, ngids * sizeof (gid_t)); i->references = 1; @@ -304,6 +307,7 @@ lookup_cache_handle (int *p, struct cache_handle **cp, struct idspec *i) } c = malloc (sizeof (struct cache_handle)); + assert_backtrace (c); memcpy (c->handle.array, p, NFS2_FHSIZE); cred_ref (i); c->ids = i; @@ -448,6 +452,7 @@ create_cached_handle (int fs, struct cache_handle *credc, file_t userport) /* Create it anew. */ c = malloc (sizeof (struct cache_handle)); + assert_backtrace (c); memcpy (c->handle.array, fhandle.array, NFS2_FHSIZE); cred_ref (credc->ids); c->ids = credc->ids; @@ -498,6 +503,7 @@ check_cached_replies (int xid, } cr = malloc (sizeof (struct cached_reply)); + assert_backtrace (cr); pthread_mutex_init (&cr->lock, NULL); pthread_mutex_lock (&cr->lock); memcpy (&cr->source, sender, sizeof (struct sockaddr_in)); diff --git a/nfsd/fsys.c b/nfsd/fsys.c index f746716..dc74e63 100644 --- a/nfsd/fsys.c +++ b/nfsd/fsys.c @@ -24,6 +24,7 @@ #include <hurd.h> #include <fcntl.h> #include <string.h> +#include <assert-backtrace.h> #include "nfsd.h" @@ -54,6 +55,12 @@ init_filesystems (void) fsystable = (struct fsys_spec *) malloc ((fsystablesize = 10) * sizeof (struct fsys_spec)); + if (!fsystable) + { + error (0, errno, "Failed to allocate memory for fsystable"); + return; + } + for (i = 0; i < fsystablesize; i++) { fsystable[i].fsys = MACH_PORT_NULL; @@ -96,8 +103,15 @@ init_filesystems (void) if (index >= fsystablesize) { - fsystable = (struct fsys_spec *) + void *new_fsystable = realloc (fsystable, index * 2 * sizeof (struct fsys_spec)); + if (!new_fsystable) + { + error (0, ENOMEM, "Cannot reallocate memory for fsystable"); + return; + } + + fsystable = new_fsystable; for (i = fsystablesize; i < index * 2; i++) { fsystable[i].fsys = MACH_PORT_NULL; @@ -190,6 +204,7 @@ enter_filesystem (char *name, file_t root) fsystable = (struct fsys_spec *) realloc (fsystable, (fsystablesize * 2) * sizeof (struct fsys_spec)); + assert_backtrace (fsystable); for (i = fsystablesize; i < fsystablesize * 2; i++) { fsystable[i].fsys = MACH_PORT_NULL; @@ -199,6 +214,7 @@ enter_filesystem (char *name, file_t root) } fsystable[nfsys].name = malloc (strlen (name) + 1); + assert_backtrace (fsystable[nfsys].name); strcpy (fsystable[nfsys].name, name); file_getcontrol (root, &fsystable[nfsys].fsys); nfsys++; diff --git a/nfsd/loop.c b/nfsd/loop.c index 8e3ab25..386a904 100644 --- a/nfsd/loop.c +++ b/nfsd/loop.c @@ -20,6 +20,7 @@ #include <string.h> #include <fcntl.h> +#include <assert-backtrace.h> #include "nfsd.h" @@ -81,6 +82,7 @@ server_loop (void *arg) goto repost_reply; r = (int *) (rbuf = malloc (MAXIOSIZE)); + assert_backtrace (r); if (ntohl (*p) != RPC_MSG_VERSION) { @@ -177,6 +179,7 @@ server_loop (void *arg) { free (rbuf); r = (int *) (rbuf = malloc (amt)); + assert_backtrace (r); } } diff --git a/nfsd/xdr.c b/nfsd/xdr.c index 8b17559..c40dc1e 100644 --- a/nfsd/xdr.c +++ b/nfsd/xdr.c @@ -23,6 +23,7 @@ #include <sys/stat.h> #include <sys/statfs.h> #include <string.h> +#include <assert-backtrace.h> #include "nfsd.h" /* Any better ideas? */ @@ -96,6 +97,7 @@ decode_name (int *p, char **name) len = ntohl (*p); p++; *name = malloc (len + 1); + assert_backtrace (*name); memcpy (*name, p, len); (*name)[len] = '\0'; return p + INTSIZE (len); diff --git a/pfinet/glue-include/linux/kernel.h b/pfinet/glue-include/linux/kernel.h index 62ba2ff..e34c0a7 100644 --- a/pfinet/glue-include/linux/kernel.h +++ b/pfinet/glue-include/linux/kernel.h @@ -46,6 +46,9 @@ static inline int getname (const char *name, char **newp) { *newp = malloc (strlen (name) + 1); + if (!*newp) + return ENOMEM; + strcpy (*newp, name); return 0; } diff --git a/pfinet/socket-ops.c b/pfinet/socket-ops.c index ff2e82b..5c587fa 100644 --- a/pfinet/socket-ops.c +++ b/pfinet/socket-ops.c @@ -349,6 +349,9 @@ S_socket_whatis_address (struct sock_addr *addr, void *new_data = mmap (0, addr->address.sa_len, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0); if (new_data == MAP_FAILED) + /* Should check whether errno is indeed ENOMEM -- + but this can't be done in a straightforward way, + because the glue headers #undef errno. */ return ENOMEM; *data = new_data; diff --git a/proc/mgt.c b/proc/mgt.c index dcb619a..05af823 100644 --- a/proc/mgt.c +++ b/proc/mgt.c @@ -885,6 +885,7 @@ complete_proc (struct proc *p, pid_t pid) if (!nulllogin) { nulllogin = malloc (sizeof (struct login) + sizeof (nullsname) + 1); + assert_backtrace (nulllogin); nulllogin->l_refcnt = 1; strcpy (nulllogin->l_name, nullsname); } diff --git a/procfs/dircat.c b/procfs/dircat.c index 5a60899..a11e278 100644 --- a/procfs/dircat.c +++ b/procfs/dircat.c @@ -36,6 +36,8 @@ dircat_get_contents (void *hook, char **contents, ssize_t *contents_len) pos = 0; *contents = malloc (sz = 512); + if (!*contents) + return errno; for (i=0; i < dcn->num_dirs; i++) { @@ -53,8 +55,20 @@ dircat_get_contents (void *hook, char **contents, ssize_t *contents_len) return err; } + char *new_contents; while (pos + sublen > sz) - *contents = realloc (*contents, sz *= 2); + { + new_contents = realloc (*contents, sz *= 2); + if (!new_contents) + { + err = errno; + free (*contents); + *contents = NULL; + return err; + } + + *contents = new_contents; + } memcpy (*contents + pos, subcon, sublen); pos += sublen; diff --git a/startup/startup.c b/startup/startup.c index fe409f5..ab49d55 100644 --- a/startup/startup.c +++ b/startup/startup.c @@ -1586,10 +1586,19 @@ S_startup_request_notification (mach_port_t server, calls; this is important. We need later notification requests to get executed first. */ nt = malloc (sizeof (struct ntfy_task)); + if (!nt) + return ENOMEM; + nt->notify_port = notify; nt->next = ntfy_tasks; - ntfy_tasks = nt; nt->name = malloc (strlen (name) + 1); + if (!nt->name) + { + free (nt); + return ENOMEM; + } + + ntfy_tasks = nt; strcpy (nt->name, name); return 0; } diff --git a/term/main.c b/term/main.c index 99ce2c6..4c24ba7 100644 --- a/term/main.c +++ b/term/main.c @@ -132,6 +132,9 @@ parse_opt (int opt, char *arg, struct argp_state *state) case ARGP_KEY_INIT: state->hook = calloc (1, sizeof *v); + if (!state->hook) + argp_failure (state, 1, errno, "Failed to allocate memory for" + " state->hook"); break; case ARGP_KEY_FINI: free (v); diff --git a/term/munge.c b/term/munge.c index 0903dd0..ca27ac1 100644 --- a/term/munge.c +++ b/term/munge.c @@ -752,6 +752,8 @@ reallocate_queue (struct queue *q) /* Make the queue twice as large. */ newq = malloc (sizeof (struct queue) + q->arraylen * 2 * sizeof (quoted_char)); + assert_backtrace (newq); + newq->susp = q->susp; newq->lowat = q->lowat; newq->hiwat = q->hiwat; diff --git a/term/users.c b/term/users.c index 629534f..2b6db3b 100644 --- a/term/users.c +++ b/term/users.c @@ -445,6 +445,12 @@ S_term_open_ctty (struct trivfs_protid *cred, if (!err) { struct protid_hook *hook = malloc (sizeof (struct protid_hook)); + if (!hook) + { + err = errno; + ports_port_deref (newcred); + return err; + } hook->pid = pid; hook->pgrp = pgrp; @@ -1938,7 +1944,15 @@ trivfs_S_io_async (struct trivfs_protid *cred, pthread_mutex_unlock (&global_lock); return EBADF; } + ar = malloc (sizeof (struct async_req)); + if (!ar) + { + error_t err = errno; + pthread_mutex_unlock (&global_lock); + return err; + } + ar->notify = notify; ar->next = async_requests; async_requests = ar; diff --git a/trans/magic.c b/trans/magic.c index 73fdaea..0ddbd78 100644 --- a/trans/magic.c +++ b/trans/magic.c @@ -427,7 +427,8 @@ parse_opt (int opt, char *arg, struct argp_state *state) void *buf = mmap (0, getpagesize (), PROT_READ|PROT_WRITE, MAP_ANON, 0, 0); if (buf == MAP_FAILED) - return errno; + argp_failure (state, 1, errno, "Failed to allocate memory for" + " m->dirbuf"); m->dirbuf = buf; struct dirent *d; d = add (m->dirbuf, "."); @@ -462,6 +463,7 @@ main (int argc, char **argv) mach_port_t bootstrap; struct trivfs_control *fsys; struct magic *m = calloc (1, sizeof *m); + assert_backtrace (m); argp_parse (&argp, argc, argv, 0, 0, m); diff --git a/trans/new-fifo.c b/trans/new-fifo.c index 7880eb2..ee8f482 100644 --- a/trans/new-fifo.c +++ b/trans/new-fifo.c @@ -100,6 +100,7 @@ static void fifo_trans_create (struct fifo_trans *from, struct fifo_trans **trans) { struct fifo_trans *new = malloc (sizeof (struct fifo_trans)); + assert_backtrace (new); new->server = 0; pthread_mutex_init (&new->active_fifo_lock, NULL); diff --git a/trans/remap.c b/trans/remap.c index 39d6ff9..c434a26 100644 --- a/trans/remap.c +++ b/trans/remap.c @@ -124,6 +124,9 @@ parse_opt (int key, char *arg, struct argp_state *state) { /* Second of a pair */ struct remap *remap = malloc (sizeof (*remap)); + if (!remap) + argp_failure (state, 1, errno, "Failed to allocate memory for" + " remap"); remap->from = remap_from; remap->to = strdup (arg); remap->next = remaps; diff --git a/utils/msgport.c b/utils/msgport.c index e3ea430..602e09e 100644 --- a/utils/msgport.c +++ b/utils/msgport.c @@ -558,6 +558,8 @@ add_cmd (cmd_func_t func, size_t minargs, size_t maxargs, *params->cmds = cmds; *params->num_cmds = num_cmds; + if (!cmds) + argp_failure (state, 1, errno, "Failed to reallocate memory for cmds"); cmd = &cmds[num_cmds-1]; cmd->f = func; @@ -565,6 +567,10 @@ add_cmd (cmd_func_t func, size_t minargs, size_t maxargs, if (maxargs) { cmd->args = malloc (maxargs * sizeof (char *)); + if (!cmd->args) + argp_failure (state, 1, errno, "Failed to allocate memory for" + " cmd->args"); + if (arg) cmd->args[i++] = arg; while (i < maxargs @@ -596,6 +602,9 @@ parse_cmd_opt (int key, char *arg, struct argp_state *state) re-parse it with 2 dashes prepended. */ size_t len = strlen (arg) + 1; arg_hack_buf = realloc (arg_hack_buf, 2 + len); + if (!arg_hack_buf) + argp_failure (state, 1, errno, "Failed to reallocate memory for" + " arg_hack_buf"); state->argv[--state->next] = arg_hack_buf; state->argv[state->next][0] = '-'; state->argv[state->next][1] = '-'; diff --git a/utils/ps.c b/utils/ps.c index 6a08f73..9ddd59e 100644 --- a/utils/ps.c +++ b/utils/ps.c @@ -276,6 +276,9 @@ main(int argc, char *argv[]) { size_t len = strlen (arg) + 1; arg_hack_buf = realloc (arg_hack_buf, 1 + len); + if (!arg_hack_buf) + argp_failure (state, 1, errno, "Failed to allocate memory for" + " arg_hack_buf"); state->argv[--state->next] = arg_hack_buf; state->argv[state->next][0] = '-'; memcpy (&state->argv[state->next][1], arg, len); diff --git a/utils/settrans.c b/utils/settrans.c index 1622f70..70971c3 100644 --- a/utils/settrans.c +++ b/utils/settrans.c @@ -109,7 +109,7 @@ get_credentials (void) uids = malloc (uids_len * sizeof (uid_t)); if (! uids) - return ENOMEM; + return errno; uids_len = geteuids (uids_len, uids); if (uids_len < 0) @@ -121,8 +121,8 @@ get_credentials (void) return errno; gids = malloc (gids_len * sizeof (gid_t)); - if (! uids) - return ENOMEM; + if (! gids) + return errno; gids_len = getgroups (gids_len, gids); if (gids_len < 0) -- 2.43.0
