37 #include <fcntl.h>
38 #include <string.h>
39 #include <strings.h>
40 #include <memory.h>
41 #include <errno.h>
42 #include <dirent.h>
43 #include <limits.h>
44 #include <signal.h>
45 #include <atomic.h>
46 #include <zone.h>
47 #include <sys/types.h>
48 #include <sys/uio.h>
49 #include <sys/stat.h>
50 #include <sys/resource.h>
51 #include <sys/param.h>
52 #include <sys/stack.h>
53 #include <sys/fault.h>
54 #include <sys/syscall.h>
55 #include <sys/sysmacros.h>
56 #include <sys/systeminfo.h>
57
58 #include "libproc.h"
59 #include "Pcontrol.h"
60 #include "Putil.h"
61 #include "P32ton.h"
62
63 int _libproc_debug; /* set non-zero to enable debugging printfs */
64 int _libproc_no_qsort; /* set non-zero to inhibit sorting */
65 /* of symbol tables */
66 int _libproc_incore_elf; /* only use in-core elf data */
67
68 sigset_t blockable_sigs; /* signals to block when we need to be safe */
69 static int minfd; /* minimum file descriptor returned by dupfd(fd, 0) */
70 char procfs_path[PATH_MAX] = "/proc";
71
72 /*
73 * Function prototypes for static routines in this module.
74 */
75 static void deadcheck(struct ps_prochandle *);
76 static void restore_tracing_flags(struct ps_prochandle *);
159 free(auxv);
160 } else {
161 auxv[naux].a_type = AT_NULL;
162 auxv[naux].a_un.a_val = 0L;
163
164 *auxvp = auxv;
165 *nauxp = (int)naux;
166 }
167 }
168
169 (void) close(fd);
170 }
171
172 /*ARGSUSED*/
173 static int
174 Pcred_live(struct ps_prochandle *P, prcred_t *pcrp, int ngroups, void *data)
175 {
176 return (proc_get_cred(P->pid, pcrp, ngroups));
177 }
178
179 /*ARGSUSED*/
180 static int
181 Ppriv_live(struct ps_prochandle *P, prpriv_t **pprv, void *data)
182 {
183 prpriv_t *pp;
184
185 pp = proc_get_priv(P->pid);
186 if (pp == NULL) {
187 return (-1);
188 }
189
190 *pprv = pp;
191 return (0);
192 }
193
194 /*ARGSUSED*/
195 static const psinfo_t *
196 Ppsinfo_live(struct ps_prochandle *P, psinfo_t *psinfo, void *data)
197 {
198 if (proc_get_psinfo(P->pid, psinfo) == -1)
309 Pldt_live(struct ps_prochandle *P, struct ssd *pldt, int nldt, void *data)
310 {
311 return (proc_get_ldt(P->pid, pldt, nldt));
312 }
313 #endif
314
315 static const ps_ops_t P_live_ops = {
316 .pop_pread = Pread_live,
317 .pop_pwrite = Pwrite_live,
318 .pop_read_maps = Pread_maps_live,
319 .pop_read_aux = Pread_aux_live,
320 .pop_cred = Pcred_live,
321 .pop_priv = Ppriv_live,
322 .pop_psinfo = Ppsinfo_live,
323 .pop_lstatus = Plstatus_live,
324 .pop_lpsinfo = Plpsinfo_live,
325 .pop_platform = Pplatform_live,
326 .pop_uname = Puname_live,
327 .pop_zonename = Pzonename_live,
328 .pop_execname = Pexecname_live,
329 #if defined(__i386) || defined(__amd64)
330 .pop_ldt = Pldt_live
331 #endif
332 };
333
334 /*
335 * This is the library's .init handler.
336 */
337 #pragma init(_libproc_init)
338 void
339 _libproc_init(void)
340 {
341 _libproc_debug = getenv("LIBPROC_DEBUG") != NULL;
342 _libproc_no_qsort = getenv("LIBPROC_NO_QSORT") != NULL;
343 _libproc_incore_elf = getenv("LIBPROC_INCORE_ELF") != NULL;
344
345 (void) sigfillset(&blockable_sigs);
346 (void) sigdelset(&blockable_sigs, SIGKILL);
347 (void) sigdelset(&blockable_sigs, SIGSTOP);
348 }
1276 }
1277
1278 static void
1279 Pread_status(struct ps_prochandle *P)
1280 {
1281 P->ops.pop_status(P, &P->status, P->data);
1282 }
1283
1284 /*
1285 * Fill in a pointer to a process credentials structure. The ngroups parameter
1286 * is the number of supplementary group entries allocated in the caller's cred
1287 * structure. It should equal zero or one unless extra space has been
1288 * allocated for the group list by the caller.
1289 */
1290 int
1291 Pcred(struct ps_prochandle *P, prcred_t *pcrp, int ngroups)
1292 {
1293 return (P->ops.pop_cred(P, pcrp, ngroups, P->data));
1294 }
1295
1296 static prheader_t *
1297 Plstatus(struct ps_prochandle *P)
1298 {
1299 return (P->ops.pop_lstatus(P, P->data));
1300 }
1301
1302 static prheader_t *
1303 Plpsinfo(struct ps_prochandle *P)
1304 {
1305 return (P->ops.pop_lpsinfo(P, P->data));
1306 }
1307
1308
1309 #if defined(__i386) || defined(__amd64)
1310 /*
1311 * Fill in a pointer to a process LDT structure.
1312 * The caller provides a buffer of size 'nldt * sizeof (struct ssd)';
1313 * If pldt == NULL or nldt == 0, we return the number of existing LDT entries.
1314 * Otherwise we return the actual number of LDT entries fetched (<= nldt).
1315 */
|
37 #include <fcntl.h>
38 #include <string.h>
39 #include <strings.h>
40 #include <memory.h>
41 #include <errno.h>
42 #include <dirent.h>
43 #include <limits.h>
44 #include <signal.h>
45 #include <atomic.h>
46 #include <zone.h>
47 #include <sys/types.h>
48 #include <sys/uio.h>
49 #include <sys/stat.h>
50 #include <sys/resource.h>
51 #include <sys/param.h>
52 #include <sys/stack.h>
53 #include <sys/fault.h>
54 #include <sys/syscall.h>
55 #include <sys/sysmacros.h>
56 #include <sys/systeminfo.h>
57 #include <sys/secflags.h>
58
59 #include "libproc.h"
60 #include "Pcontrol.h"
61 #include "Putil.h"
62 #include "P32ton.h"
63
64 int _libproc_debug; /* set non-zero to enable debugging printfs */
65 int _libproc_no_qsort; /* set non-zero to inhibit sorting */
66 /* of symbol tables */
67 int _libproc_incore_elf; /* only use in-core elf data */
68
69 sigset_t blockable_sigs; /* signals to block when we need to be safe */
70 static int minfd; /* minimum file descriptor returned by dupfd(fd, 0) */
71 char procfs_path[PATH_MAX] = "/proc";
72
73 /*
74 * Function prototypes for static routines in this module.
75 */
76 static void deadcheck(struct ps_prochandle *);
77 static void restore_tracing_flags(struct ps_prochandle *);
160 free(auxv);
161 } else {
162 auxv[naux].a_type = AT_NULL;
163 auxv[naux].a_un.a_val = 0L;
164
165 *auxvp = auxv;
166 *nauxp = (int)naux;
167 }
168 }
169
170 (void) close(fd);
171 }
172
173 /*ARGSUSED*/
174 static int
175 Pcred_live(struct ps_prochandle *P, prcred_t *pcrp, int ngroups, void *data)
176 {
177 return (proc_get_cred(P->pid, pcrp, ngroups));
178 }
179
180 /* ARGSUSED */
181 static int
182 Psecflags_live(struct ps_prochandle *P, prsecflags_t **psf, void *data)
183 {
184 return (proc_get_secflags(P->pid, psf));
185 }
186
187 /*ARGSUSED*/
188 static int
189 Ppriv_live(struct ps_prochandle *P, prpriv_t **pprv, void *data)
190 {
191 prpriv_t *pp;
192
193 pp = proc_get_priv(P->pid);
194 if (pp == NULL) {
195 return (-1);
196 }
197
198 *pprv = pp;
199 return (0);
200 }
201
202 /*ARGSUSED*/
203 static const psinfo_t *
204 Ppsinfo_live(struct ps_prochandle *P, psinfo_t *psinfo, void *data)
205 {
206 if (proc_get_psinfo(P->pid, psinfo) == -1)
317 Pldt_live(struct ps_prochandle *P, struct ssd *pldt, int nldt, void *data)
318 {
319 return (proc_get_ldt(P->pid, pldt, nldt));
320 }
321 #endif
322
323 static const ps_ops_t P_live_ops = {
324 .pop_pread = Pread_live,
325 .pop_pwrite = Pwrite_live,
326 .pop_read_maps = Pread_maps_live,
327 .pop_read_aux = Pread_aux_live,
328 .pop_cred = Pcred_live,
329 .pop_priv = Ppriv_live,
330 .pop_psinfo = Ppsinfo_live,
331 .pop_lstatus = Plstatus_live,
332 .pop_lpsinfo = Plpsinfo_live,
333 .pop_platform = Pplatform_live,
334 .pop_uname = Puname_live,
335 .pop_zonename = Pzonename_live,
336 .pop_execname = Pexecname_live,
337 .pop_secflags = Psecflags_live,
338 #if defined(__i386) || defined(__amd64)
339 .pop_ldt = Pldt_live
340 #endif
341 };
342
343 /*
344 * This is the library's .init handler.
345 */
346 #pragma init(_libproc_init)
347 void
348 _libproc_init(void)
349 {
350 _libproc_debug = getenv("LIBPROC_DEBUG") != NULL;
351 _libproc_no_qsort = getenv("LIBPROC_NO_QSORT") != NULL;
352 _libproc_incore_elf = getenv("LIBPROC_INCORE_ELF") != NULL;
353
354 (void) sigfillset(&blockable_sigs);
355 (void) sigdelset(&blockable_sigs, SIGKILL);
356 (void) sigdelset(&blockable_sigs, SIGSTOP);
357 }
1285 }
1286
1287 static void
1288 Pread_status(struct ps_prochandle *P)
1289 {
1290 P->ops.pop_status(P, &P->status, P->data);
1291 }
1292
1293 /*
1294 * Fill in a pointer to a process credentials structure. The ngroups parameter
1295 * is the number of supplementary group entries allocated in the caller's cred
1296 * structure. It should equal zero or one unless extra space has been
1297 * allocated for the group list by the caller.
1298 */
1299 int
1300 Pcred(struct ps_prochandle *P, prcred_t *pcrp, int ngroups)
1301 {
1302 return (P->ops.pop_cred(P, pcrp, ngroups, P->data));
1303 }
1304
1305 /* Return an allocated prsecflags_t */
1306 int
1307 Psecflags(struct ps_prochandle *P, prsecflags_t **psf)
1308 {
1309 int ret;
1310
1311 if ((ret = P->ops.pop_secflags(P, psf, P->data)) == 0) {
1312 if ((*psf)->pr_version != PRSECFLAGS_VERSION_1) {
1313 errno = EINVAL;
1314 return (-1);
1315 }
1316 }
1317
1318 return (ret);
1319 }
1320
1321 void
1322 Psecflags_free(prsecflags_t *psf)
1323 {
1324 free(psf);
1325 }
1326
1327 static prheader_t *
1328 Plstatus(struct ps_prochandle *P)
1329 {
1330 return (P->ops.pop_lstatus(P, P->data));
1331 }
1332
1333 static prheader_t *
1334 Plpsinfo(struct ps_prochandle *P)
1335 {
1336 return (P->ops.pop_lpsinfo(P, P->data));
1337 }
1338
1339
1340 #if defined(__i386) || defined(__amd64)
1341 /*
1342 * Fill in a pointer to a process LDT structure.
1343 * The caller provides a buffer of size 'nldt * sizeof (struct ssd)';
1344 * If pldt == NULL or nldt == 0, we return the number of existing LDT entries.
1345 * Otherwise we return the actual number of LDT entries fetched (<= nldt).
1346 */
|