From 40fd49dcdf0072e4229473f2350f0b8a1ea04a04 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Sun, 15 Apr 2001 08:10:44 +0000 Subject: 2000-04-03 Neal H Walfield * host.c: Doc fix: ``Implement foo as described in '' => ``Implement foo as described in '' * info.c: Likewise. * mgt.c: Likewise. * pgrp.c: Likewise. * wait.c: Likewise. * host.c (S_proc_setexecdata): Check for memory allocation errors. Use memcpy, not bcopy. (S_proc_getexecdata): Likewise. (S_proc_execdata_notify): Check return of malloc. (S_proc_register_version): Likewise. (initialize_version_info): Add asserts. * info.c (S_proc_pid2task): Do not bother searching for the pid if we do not have a valid caller. (S_proc_pid2proc): Likewise. Use memcpy, not bcopy. (S_proc_getprocinfo): Doc fixes. Use MAP_FAILED not -1. Use memcpy, not bcopy. (S_proc_getloginpids): Check return value of malloc. Use realloc correctly. (S_proc_setlogin): Check return value of malloc. * main.c (main): Assert allocate_proc. * mgt.c (make_ids): Check return value of malloc and fail accordingly. (S_proc_reauthenticate): Check return value of make_ids and fail accordingly. (S_proc_child): Call task_find after we know that we were passed a valid child. (S_proc_reassign): Likewise. (S_proc_handle_exceptions): Use memcpy, not bcopy. (allocate_proc): Check return value of ports_create_port and fail accordingly. (create_startup_proc): Add asserts. (complete_proc): Do not assume the length of "". * msg.c (S_proc_getmsgport): Call pid_find_allow_zombie after we know we were passed a valid caller. * pgrp.c: Include assert.h. (new_pgrp): Check return value of malloc and fail accordingly. (new_session): Likewise. (boot_setsid): Assert sess. (S_proc_getsessionpids): Use MAP_FAILED not -1. (S_proc_getsessionppids): Likewise. (S_proc_getpgrppids): Likewise. * wait.c (S_proc_wait): Use memset, not bzero. --- proc/host.c | 99 +++++++++++++++++++++++++++++++++++++++++++++------------ proc/info.c | 104 +++++++++++++++++++++++++++++++++++++----------------------- proc/pgrp.c | 33 ++++++++++++++----- proc/wait.c | 16 +++++----- 4 files changed, 176 insertions(+), 76 deletions(-) (limited to 'proc') diff --git a/proc/host.c b/proc/host.c index 8f9460cb..e34b33af 100644 --- a/proc/host.c +++ b/proc/host.c @@ -1,5 +1,5 @@ /* Proc server host management calls - Copyright (C) 1992, 1993, 1994, 1996, 1997 Free Software Foundation + Copyright (C) 1992,93,94,96,97,2001 Free Software Foundation This file is part of the GNU Hurd. @@ -32,6 +32,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include +#include #include "proc.h" #include "process_S.h" @@ -55,7 +56,7 @@ struct execdata_notify } *execdata_notifys; -/* Implement proc_getprivports as described in . */ +/* Implement proc_getprivports as described in . */ kern_return_t S_proc_getprivports (struct proc *p, mach_port_t *hostpriv, @@ -73,7 +74,7 @@ S_proc_getprivports (struct proc *p, } -/* Implement proc_setexecdata as described in . */ +/* Implement proc_setexecdata as described in . */ kern_return_t S_proc_setexecdata (struct proc *p, mach_port_t *ports, @@ -83,12 +84,26 @@ S_proc_setexecdata (struct proc *p, { int i; struct execdata_notify *n; - + mach_port_t *std_port_array_new; + int *std_int_array_new; + if (!p) return EOPNOTSUPP; if (!check_uid (p, 0)) return EPERM; + + /* Allocate memory up front. */ + std_port_array_new = malloc (sizeof (mach_port_t) * nports); + if (! std_port_array_new) + return ENOMEM; + + std_int_array_new = malloc (sizeof (int) * nints); + if (! std_int_array_new) + { + free (std_port_array_new); + return ENOMEM; + } if (std_port_array) { @@ -99,13 +114,13 @@ S_proc_setexecdata (struct proc *p, if (std_int_array) free (std_int_array); - std_port_array = malloc (sizeof (mach_port_t) * nports); + std_port_array = std_port_array_new; n_std_ports = nports; - bcopy (ports, std_port_array, sizeof (mach_port_t) * nports); + memcpy (std_port_array, ports, sizeof (mach_port_t) * nports); - std_int_array = malloc (sizeof (int) * nints); + std_int_array = std_int_array_new; n_std_ints = nints; - bcopy (ints, std_int_array, sizeof (int) * nints); + memcpy (std_int_array, ints, sizeof (int) * nints); for (n = execdata_notifys; n; n = n->next) exec_setexecdata (n->notify_port, std_port_array, MACH_MSG_TYPE_COPY_SEND, @@ -114,7 +129,7 @@ S_proc_setexecdata (struct proc *p, return 0; } -/* Implement proc_getexecdata as described in . */ +/* Implement proc_getexecdata as described in . */ kern_return_t S_proc_getexecdata (struct proc *p, mach_port_t **ports, @@ -125,34 +140,46 @@ S_proc_getexecdata (struct proc *p, { /* No need to check P here; we don't use it. */ - /* XXX memory leak here */ - if (!std_port_array) return ENOENT; if (*nports < n_std_ports) - *ports = malloc (n_std_ports * sizeof (mach_port_t)); - bcopy (std_port_array, *ports, n_std_ports * sizeof (mach_port_t)); + { + *ports = mmap (0, round_page (n_std_ports * sizeof (mach_port_t)), + PROT_READ|PROT_WRITE, MAP_ANON, 0, 0); + if (*ports == MAP_FAILED) + return ENOMEM; + } + memcpy (*ports, std_port_array, n_std_ports * sizeof (mach_port_t)); *nports = n_std_ports; if (*nints < n_std_ints) - *ints = malloc (n_std_ints * sizeof (mach_port_t)); - bcopy (std_int_array, *ints, n_std_ints * sizeof (int)); + { + *ints = mmap (0, round_page (n_std_ints * sizeof (int)), + PROT_READ|PROT_WRITE, MAP_ANON, 0, 0); + if (*ints == MAP_FAILED) + return ENOMEM; + } + memcpy (*ints, std_int_array, n_std_ints * sizeof (int)); *nints = n_std_ints; return 0; } -/* Implement proc_execdata_notify as described in . */ +/* Implement proc_execdata_notify as described in . */ kern_return_t S_proc_execdata_notify (struct proc *p, mach_port_t notify) { - struct execdata_notify *n = malloc (sizeof (struct execdata_notify)); + struct execdata_notify *n; mach_port_t foo; /* No need to check P here; we don't use it. */ + n = malloc (sizeof (struct execdata_notify)); + if (! n) + return ENOMEM; + n->notify_port = notify; n->next = execdata_notifys; execdata_notifys = n; @@ -327,6 +354,7 @@ initialize_version_info (void) /* Notice Mach's and our own version and initialize server version varables. */ server_versions = malloc (sizeof (struct server_version) * 10); + assert (server_versions); server_versions_nalloc = 10; err = host_kernel_version (mach_host_self (), kv); @@ -338,10 +366,14 @@ initialize_version_info (void) if (p) *p = '\0'; kernel_name = strdup (p ? kv : "mach"); + assert (kernel_name); kernel_version = strdup (p ? p + 1 : kv); + assert (kernel_version); server_versions[0].name = strdup ("proc"); + assert (server_versions[0].name); server_versions[0].version = strdup (HURD_VERSION); + assert (server_versions[0].version); nserver_versions = 1; @@ -366,6 +398,7 @@ S_proc_register_version (pstruct_t server, char *release, char *version) { + error_t err = 0; int i; /* No need to check SERVER here; we don't use it. */ @@ -380,6 +413,11 @@ S_proc_register_version (pstruct_t server, /* Change this entry. */ free (server_versions[i].version); server_versions[i].version = malloc (strlen (version) + 1); + if (! server_versions[i].version) + { + err = ENOMEM; + goto out; + } strcpy (server_versions[i].version, version); break; } @@ -388,21 +426,40 @@ S_proc_register_version (pstruct_t server, /* Didn't find it; extend. */ if (nserver_versions == server_versions_nalloc) { + void *new = realloc (server_versions, + sizeof (struct server_version) * + server_versions_nalloc * 2); + if (! new) + { + err = ENOMEM; + goto out; + } + server_versions_nalloc *= 2; - server_versions = realloc (server_versions, - sizeof (struct server_version) * - server_versions_nalloc); + server_versions = new; } server_versions[nserver_versions].name = malloc (strlen (name) + 1); + if (! server_versions[nserver_versions].name) + { + err = ENOMEM; + goto out; + } server_versions[nserver_versions].version = malloc (strlen (version) + 1); + if (! server_versions[nserver_versions].version) + { + free (server_versions[nserver_versions].name); + err = ENOMEM; + goto out; + } strcpy (server_versions[nserver_versions].name, name); strcpy (server_versions[nserver_versions].version, version); nserver_versions++; } rebuild_uname (); +out: mach_port_deallocate (mach_task_self (), credential); - return 0; + return err; } diff --git a/proc/info.c b/proc/info.c index 2855adef..01f01036 100644 --- a/proc/info.c +++ b/proc/info.c @@ -1,5 +1,5 @@ /* Process information queries - Copyright (C) 1992,93,94,95,96,99,2000 Free Software Foundation, Inc. + Copyright (C) 1992,93,94,95,96,99,2000,01 Free Software Foundation, Inc. This file is part of the GNU Hurd. @@ -33,17 +33,18 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "proc.h" #include "process_S.h" -/* Implement S_proc_pid2task as described in . */ +/* Implement S_proc_pid2task as described in . */ kern_return_t S_proc_pid2task (struct proc *callerp, - pid_t pid, - task_t *t) + pid_t pid, + task_t *t) { - struct proc *p = pid_find_allow_zombie (pid); - + struct proc *p; + if (!callerp) return EOPNOTSUPP; + p = pid_find_allow_zombie (pid); if (!p) return ESRCH; @@ -62,11 +63,11 @@ S_proc_pid2task (struct proc *callerp, return 0; } -/* Implement proc_task2pid as described in . */ +/* Implement proc_task2pid as described in . */ kern_return_t S_proc_task2pid (struct proc *callerp, - task_t t, - pid_t *pid) + task_t t, + pid_t *pid) { struct proc *p = task_find (t); @@ -80,11 +81,11 @@ S_proc_task2pid (struct proc *callerp, return 0; } -/* Implement proc_task2proc as described in . */ +/* Implement proc_task2proc as described in . */ kern_return_t S_proc_task2proc (struct proc *callerp, - task_t t, - mach_port_t *outproc) + task_t t, + mach_port_t *outproc) { struct proc *p = task_find (t); @@ -98,10 +99,10 @@ S_proc_task2proc (struct proc *callerp, return 0; } -/* Implement proc_proc2task as described in . */ +/* Implement proc_proc2task as described in . */ kern_return_t S_proc_proc2task (struct proc *p, - task_t *t) + task_t *t) { if (!p) return EOPNOTSUPP; @@ -109,17 +110,18 @@ S_proc_proc2task (struct proc *p, return 0; } -/* Implement proc_pid2proc as described in . */ +/* Implement proc_pid2proc as described in . */ kern_return_t S_proc_pid2proc (struct proc *callerp, - pid_t pid, - mach_port_t *outproc) + pid_t pid, + mach_port_t *outproc) { - struct proc *p = pid_find_allow_zombie (pid); + struct proc *p; if (!callerp) return EOPNOTSUPP; + p = pid_find_allow_zombie (pid); if (!p) return ESRCH; @@ -225,7 +227,7 @@ get_vector (task_t task, if (*vec == NULL) err = ENOMEM; else - bcopy ((char *)(data + (addr - readaddr)), *vec, + memcpy (*vec, (char *)(data + (addr - readaddr)), (char *)t - (char *)(data + (addr - readaddr))); break; } @@ -313,7 +315,7 @@ get_string_array (task_t t, } -/* Implement proc_getprocargs as described in . */ +/* Implement proc_getprocargs as described in . */ kern_return_t S_proc_getprocargs (struct proc *callerp, pid_t pid, @@ -330,7 +332,7 @@ S_proc_getprocargs (struct proc *callerp, return get_string_array (p->p_task, p->p_argv, (vm_address_t *) buf, buflen); } -/* Implement proc_getprocenv as described in . */ +/* Implement proc_getprocenv as described in . */ kern_return_t S_proc_getprocenv (struct proc *callerp, pid_t pid, @@ -351,7 +353,7 @@ S_proc_getprocenv (struct proc *callerp, #define PI_FETCH_THREAD_DETAILS \ (PI_FETCH_THREAD_SCHED | PI_FETCH_THREAD_BASIC | PI_FETCH_THREAD_WAITS) -/* Implement proc_getprocinfo as described in . */ +/* Implement proc_getprocinfo as described in . */ kern_return_t S_proc_getprocinfo (struct proc *callerp, pid_t pid, @@ -406,6 +408,8 @@ S_proc_getprocinfo (struct proc *callerp, if (structsize / sizeof (int) > *piarraylen) { *piarray = mmap (0, structsize, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0); + if (*piarray == MAP_FAILED) + return errno; pi_alloced = 1; } *piarraylen = structsize / sizeof (int); @@ -489,15 +493,15 @@ S_proc_getprocinfo (struct proc *callerp, continue; } if (err) - /* Something screwy, give up o nthis bit of info. */ + /* Something screwy, give up on this bit of info. */ { *flags &= ~PI_FETCH_THREAD_SCHED; err = 0; } } - /* Note that there are thread wait entries only for threads not marked - dead. */ + /* Note that there are thread wait entries only for those threads + not marked dead. */ if (*flags & PI_FETCH_THREAD_WAITS) { @@ -526,14 +530,14 @@ S_proc_getprocinfo (struct proc *callerp, new_waits = mmap (0, new_len, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0); - err = (new_waits == (char *) -1) ? errno : 0; + err = (new_waits == MAP_FAILED) ? errno : 0; if (err) /* Just don't return any more waits information. */ *flags &= ~PI_FETCH_THREAD_WAITS; else { if (waits_used > 0) - bcopy (*waits, new_waits, waits_used); + memcpy (new_waits, *waits, waits_used); if (*waits_len > 0 && waits_alloced) munmap (*waits, *waits_len); *waits = new_waits; @@ -545,7 +549,7 @@ S_proc_getprocinfo (struct proc *callerp, if (waits_used + desc_len + 1 <= *waits_len) /* Append DESC to WAITS. */ { - bcopy (desc, *waits + waits_used, desc_len); + memcpy (*waits + waits_used, desc, desc_len); waits_used += desc_len; (*waits)[waits_used++] = '\0'; } @@ -608,6 +612,7 @@ S_proc_getloginpids (struct proc *callerp, pid_t **pids, u_int *npids) { + error_t err = 0; struct proc *l = pid_find (id); struct proc *p; struct proc **tail, **new, **parray; @@ -622,6 +627,9 @@ S_proc_getloginpids (struct proc *callerp, /* Simple breadth first search of the children of L. */ parraysize = 50; parray = malloc (sizeof (struct proc *) * parraysize); + if (! parray) + return ENOMEM; + parray[0] = l; for (tail = parray, new = &parray[1]; tail != new; tail++) { @@ -634,6 +642,12 @@ S_proc_getloginpids (struct proc *callerp, struct proc **newparray; newparray = realloc (parray, ((parraysize *= 2) * sizeof (struct proc *))); + if (! newparray) + { + free (parray); + return ENOMEM; + } + tail = newparray + (tail - parray); new = newparray + (new - parray); parray = newparray; @@ -643,19 +657,28 @@ S_proc_getloginpids (struct proc *callerp, } if (*npids < new - parray) - *pids = mmap (0, (new - parray) * sizeof (pid_t), PROT_READ|PROT_WRITE, - MAP_ANON, 0, 0); - *npids = new - parray; - for (i = 0; i < *npids; i++) - (*pids)[i] = parray[i]->p_pid; + { + *pids = mmap (0, (new - parray) * sizeof (pid_t), PROT_READ|PROT_WRITE, + MAP_ANON, 0, 0); + if (*pids == MAP_FAILED) + err = errno; + } + + if (! err) + { + *npids = new - parray; + for (i = 0; i < *npids; i++) + (*pids)[i] = parray[i]->p_pid; + } + free (parray); - return 0; + return err; } -/* Implement proc_setlogin as described in . */ +/* Implement proc_setlogin as described in . */ kern_return_t S_proc_setlogin (struct proc *p, - char *login) + char *login) { struct login *l; @@ -666,6 +689,9 @@ S_proc_setlogin (struct proc *p, return EPERM; l = malloc (sizeof (struct login) + strlen (login) + 1); + if (! l) + return ENOMEM; + l->l_refcnt = 1; strcpy (l->l_name, login); if (!--p->p_login->l_refcnt) @@ -674,10 +700,10 @@ S_proc_setlogin (struct proc *p, return 0; } -/* Implement proc_getlogin as described in . */ +/* Implement proc_getlogin as described in . */ kern_return_t S_proc_getlogin (struct proc *p, - char *login) + char *login) { if (!p) return EOPNOTSUPP; @@ -685,7 +711,7 @@ S_proc_getlogin (struct proc *p, return 0; } -/* Implement proc_get_tty as described in . */ +/* Implement proc_get_tty as described in . */ kern_return_t S_proc_get_tty (struct proc *p, pid_t pid, mach_port_t *tty, mach_msg_type_name_t *tty_type) diff --git a/proc/pgrp.c b/proc/pgrp.c index ecd4b6e3..665a3472 100644 --- a/proc/pgrp.c +++ b/proc/pgrp.c @@ -1,5 +1,5 @@ /* Session and process group manipulation - Copyright (C) 1992, 1993, 1994, 1995, 1996, 1999 Free Software Foundation, Inc. + Copyright (C) 1992,93,94,95,96,99,2001 Free Software Foundation, Inc. This file is part of the GNU Hurd. @@ -25,6 +25,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include +#include #include "proc.h" #include "process_S.h" @@ -39,6 +40,9 @@ new_pgrp (pid_t pgid, struct pgrp *pg; pg = malloc (sizeof (struct pgrp)); + if (! pg) + return NULL; + pg->pg_plist = 0; pg->pg_pgid = pgid; pg->pg_orphcnt = 0; @@ -61,6 +65,9 @@ new_session (struct proc *p) struct session *sess; sess = malloc (sizeof (struct session)); + if (! sess) + return NULL; + sess->s_sid = p->p_pid; sess->s_pgrps = 0; sess->s_sessionid = MACH_PORT_NULL; @@ -94,7 +101,7 @@ free_pgrp (struct pgrp *pg) free (pg); } -/* Implement proc_setsid as described in . */ +/* Implement proc_setsid as described in . */ kern_return_t S_proc_setsid (struct proc *p) { @@ -123,11 +130,12 @@ boot_setsid (struct proc *p) sess = new_session (p); p->p_pgrp = new_pgrp (p->p_pid, sess); + assert (p->p_pgrp); join_pgrp (p); return; } -/* Implement proc_getsid as described in . */ +/* Implement proc_getsid as described in . */ kern_return_t S_proc_getsid (struct proc *callerp, pid_t pid, @@ -143,7 +151,7 @@ S_proc_getsid (struct proc *callerp, return 0; } -/* Implement proc_getsessionpids as described in . */ +/* Implement proc_getsessionpids as described in . */ kern_return_t S_proc_getsessionpids (struct proc *callerp, pid_t sid, @@ -176,6 +184,9 @@ S_proc_getsessionpids (struct proc *callerp, { *pids = mmap (0, count * sizeof (pid_t), PROT_READ|PROT_WRITE, MAP_ANON, 0, 0); + if (*pids == MAP_FAILED) + return errno; + pp = *pids; for (pg = s->s_pgrps; pg; pg = pg->pg_next) for (p = pg->pg_plist; p; p = p->p_gnext) @@ -216,6 +227,9 @@ S_proc_getsessionpgids (struct proc *callerp, { *pgids = mmap (0, count * sizeof (pid_t), PROT_READ|PROT_WRITE, MAP_ANON, 0, 0); + if (*pgids == MAP_FAILED) + return errno; + pp = *pgids; for (pg = s->s_pgrps; pg; pg = pg->pg_next) *pp++ = pg->pg_pgid; @@ -259,6 +273,9 @@ S_proc_getpgrppids (struct proc *callerp, { *pids = mmap (0, count * sizeof (pid_t), PROT_READ|PROT_WRITE, MAP_ANON, 0, 0); + if (*pids == MAP_FAILED) + return errno; + pp = *pids; for (p = pg->pg_plist; p; p = p->p_gnext) *pp++ = p->p_pid; @@ -268,7 +285,7 @@ S_proc_getpgrppids (struct proc *callerp, return 0; } -/* Implement proc_getsidport as described in . */ +/* Implement proc_getsidport as described in . */ kern_return_t S_proc_getsidport (struct proc *p, mach_port_t *sessport, mach_msg_type_name_t *sessport_type) @@ -291,7 +308,7 @@ S_proc_getsidport (struct proc *p, return err; } -/* Implement proc_setpgrp as described in . */ +/* Implement proc_setpgrp as described in . */ kern_return_t S_proc_setpgrp (struct proc *callerp, pid_t pid, @@ -334,7 +351,7 @@ S_proc_setpgrp (struct proc *callerp, return 0; } -/* Implement proc_getpgrp as described in . */ +/* Implement proc_getpgrp as described in . */ kern_return_t S_proc_getpgrp (struct proc *callerp, pid_t pid, @@ -353,7 +370,7 @@ S_proc_getpgrp (struct proc *callerp, return 0; } -/* Implement proc_mark_exec as described in . */ +/* Implement proc_mark_exec as described in . */ kern_return_t S_proc_mark_exec (struct proc *p) { diff --git a/proc/wait.c b/proc/wait.c index 60ec58ff..06aa594b 100644 --- a/proc/wait.c +++ b/proc/wait.c @@ -1,5 +1,5 @@ /* Implementation of wait - Copyright (C) 1994, 1995, 1996 Free Software Foundation + Copyright (C) 1994, 1995, 1996, 2001 Free Software Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -113,7 +113,7 @@ S_proc_wait (struct proc *p, *sigcode = child->p_sigcode; if (child->p_dead) complete_exit (child); - bzero (ru, sizeof (struct rusage)); + memset (ru, 0, sizeof (struct rusage)); *pid_status = pid; return 0; } @@ -136,7 +136,7 @@ S_proc_wait (struct proc *p, *pid_status = child->p_pid; if (child->p_dead) complete_exit (child); - bzero (ru, sizeof (struct rusage)); + memset (ru, 0, sizeof (struct rusage)); return 0; } } @@ -157,7 +157,7 @@ S_proc_wait (struct proc *p, goto start_over; } -/* Implement proc_mark_stop as described in . */ +/* Implement proc_mark_stop as described in . */ kern_return_t S_proc_mark_stop (struct proc *p, int signo, @@ -183,7 +183,7 @@ S_proc_mark_stop (struct proc *p, return 0; } -/* Implement proc_mark_exit as described in . */ +/* Implement proc_mark_exit as described in . */ kern_return_t S_proc_mark_exit (struct proc *p, int status, @@ -201,7 +201,7 @@ S_proc_mark_exit (struct proc *p, return 0; } -/* Implement proc_mark_cont as described in . */ +/* Implement proc_mark_cont as described in . */ kern_return_t S_proc_mark_cont (struct proc *p) { @@ -211,7 +211,7 @@ S_proc_mark_cont (struct proc *p) return 0; } -/* Implement proc_mark_traced as described in . */ +/* Implement proc_mark_traced as described in . */ kern_return_t S_proc_mark_traced (struct proc *p) { @@ -221,7 +221,7 @@ S_proc_mark_traced (struct proc *p) return 0; } -/* Implement proc_mark_nostopchild as described in . */ +/* Implement proc_mark_nostopchild as described in . */ kern_return_t S_proc_mod_stopchild (struct proc *p, int value) -- cgit v1.2.3