diff -rup /local/src/hurd.orig/nfs/ChangeLog hurd/nfs/ChangeLog --- /local/src/hurd.orig/nfs/ChangeLog Wed Apr 25 13:38:05 2001 +++ hurd/nfs/ChangeLog Mon Aug 20 23:18:22 2001 @@ -1,3 +1,15 @@ +2001-08-20 Igor Khavkine + + * ops.c (netfs_attempt_mksymlink): Check return value + of malloc(). + * pager.c (register_new_page): Likewise, and change the return + value to `error_t' instead of `void' to be able to propagate + errors. + * pager.c (pager_read_page): Adjust to new `register_new_page' + interface. Change `bcopy' to `memcpy'. + * pager.c (netfs_get_filemap): Check return value of malloc(). + * rpc.c (generate_xid): Comment fix. + 2000-12-26 Neal H Walfield * cache.c: Change cache/hash table size to 509, a prime. Use diff -rup /local/src/hurd.orig/nfs/ops.c hurd/nfs/ops.c --- /local/src/hurd.orig/nfs/ops.c Wed Apr 25 13:38:05 2001 +++ hurd/nfs/ops.c Mon Aug 20 01:35:31 2001 @@ -1843,6 +1843,9 @@ netfs_attempt_mksymlink (struct iouser * free (np->nn->transarg.name); np->nn->transarg.name = malloc (strlen (arg) + 1); + if (!np->nn->transarg.name) + return ENOMEM; + strcpy (np->nn->transarg.name, arg); np->nn->dtrans = SYMLINK; np->nn->stat_updated = 0; diff -rup /local/src/hurd.orig/nfs/pager.c hurd/nfs/pager.c --- /local/src/hurd.orig/nfs/pager.c Sun Jul 11 01:31:15 1999 +++ hurd/nfs/pager.c Mon Aug 20 02:12:59 2001 @@ -24,6 +24,7 @@ #include #include #include +#include struct user_pager_info { @@ -45,12 +46,16 @@ static spin_lock_t pager_cache_rec_lock static spin_lock_t node2pagelock = SPIN_LOCK_INITIALIZER; static struct port_bucket *pager_bucket; -void +error_t register_new_page (struct pager *p, vm_offset_t offset) { + error_t err; struct pager_cache_rec *pc; pc = malloc (sizeof (struct pager_cache_rec)); + if (!pc) + return ENOMEM; + pc->offset = offset; pc->p = p; ports_port_ref (p); @@ -60,6 +65,8 @@ register_new_page (struct pager *p, vm_o pc->next = pager_cache_recs; pager_cache_recs = pc; spin_unlock (&pager_cache_rec_lock); + + return 0; } any_t @@ -153,7 +160,7 @@ pager_read_page (struct user_pager_info if (trans_len > thisamt) trans_len = thisamt; /* ??? */ - bcopy (p, data, trans_len); + memcpy (data, p, trans_len); free (rpcbuf); @@ -166,7 +173,14 @@ pager_read_page (struct user_pager_info break; } - register_new_page (pager->p, page); + err = register_new_page (pager->p, page); + if (!err) + { + munmap ((caddr_t) *buf, vm_page_size); + mutex_unlock (&np->lock); + return err; + } + mutex_unlock (&np->lock); return 0; } @@ -280,6 +294,11 @@ netfs_get_filemap (struct node *np, vm_p if (!np->nn->fileinfo) { upi = malloc (sizeof (struct user_pager_info)); + if (!upi) + { + spin_unlock (&node2pagelock); + return MACH_PORT_NULL; + } upi->np = np; netfs_nref (np); upi->max_prot = prot; diff -rup /local/src/hurd.orig/nfs/rpc.c hurd/nfs/rpc.c --- /local/src/hurd.orig/nfs/rpc.c Wed Apr 25 13:38:05 2001 +++ hurd/nfs/rpc.c Mon Aug 20 02:16:48 2001 @@ -69,7 +69,7 @@ generate_xid () /* Set up an RPC for procdeure RPC_PROC for talking to the server PROGRAM of version VERSION. Allocate storage with malloc and point - *BUF at it; caller must free this when done. Allocate at least LEN + *BUFP at it; caller must free this when done. Allocate at least LEN bytes more than the usual amount for the RPC. Initialize the RPC credential structure with UID, GID, and SECOND_GID; any of these may be -1 to indicate that it does not apply, however, exactly zero diff -rup /local/src/hurd.orig/nfsd/ChangeLog hurd/nfsd/ChangeLog --- /local/src/hurd.orig/nfsd/ChangeLog Wed Apr 25 13:38:05 2001 +++ hurd/nfsd/ChangeLog Mon Aug 20 23:28:19 2001 @@ -1,3 +1,27 @@ +2001-08-20 Igor Khavkine + + * cache.c (idspec_lookup): Check return value of malloc(). + Change `bcopy' to `memcpy'. + * cache.c (process_cred): Check return value of idspec_lookup(). + * cache.c (lookup_cache_handle): Changed function prototype + to return `error_t' to be able to propagate errors. Check for + return value of malloc(). Changed `bcopy' to `memcpy'. + * cache.c (create_cached_handle): Handle invalid value of + the first argument FS. Check return value of malloc(). Changed + `bcopy' to `memcpy'. + * cache.c (check_cached_replies): Check return value of malloc(). + Changed `bcopy' to `memcpy'. + * fsys.c (init_filesystems): Check return value of malloc(). + * fsys.c (enter_filesystem): Check return value of malloc(). + * loop.c (server_loop): Check return value of malloc(). Adapted + to the new interface for `lookup_cache_handle'. + * nfsd.h: Updated the prototype for `lookup_cache_handle'. + * ops.c (op_lookup, op_create, op_remove, op_rename, op_link, + op_symlink, op_mkdir, op_rmdir, op_mnt): Check return value of + `decode_name' and `lookup_cache_handle'. + * xdr.c (decode_name): Check return value of malloc(). Changed + `bcopy' to `memcpy'. + 2001-02-25 Roland McGrath * ops.c: Include for decls of built-ins. diff -rup /local/src/hurd.orig/nfsd/cache.c hurd/nfsd/cache.c --- /local/src/hurd.orig/nfsd/cache.c Wed Apr 25 13:38:05 2001 +++ hurd/nfsd/cache.c Mon Aug 20 23:03:12 2001 @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -103,12 +104,26 @@ idspec_lookup (int nuids, int ngids, int assert (sizeof (uid_t) == sizeof (int)); i = malloc (sizeof (struct idspec)); + if (!i) + { + spin_unlock (&idhashlock); + return NULL; + } + i->nuids = nuids; i->ngids = ngids; i->uids = malloc (nuids * sizeof (uid_t)); i->gids = malloc (ngids * sizeof (gid_t)); - bcopy (uids, i->uids, nuids * sizeof (uid_t)); - bcopy (gids, i->gids, ngids * sizeof (gid_t)); + if (!i->uids || !i->gids) + { + free (i->uids); + free (i->gids); + free (i); + spin_unlock (&idhashlock); + return NULL; + } + memcpy (i->uids, uids, nuids * sizeof (uid_t)); + memcpy (i->gids, gids, ngids * sizeof (gid_t)); i->references = 1; i->next = idhashtable[hash]; @@ -138,6 +153,7 @@ process_cred (int *p, struct idspec **cr { int size = ntohl (*p++); *credp = idspec_lookup (0, 0, 0, 0); + assert (*credp); p += INTSIZE (size); } else @@ -165,6 +181,7 @@ process_cred (int *p, struct idspec **cr p += ngids - 1; *credp = idspec_lookup (1, ngids, uid, gids); + assert (*credp); } /* Next is the verf field; skip it entirely */ @@ -260,42 +277,51 @@ fh_hash (char *fhandle, struct idspec *i return hash % FHHASH_TABLE_SIZE; } -int * -lookup_cache_handle (int *p, struct cache_handle **cp, struct idspec *i) +error_t +lookup_cache_handle (int **p, struct cache_handle **cp, struct idspec *i) { int hash; struct cache_handle *c; fsys_t fsys; file_t port; - hash = fh_hash ((char *)p, i); + hash = fh_hash ((char *)*p, i); mutex_lock (&fhhashlock); for (c = fhhashtable[hash]; c; c = c->next) - if (c->ids == i && ! bcmp (c->handle, p, NFS2_FHSIZE)) + if (c->ids == i && ! bcmp (c->handle, *p, NFS2_FHSIZE)) { if (c->references == 0) nfreefh--; c->references++; mutex_unlock (&fhhashlock); *cp = c; - return p + NFS2_FHSIZE / sizeof (int); + *p += NFS2_FHSIZE / sizeof (int); + return 0; } /* Not found */ /* First four bytes are our internal table of filesystems */ - fsys = lookup_filesystem (*p); + fsys = lookup_filesystem (**p); if (fsys == MACH_PORT_NULL || fsys_getfile (fsys, i->uids, i->nuids, i->gids, i->ngids, - (char *)(p + 1), NFS2_FHSIZE - sizeof (int), &port)) + (char *)(*p + 1), NFS2_FHSIZE - sizeof (int), &port)) { mutex_unlock (&fhhashlock); *cp = 0; - return p + NFS2_FHSIZE / sizeof (int); + *p += NFS2_FHSIZE / sizeof (int); + return 0; } c = malloc (sizeof (struct cache_handle)); - bcopy (p, c->handle, NFS2_FHSIZE); + if (!c) + { + mutex_unlock (&fhhashlock); + *cp = 0; + /* do not advance *P before returning */ + return ENOMEM; + } + memcpy (c->handle, *p, NFS2_FHSIZE); cred_ref (i); c->ids = i; c->port = port; @@ -309,7 +335,8 @@ lookup_cache_handle (int *p, struct cach mutex_unlock (&fhhashlock); *cp = c; - return p + NFS2_FHSIZE / sizeof (int); + *p += NFS2_FHSIZE / sizeof (int); + return 0; } void @@ -381,6 +408,10 @@ create_cached_handle (int fs, struct cac size_t handlelen = NFS2_FHSIZE - sizeof (int); mach_port_t newport, ref; + /* handle possibly invalid FS argument */ + if (fs < 0) + return NULL; + /* Authenticate USERPORT so that we can call file_getfh on it. */ ref = mach_reply_port (); /* MAKE_SEND is safe becaue we destroy REF ourselves. */ @@ -438,7 +469,12 @@ create_cached_handle (int fs, struct cac /* Create it anew */ c = malloc (sizeof (struct cache_handle)); - bcopy (fhandle, c->handle, NFS2_FHSIZE); + if (!c) + { + mutex_unlock (&fhhashlock); + return 0; + } + memcpy (c->handle, fhandle, NFS2_FHSIZE); cred_ref (credc->ids); c->ids = credc->ids; c->port = newport; @@ -488,9 +524,14 @@ check_cached_replies (int xid, } cr = malloc (sizeof (struct cached_reply)); + if (!cr) + { + spin_unlock (&replycachelock); + return NULL; + } mutex_init (&cr->lock); mutex_lock (&cr->lock); - bcopy (sender, &cr->source, sizeof (struct sockaddr_in)); + memcpy (&cr->source, sender, sizeof (struct sockaddr_in)); cr->xid = xid; cr->data = 0; cr->references = 1; diff -rup /local/src/hurd.orig/nfsd/fsys.c hurd/nfsd/fsys.c --- /local/src/hurd.orig/nfsd/fsys.c Wed Aug 7 15:03:28 1996 +++ hurd/nfsd/fsys.c Mon Aug 20 23:04:19 2001 @@ -53,6 +53,13 @@ init_filesystems (void) fsystable = (struct fsys_spec *) malloc ((fsystablesize = 10) * sizeof (struct fsys_spec)); + if (!fsystable) + { + fprintf (stderr, "%s: Cannot llocate fsystable: %s\n", + program_invocation_name, strerror (errno)); + return; + } + for (i = 0; i < fsystablesize; i++) { fsystable[i].fsys = MACH_PORT_NULL; @@ -100,6 +107,14 @@ init_filesystems (void) { fsystable = (struct fsys_spec *) realloc (fsystable, index * 2 * sizeof (struct fsys_spec)); + if (!fsystable) + { + fprintf (stderr, "%s: Cannot realloc fsystable: %s\n", + program_invocation_name, strerror (errno)); + free (name); + fclose (index_file); + return; + } for (i = fsystablesize; i < index * 2; i++) { fsystable[i].fsys = MACH_PORT_NULL; @@ -194,6 +209,12 @@ enter_filesystem (char *name, file_t roo fsystable = (struct fsys_spec *) realloc (fsystable, (fsystablesize * 2) * sizeof (struct fsys_spec)); + if (!fsystable) + { + fprintf (stderr, "%s: Cannot reallocate fsystable: %s\n", + program_invocation_name, strerror (errno)); + return -1; + } for (i = fsystablesize; i < fsystablesize * 2; i++) { fsystable[i].fsys = MACH_PORT_NULL; @@ -203,6 +224,12 @@ enter_filesystem (char *name, file_t roo } fsystable[nfsys].name = malloc (strlen (name) + 1); + if (!fsystable[nfsys].name) + { + fprintf (stderr, "%s: Cannot allocate file name: %s\n", + program_invocation_name, strerror (errno)); + return -1; + } strcpy (fsystable[nfsys].name, name); file_getcontrol (root, &fsystable[nfsys].fsys); nfsys++; diff -rup /local/src/hurd.orig/nfsd/loop.c hurd/nfsd/loop.c --- /local/src/hurd.orig/nfsd/loop.c Sun Dec 20 15:51:58 1998 +++ hurd/nfsd/loop.c Mon Aug 20 22:58:32 2001 @@ -77,6 +77,12 @@ server_loop (int fd) goto repost_reply; r = (int *) rbuf = malloc (MAXIOSIZE); + if (!rbuf) + { + fprintf (stderr, "%s: Not enough memory: %s\n\n", + program_invocation_name, strerror (errno)); + exit (1); + } if (ntohl (*p++) != RPC_MSG_VERSION) { @@ -154,7 +160,15 @@ server_loop (int fd) p = process_cred (p, &cred); if (proc->need_handle) - p = lookup_cache_handle (p, &c, cred); + { + err = lookup_cache_handle (&p, &c, cred); + if (err) + { + fprintf (stderr, "%s: %s\n\n", + program_invocation_name, strerror (err)); + exit(1); + } + } else { fakec.ids = cred; @@ -169,6 +183,12 @@ server_loop (int fd) { free (rbuf); r = (int *) rbuf = malloc (amt); + if (!rbuf) + { + fprintf (stderr, "%s: Not enough memory: %s\n\n", + program_invocation_name, strerror (errno)); + exit(1); + } } } diff -rup /local/src/hurd.orig/nfsd/nfsd.h hurd/nfsd/nfsd.h --- /local/src/hurd.orig/nfsd/nfsd.h Sun Dec 20 15:51:42 1998 +++ hurd/nfsd/nfsd.h Mon Aug 20 22:49:24 2001 @@ -100,7 +100,7 @@ int *process_cred (int *, struct idspec void cred_rele (struct idspec *); void cred_ref (struct idspec *); void scan_creds (void); -int *lookup_cache_handle (int *, struct cache_handle **, struct idspec *); +error_t lookup_cache_handle (int **, struct cache_handle **, struct idspec *); void cache_handle_rele (struct cache_handle *); void scan_fhs (void); struct cache_handle *create_cached_handle (int, struct cache_handle *, file_t); diff -rup /local/src/hurd.orig/nfsd/ops.c hurd/nfsd/ops.c --- /local/src/hurd.orig/nfsd/ops.c Wed Apr 25 13:38:05 2001 +++ hurd/nfsd/ops.c Tue Aug 21 08:37:34 2001 @@ -154,6 +154,8 @@ op_lookup (struct cache_handle *c, struct stat st; decode_name (p, &name); + if (! name) + return ENOMEM; err = dir_lookup (c->port, name, O_NOTRANS, 0, &do_retry, retry_name, &newport); @@ -313,6 +315,9 @@ op_create (struct cache_handle *c, off_t size; p = decode_name (p, &name); + if (! name) + return ENOMEM; + mode = ntohl (*p++); err = dir_lookup (c->port, name, O_NOTRANS | O_CREAT | O_TRUNC, mode, @@ -377,6 +382,8 @@ op_remove (struct cache_handle *c, char *name; decode_name (p, &name); + if (! name) + return ENOMEM; err = dir_unlink (c->port, name); free (name); @@ -395,8 +402,21 @@ op_rename (struct cache_handle *fromc, error_t err = 0; p = decode_name (p, &fromname); - p = lookup_cache_handle (p, &toc, fromc->ids); + if (! fromname) + return ENOMEM; + + err = lookup_cache_handle (&p, &toc, fromc->ids); + if (err) + { + free (fromname); + return err; + } decode_name (p, &toname); + if (! toname) + { + free (fromname); + return ENOMEM; + } if (!toc) err = ESTALE; @@ -417,8 +437,12 @@ op_link (struct cache_handle *filec, char *name; error_t err = 0; - p = lookup_cache_handle (p, &dirc, filec->ids); + err = lookup_cache_handle (&p, &dirc, filec->ids); + if (err) + return err; decode_name (p, &name); + if (! name) + return ENOMEM; if (!dirc) err = ESTALE; @@ -444,6 +468,13 @@ op_symlink (struct cache_handle *c, p = decode_name (p, &name); p = decode_name (p, &target); + if (!name || !target) + { + free (name); + free (target); + return ENOMEM; + } + mode = ntohl (*p++); if (mode == -1) mode = 0777; @@ -487,6 +518,9 @@ op_mkdir (struct cache_handle *c, error_t err; p = decode_name (p, &name); + if (! name) + return ENOMEM; + mode = ntohl (*p++); err = dir_mkdir (c->port, name, mode); @@ -532,6 +566,8 @@ op_rmdir (struct cache_handle *c, error_t err; decode_name (p, &name); + if (! name) + return ENOMEM; err = dir_rmdir (c->port, name); free (name); @@ -632,6 +668,8 @@ op_mnt (struct cache_handle *c, char *name; decode_name (p, &name); + if (! name) + return ENOMEM; root = file_name_lookup (name, 0, 0); if (!root) diff -rup /local/src/hurd.orig/nfsd/xdr.c hurd/nfsd/xdr.c --- /local/src/hurd.orig/nfsd/xdr.c Wed Aug 14 14:10:19 1996 +++ hurd/nfsd/xdr.c Mon Aug 20 22:29:48 2001 @@ -21,6 +21,7 @@ #include #include #include +#include #include "nfsd.h" /* Any better ideas? */ @@ -93,7 +94,15 @@ decode_name (int *p, char **name) len = ntohl (*p++); *name = malloc (len + 1); - bcopy (p, *name, len); + if (! *name) + { + *name = NULL; + /* Return the pointer to the original pozition so this + operation could be retried. */ + return --p; + } + + memcpy (*name, p, len); (*name)[len] = '\0'; return p + INTSIZE (len); } diff -rup /local/src/hurd.orig/pfinet/ChangeLog hurd/pfinet/ChangeLog --- /local/src/hurd.orig/pfinet/ChangeLog Wed Jul 25 01:50:00 2001 +++ hurd/pfinet/ChangeLog Tue Aug 21 10:13:39 2001 @@ -1,3 +1,9 @@ +2001-08-21 Igor Khavkine + + * dummy.c (setup_dummy_device): Check return value of strdup(). + * ethernet.c (setup_ethernet_device): Likewise. + * tunnel.c (setup_tunnel_device): Likewise. + 2001-07-18 Marcus Brinkmann * linux-src/net/ipv4/devinit.c (configure_device): Initialize IFA diff -rup /local/src/hurd.orig/pfinet/dummy.c hurd/pfinet/dummy.c --- /local/src/hurd.orig/pfinet/dummy.c Tue Oct 3 21:59:03 2000 +++ hurd/pfinet/dummy.c Tue Aug 21 00:32:42 2001 @@ -92,6 +92,8 @@ setup_dummy_device (char *name, struct d *device = dev = &ddev->dev; dev->name = strdup (name); + if (!dev->name) + error (2, ENOMEM, "%s", name); dev->priv = ddev; dev->get_stats = dummy_get_stats; diff -rup /local/src/hurd.orig/pfinet/ethernet.c hurd/pfinet/ethernet.c --- /local/src/hurd.orig/pfinet/ethernet.c Thu Oct 12 01:17:52 2000 +++ hurd/pfinet/ethernet.c Tue Aug 21 00:33:25 2001 @@ -211,6 +211,9 @@ setup_ethernet_device (char *name, struc *device = dev = &edev->dev; dev->name = strdup (name); + if (!dev->name) + error (2, ENOMEM, "%s", name); + /* Functions. These ones are the true "hardware layer" in Linux. */ dev->open = 0; /* We set up before calling dev_open. */ dev->stop = ethernet_stop; diff -rup /local/src/hurd.orig/pfinet/tunnel.c hurd/pfinet/tunnel.c --- /local/src/hurd.orig/pfinet/tunnel.c Wed Apr 25 13:38:05 2001 +++ hurd/pfinet/tunnel.c Tue Aug 21 00:33:48 2001 @@ -165,6 +165,8 @@ setup_tunnel_device (char *name, struct *device = dev = &tdev->dev; dev->name = strdup (name); + if (!dev->name) + error (2, ENOMEM, "%s", name); dev->priv = tdev; dev->get_stats = tunnel_get_stats; diff -rup /local/src/hurd.orig/pflocal/ChangeLog hurd/pflocal/ChangeLog --- /local/src/hurd.orig/pflocal/ChangeLog Wed Apr 25 13:38:06 2001 +++ hurd/pflocal/ChangeLog Tue Aug 21 10:13:36 2001 @@ -1,3 +1,8 @@ +2001-08-21 Igor Khavkine + + * connq.c (connq_set_length): Check return value of realloc() and + malloc(). + 2001-03-31 Roland McGrath * sock.c: Include "connq.h" for connq_destroy decl. diff -rup /local/src/hurd.orig/pflocal/connq.c hurd/pflocal/connq.c --- /local/src/hurd.orig/pflocal/connq.c Wed Apr 25 13:38:06 2001 +++ hurd/pflocal/connq.c Tue Aug 21 00:36:52 2001 @@ -259,13 +259,25 @@ connq_set_length (struct connq *cq, int if (length > cq->length) /* Growing the queue is simple... */ - cq->queue = realloc (cq->queue, sizeof (struct connq_request *) * length); + { + cq->queue = realloc (cq->queue, sizeof (struct connq_request *) * length); + if (! cq->queue) + { + mutex_unlock (&cq->lock); + return ENOMEM; + } + } else /* Shrinking it less so. */ { int i; struct connq_request **new_queue = malloc (sizeof (struct connq_request *) * length); + if (! new_queue) + { + mutex_unlock (&cq->lock); + return ENOMEM; + } for (i = 0; i < cq->length && cq->head != cq->tail; i++) { diff -rup /local/src/hurd.orig/proc/ChangeLog hurd/proc/ChangeLog --- /local/src/hurd.orig/proc/ChangeLog Wed Jul 25 01:50:00 2001 +++ hurd/proc/ChangeLog Tue Aug 21 10:24:14 2001 @@ -1,3 +1,23 @@ +2001-08-21 Igor Khavkine + + * hash.c (task_find): Change prototype to return `error_t' + to be able to propagate errors. + * info.c (S_proc_task2pid, S_proc_task2proc): Adjusted to + new prototype of task_find(). + * main.c (main): Adjusted to new prototype of complete_proc(). + * mgt.c (S_proc_child, S_proc_reassign, S_proc_exception_raise): + Adjusted to new task_find() prototype. + * mgt.c (S_proc_getallpids): Adjusted to new add_tasks() prototype. + * mgt.c (complete_proc): Change prototype to return `error_t' + to be able to propagate errors. Check return value of malloc(). + * mgt.c (new_proc): Adjusted to new prototype of complete_proc(). + * mgt.c (add_tasks): Change prototype to return `error_t' to be + able to propagate errors. + * pgrp.c (S_proc_setsid, boot_setsid, S_proc_setpgrp): Check + return value of new_session() and new_pgrp(). + * proc.h: Change prototypes of task_find(), add_tasks() and + complete_proc(). + 2001-07-13 Marcus Brinkmann * host.c (S_proc_getexecdata): New variable PORTS_ALLOCATED. diff -rup /local/src/hurd.orig/proc/hash.c hurd/proc/hash.c --- /local/src/hurd.orig/proc/hash.c Mon Feb 3 22:10:27 1997 +++ hurd/proc/hash.c Tue Aug 21 09:16:06 2001 @@ -24,6 +24,7 @@ the Free Software Foundation, 675 Mass A #include #include #include +#include #include #include "proc.h" @@ -49,12 +50,16 @@ pid_find_allow_zombie (pid_t pid) } /* Find the process corresponding to a given task. */ -struct proc * -task_find (task_t task) +error_t +task_find (task_t task, struct proc **result) { struct proc *p; - p = ihash_find (&taskhash, task) ? : add_tasks (task); - return (!p || p->p_dead) ? 0 : p; + error_t err; + p = ihash_find (&taskhash, task); + if (!p) + err = add_tasks (task, &p); + *result = (!p || p->p_dead) ? 0 : p; + return err; } /* Find the process corresponding to a given task, but diff -rup /local/src/hurd.orig/proc/info.c hurd/proc/info.c --- /local/src/hurd.orig/proc/info.c Wed Jul 25 01:50:00 2001 +++ hurd/proc/info.c Tue Aug 21 09:17:44 2001 @@ -69,7 +69,12 @@ S_proc_task2pid (struct proc *callerp, task_t t, pid_t *pid) { - struct proc *p = task_find (t); + struct proc *p; + error_t err; + + err = task_find (t, &p); + if (err) + return err; /* No need to check CALLERP here; we don't use it. */ @@ -87,7 +92,12 @@ S_proc_task2proc (struct proc *callerp, task_t t, mach_port_t *outproc) { - struct proc *p = task_find (t); + struct proc *p; + error_t err; + + err = task_find (t, &p); + if (err) + return err; /* No need to check CALLERP here; we don't use it. */ diff -rup /local/src/hurd.orig/proc/main.c hurd/proc/main.c --- /local/src/hurd.orig/proc/main.c Wed Apr 25 13:38:22 2001 +++ hurd/proc/main.c Tue Aug 21 00:46:44 2001 @@ -87,7 +87,8 @@ main (int argc, char **argv, char **envp self_proc = allocate_proc (mach_task_self ()); assert (self_proc); - complete_proc (self_proc, 0); + err = complete_proc (self_proc, 0); + assert_perror (err); startup_port = ports_get_send_right (startup_proc); err = startup_procinit (boot, startup_port, &startup_proc->p_task, diff -rup /local/src/hurd.orig/proc/mgt.c hurd/proc/mgt.c --- /local/src/hurd.orig/proc/mgt.c Wed Apr 25 13:38:22 2001 +++ hurd/proc/mgt.c Tue Aug 21 09:19:34 2001 @@ -32,6 +32,7 @@ the Free Software Foundation, 675 Mass A #include #include #include +#include #include "proc.h" #include "process_S.h" @@ -139,11 +140,14 @@ S_proc_child (struct proc *parentp, task_t childt) { struct proc *childp; + error_t err; if (!parentp) return EOPNOTSUPP; - childp = task_find (childt); + err = task_find (childt, &childp); + if (err) + return err; if (!childp) return ESRCH; @@ -206,11 +210,14 @@ S_proc_reassign (struct proc *p, task_t newt) { struct proc *stubp; + error_t err; if (!p) return EOPNOTSUPP; - stubp = task_find (newt); + err = task_find (newt, &stubp); + if (err) + return err; if (!stubp) return ESRCH; @@ -404,7 +411,9 @@ S_proc_exception_raise (mach_port_t excp if (!e) return EOPNOTSUPP; - p = task_find (task); + err = task_find (task, &p); + if (err) + return err; if (! p) { /* Bogus RPC. */ @@ -494,6 +503,7 @@ S_proc_getallpids (struct proc *p, { int nprocs; pid_t *loc; + error_t err; void count_up (struct proc *p, void *counter) { @@ -506,7 +516,9 @@ S_proc_getallpids (struct proc *p, /* No need to check P here; we don't use it. */ - add_tasks (0); + err = add_tasks (0, NULL); + if (err) + return err; nprocs = 0; prociterate (count_up, &nprocs); @@ -625,7 +637,7 @@ proc_death_notify (struct proc *p) /* Complete a new process that has been allocated but not entirely initialized. This gets called for every process except startup_proc (PID 1). */ -void +error_t complete_proc (struct proc *p, pid_t pid) { /* Because these have a reference count of one before starting, @@ -637,6 +649,9 @@ complete_proc (struct proc *p, pid_t pid if (!nulllogin) { nulllogin = malloc (sizeof (struct login) + sizeof (nullsname) + 1); + if (! nulllogin) + return ENOMEM; + nulllogin->l_refcnt = 1; strcpy (nulllogin->l_name, nullsname); } @@ -668,6 +683,8 @@ complete_proc (struct proc *p, pid_t pid proc_death_notify (p); add_proc_to_hash (p); join_pgrp (p); + + return 0; } @@ -680,7 +697,8 @@ new_proc (task_t task) p = allocate_proc (task); if (p) - complete_proc (p, genpid ()); + if (complete_proc (p, genpid ()) != 0) + return NULL; return p; } @@ -782,15 +800,16 @@ complete_exit (struct proc *p) } /* Get the list of all tasks from the kernel and start adding them. - If we encounter TASK, then don't do any more and return its proc. - If TASK is null or we never find it, then return 0. */ -struct proc * -add_tasks (task_t task) + If we encounter TASK, then don't do any more and return its proc + in *RESULT. If TASK is null or we never find it, then return 0. */ +error_t +add_tasks (task_t task, struct proc **result) { mach_port_t *psets; u_int npsets; int i; struct proc *foundp = 0; + error_t err = 0; host_processor_sets (mach_host_self (), &psets, &npsets); for (i = 0; i < npsets; i++) @@ -819,9 +838,17 @@ add_tasks (task_t task) if (!p) { p = new_proc (tasks[j]); - set = 1; + if (p) + set = 1; + else + err = ENOMEM; } - if (!foundp && tasks[j] == task) + if (err) + /* set foundp to nonzero to finish this loop + without doing anything other the deallocating + resources. */ + foundp = (void *)-1; + if (p && tasks[j] == task) foundp = p; } if (!set) @@ -833,7 +860,15 @@ add_tasks (task_t task) mach_port_deallocate (mach_task_self (), psets[i]); } munmap (psets, npsets * sizeof (mach_port_t)); - return foundp; + + if (result) + { + if (err) + *result = NULL; + else + *result = foundp; + } + return err; } /* Allocate a new unused PID. diff -rup /local/src/hurd.orig/proc/pgrp.c hurd/proc/pgrp.c --- /local/src/hurd.orig/proc/pgrp.c Wed Apr 25 13:38:22 2001 +++ hurd/proc/pgrp.c Tue Aug 21 01:30:59 2001 @@ -106,6 +106,7 @@ kern_return_t S_proc_setsid (struct proc *p) { struct session *sess; + struct pgrp *new_pg; if (!p) return EOPNOTSUPP; @@ -113,10 +114,19 @@ S_proc_setsid (struct proc *p) if (p->p_pgrp->pg_pgid == p->p_pid || pgrp_find (p->p_pid)) return EPERM; - leave_pgrp (p); - sess = new_session (p); - p->p_pgrp= new_pgrp (p->p_pid, sess); + if (!sess) + return ENOMEM; + + new_pg = new_pgrp (p->p_pid, sess); + if (!new_pg) + { + free_session (sess); + return ENOMEM; + } + + leave_pgrp (p); + p->p_pgrp= new_pg; join_pgrp (p); return 0; @@ -129,6 +139,7 @@ boot_setsid (struct proc *p) struct session *sess; sess = new_session (p); + assert (sess); p->p_pgrp = new_pgrp (p->p_pid, sess); assert (p->p_pgrp); join_pgrp (p); @@ -340,8 +351,18 @@ S_proc_setpgrp (struct proc *callerp, if (p->p_pgrp != pg) { + struct pgrp *new_pg; + + if (pg) + new_pg = pg; + else + { + new_pg = new_pgrp (pgid, p->p_pgrp->pg_session); + if (!new_pg) + return ENOMEM; + } leave_pgrp (p); - p->p_pgrp = pg ? pg : new_pgrp (pgid, p->p_pgrp->pg_session); + p->p_pgrp = new_pg; join_pgrp (p); } else diff -rup /local/src/hurd.orig/proc/proc.h hurd/proc/proc.h --- /local/src/hurd.orig/proc/proc.h Wed Apr 25 13:38:22 2001 +++ hurd/proc/proc.h Tue Aug 21 09:19:55 2001 @@ -22,6 +22,7 @@ the Free Software Foundation, 675 Mass A #ifndef PROC_H_INCLUDED #define PROC_H_INCLUDED +#include #include #include #include @@ -178,7 +179,7 @@ void remove_exc_from_hash (struct exc *) struct exc *exc_find (mach_port_t); struct proc *pid_find (int); struct proc *pid_find_allow_zombie (int); -struct proc *task_find (task_t); +error_t task_find (task_t, struct proc **); struct proc *task_find_nocreate (task_t); struct pgrp *pgrp_find (int); struct proc *reqport_find (mach_port_t); @@ -186,13 +187,13 @@ struct session *session_find (pid_t); void exc_clean (void *); -struct proc *add_tasks (task_t); +error_t add_tasks (task_t, struct proc **); int pidfree (pid_t); struct proc *create_startup_proc (void); struct proc *allocate_proc (task_t); void proc_death_notify (struct proc *); -void complete_proc (struct proc *, pid_t); +error_t complete_proc (struct proc *, pid_t); void leave_pgrp (struct proc *); void join_pgrp (struct proc *);