11de7b4b8SPedro F. Giffuni /*-
21de7b4b8SPedro F. Giffuni * SPDX-License-Identifier: BSD-3-Clause
31de7b4b8SPedro F. Giffuni *
455e2cb41SEdwin Groothuis * Copyright (c) 1994 SigmaSoft, Th. Lockert <tholo@sigmasoft.com>
555e2cb41SEdwin Groothuis * All rights reserved.
655e2cb41SEdwin Groothuis *
755e2cb41SEdwin Groothuis * Redistribution and use in source and binary forms, with or without
855e2cb41SEdwin Groothuis * modification, are permitted provided that the following conditions
955e2cb41SEdwin Groothuis * are met:
1055e2cb41SEdwin Groothuis * 1. Redistributions of source code must retain the above copyright
1155e2cb41SEdwin Groothuis * notice, this list of conditions and the following disclaimer.
1255e2cb41SEdwin Groothuis * 2. Redistributions in binary form must reproduce the above copyright
1355e2cb41SEdwin Groothuis * notice, this list of conditions and the following disclaimer in the
1455e2cb41SEdwin Groothuis * documentation and/or other materials provided with the distribution.
1555e2cb41SEdwin Groothuis * 3. The name of the author may not be used to endorse or promote products
1655e2cb41SEdwin Groothuis * derived from this software without specific prior written permission.
1755e2cb41SEdwin Groothuis *
1855e2cb41SEdwin Groothuis * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
1955e2cb41SEdwin Groothuis * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
2055e2cb41SEdwin Groothuis * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
2155e2cb41SEdwin Groothuis * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
2255e2cb41SEdwin Groothuis * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
2355e2cb41SEdwin Groothuis * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
2455e2cb41SEdwin Groothuis * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
2555e2cb41SEdwin Groothuis * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
2655e2cb41SEdwin Groothuis * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
2755e2cb41SEdwin Groothuis * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2855e2cb41SEdwin Groothuis *
29487ac9acSUlrich Spörlein * The split of ipcs.c into ipcs.c and ipc.c to accommodate the
3055e2cb41SEdwin Groothuis * changes in ipcrm.c was done by Edwin Groothuis <edwin@FreeBSD.org>
3155e2cb41SEdwin Groothuis */
3255e2cb41SEdwin Groothuis
3355e2cb41SEdwin Groothuis #include <sys/types.h>
3455e2cb41SEdwin Groothuis #include <sys/sysctl.h>
35*ab4a4d40SLi-Wen Hsu #define _WANT_SYSVMSG_INTERNALS
3655e2cb41SEdwin Groothuis #include <sys/msg.h>
37*ab4a4d40SLi-Wen Hsu #define _WANT_SYSVSEM_INTERNALS
38*ab4a4d40SLi-Wen Hsu #include <sys/sem.h>
39*ab4a4d40SLi-Wen Hsu #define _WANT_SYSVSHM_INTERNALS
40*ab4a4d40SLi-Wen Hsu #include <sys/shm.h>
4155e2cb41SEdwin Groothuis
4255e2cb41SEdwin Groothuis #include <assert.h>
4355e2cb41SEdwin Groothuis #include <err.h>
4455e2cb41SEdwin Groothuis #include <kvm.h>
4555e2cb41SEdwin Groothuis #include <nlist.h>
4655e2cb41SEdwin Groothuis #include <stddef.h>
4755e2cb41SEdwin Groothuis
4855e2cb41SEdwin Groothuis #include "ipc.h"
4955e2cb41SEdwin Groothuis
5055e2cb41SEdwin Groothuis int use_sysctl = 1;
5155e2cb41SEdwin Groothuis struct semid_kernel *sema;
5255e2cb41SEdwin Groothuis struct seminfo seminfo;
5355e2cb41SEdwin Groothuis struct msginfo msginfo;
5455e2cb41SEdwin Groothuis struct msqid_kernel *msqids;
5555e2cb41SEdwin Groothuis struct shminfo shminfo;
5655e2cb41SEdwin Groothuis struct shmid_kernel *shmsegs;
5755e2cb41SEdwin Groothuis
5855e2cb41SEdwin Groothuis struct nlist symbols[] = {
5911f4012fSEitan Adler { .n_name = "sema" },
6011f4012fSEitan Adler { .n_name = "seminfo" },
6111f4012fSEitan Adler { .n_name = "msginfo" },
6211f4012fSEitan Adler { .n_name = "msqids" },
6311f4012fSEitan Adler { .n_name = "shminfo" },
6411f4012fSEitan Adler { .n_name = "shmsegs" },
6511f4012fSEitan Adler { .n_name = NULL }
6655e2cb41SEdwin Groothuis };
6755e2cb41SEdwin Groothuis
6855e2cb41SEdwin Groothuis #define SHMINFO_XVEC X(shmmax, sizeof(u_long)) \
6955e2cb41SEdwin Groothuis X(shmmin, sizeof(u_long)) \
7055e2cb41SEdwin Groothuis X(shmmni, sizeof(u_long)) \
7155e2cb41SEdwin Groothuis X(shmseg, sizeof(u_long)) \
7255e2cb41SEdwin Groothuis X(shmall, sizeof(u_long))
7355e2cb41SEdwin Groothuis
741080a2c8SBjoern A. Zeeb #define SEMINFO_XVEC X(semmni, sizeof(int)) \
7555e2cb41SEdwin Groothuis X(semmns, sizeof(int)) \
7655e2cb41SEdwin Groothuis X(semmnu, sizeof(int)) \
7755e2cb41SEdwin Groothuis X(semmsl, sizeof(int)) \
7855e2cb41SEdwin Groothuis X(semopm, sizeof(int)) \
7955e2cb41SEdwin Groothuis X(semume, sizeof(int)) \
8055e2cb41SEdwin Groothuis X(semusz, sizeof(int)) \
8155e2cb41SEdwin Groothuis X(semvmx, sizeof(int)) \
8255e2cb41SEdwin Groothuis X(semaem, sizeof(int))
8355e2cb41SEdwin Groothuis
8455e2cb41SEdwin Groothuis #define MSGINFO_XVEC X(msgmax, sizeof(int)) \
8555e2cb41SEdwin Groothuis X(msgmni, sizeof(int)) \
8655e2cb41SEdwin Groothuis X(msgmnb, sizeof(int)) \
8755e2cb41SEdwin Groothuis X(msgtql, sizeof(int)) \
8855e2cb41SEdwin Groothuis X(msgssz, sizeof(int)) \
8955e2cb41SEdwin Groothuis X(msgseg, sizeof(int))
9055e2cb41SEdwin Groothuis
9155e2cb41SEdwin Groothuis #define X(a, b) { "kern.ipc." #a, offsetof(TYPEC, a), (b) },
9255e2cb41SEdwin Groothuis #define TYPEC struct shminfo
9311f4012fSEitan Adler static struct scgs_vector shminfo_scgsv[] = { SHMINFO_XVEC { .sysctl=NULL } };
9455e2cb41SEdwin Groothuis #undef TYPEC
9555e2cb41SEdwin Groothuis #define TYPEC struct seminfo
9611f4012fSEitan Adler static struct scgs_vector seminfo_scgsv[] = { SEMINFO_XVEC { .sysctl=NULL } };
9755e2cb41SEdwin Groothuis #undef TYPEC
9855e2cb41SEdwin Groothuis #define TYPEC struct msginfo
9911f4012fSEitan Adler static struct scgs_vector msginfo_scgsv[] = { MSGINFO_XVEC { .sysctl=NULL } };
10055e2cb41SEdwin Groothuis #undef TYPEC
10155e2cb41SEdwin Groothuis #undef X
10255e2cb41SEdwin Groothuis
10355e2cb41SEdwin Groothuis kvm_t *kd;
10455e2cb41SEdwin Groothuis
10555e2cb41SEdwin Groothuis void
sysctlgatherstruct(void * addr,size_t size,struct scgs_vector * vecarr)10655e2cb41SEdwin Groothuis sysctlgatherstruct(void *addr, size_t size, struct scgs_vector *vecarr)
10755e2cb41SEdwin Groothuis {
10855e2cb41SEdwin Groothuis struct scgs_vector *xp;
10955e2cb41SEdwin Groothuis size_t tsiz;
11055e2cb41SEdwin Groothuis int rv;
11155e2cb41SEdwin Groothuis
11255e2cb41SEdwin Groothuis for (xp = vecarr; xp->sysctl != NULL; xp++) {
11355e2cb41SEdwin Groothuis assert(xp->offset <= size);
11455e2cb41SEdwin Groothuis tsiz = xp->size;
11555e2cb41SEdwin Groothuis rv = sysctlbyname(xp->sysctl, (char *)addr + xp->offset,
11655e2cb41SEdwin Groothuis &tsiz, NULL, 0);
11755e2cb41SEdwin Groothuis if (rv == -1)
11855e2cb41SEdwin Groothuis err(1, "sysctlbyname: %s", xp->sysctl);
11955e2cb41SEdwin Groothuis if (tsiz != xp->size)
1208dc79f22SXin LI errx(1, "%s size mismatch (expected %zu, got %zu)",
12155e2cb41SEdwin Groothuis xp->sysctl, xp->size, tsiz);
12255e2cb41SEdwin Groothuis }
12355e2cb41SEdwin Groothuis }
12455e2cb41SEdwin Groothuis
12555e2cb41SEdwin Groothuis void
kget(int idx,void * addr,size_t size)12655e2cb41SEdwin Groothuis kget(int idx, void *addr, size_t size)
12755e2cb41SEdwin Groothuis {
12854e57c81SBjoern A. Zeeb const char *symn; /* symbol name */
12955e2cb41SEdwin Groothuis size_t tsiz;
13055e2cb41SEdwin Groothuis int rv;
13155e2cb41SEdwin Groothuis unsigned long kaddr;
13255e2cb41SEdwin Groothuis const char *sym2sysctl[] = { /* symbol to sysctl name table */
13355e2cb41SEdwin Groothuis "kern.ipc.sema",
13455e2cb41SEdwin Groothuis "kern.ipc.seminfo",
13555e2cb41SEdwin Groothuis "kern.ipc.msginfo",
13655e2cb41SEdwin Groothuis "kern.ipc.msqids",
13755e2cb41SEdwin Groothuis "kern.ipc.shminfo",
13855e2cb41SEdwin Groothuis "kern.ipc.shmsegs" };
13955e2cb41SEdwin Groothuis
14055e2cb41SEdwin Groothuis assert((unsigned)idx <= sizeof(sym2sysctl) / sizeof(*sym2sysctl));
14155e2cb41SEdwin Groothuis if (!use_sysctl) {
14255e2cb41SEdwin Groothuis symn = symbols[idx].n_name;
14355e2cb41SEdwin Groothuis if (*symn == '_')
14455e2cb41SEdwin Groothuis symn++;
14555e2cb41SEdwin Groothuis if (symbols[idx].n_type == 0 || symbols[idx].n_value == 0)
14655e2cb41SEdwin Groothuis errx(1, "symbol %s undefined", symn);
14755e2cb41SEdwin Groothuis /*
14855e2cb41SEdwin Groothuis * For some symbols, the value we retrieve is
14955e2cb41SEdwin Groothuis * actually a pointer; since we want the actual value,
15055e2cb41SEdwin Groothuis * we have to manually dereference it.
15155e2cb41SEdwin Groothuis */
15255e2cb41SEdwin Groothuis switch (idx) {
15355e2cb41SEdwin Groothuis case X_MSQIDS:
15455e2cb41SEdwin Groothuis tsiz = sizeof(msqids);
15555e2cb41SEdwin Groothuis rv = kvm_read(kd, symbols[idx].n_value,
15655e2cb41SEdwin Groothuis &msqids, tsiz);
15755e2cb41SEdwin Groothuis kaddr = (u_long)msqids;
15855e2cb41SEdwin Groothuis break;
15955e2cb41SEdwin Groothuis case X_SHMSEGS:
16055e2cb41SEdwin Groothuis tsiz = sizeof(shmsegs);
16155e2cb41SEdwin Groothuis rv = kvm_read(kd, symbols[idx].n_value,
16255e2cb41SEdwin Groothuis &shmsegs, tsiz);
16355e2cb41SEdwin Groothuis kaddr = (u_long)shmsegs;
16455e2cb41SEdwin Groothuis break;
16555e2cb41SEdwin Groothuis case X_SEMA:
16655e2cb41SEdwin Groothuis tsiz = sizeof(sema);
16755e2cb41SEdwin Groothuis rv = kvm_read(kd, symbols[idx].n_value,
16855e2cb41SEdwin Groothuis &sema, tsiz);
16955e2cb41SEdwin Groothuis kaddr = (u_long)sema;
17055e2cb41SEdwin Groothuis break;
17155e2cb41SEdwin Groothuis default:
17255e2cb41SEdwin Groothuis rv = tsiz = 0;
17355e2cb41SEdwin Groothuis kaddr = symbols[idx].n_value;
17455e2cb41SEdwin Groothuis break;
17555e2cb41SEdwin Groothuis }
17655e2cb41SEdwin Groothuis if ((unsigned)rv != tsiz)
17755e2cb41SEdwin Groothuis errx(1, "%s: %s", symn, kvm_geterr(kd));
17855e2cb41SEdwin Groothuis if ((unsigned)kvm_read(kd, kaddr, addr, size) != size)
17955e2cb41SEdwin Groothuis errx(1, "%s: %s", symn, kvm_geterr(kd));
18055e2cb41SEdwin Groothuis } else {
18155e2cb41SEdwin Groothuis switch (idx) {
18255e2cb41SEdwin Groothuis case X_SHMINFO:
18355e2cb41SEdwin Groothuis sysctlgatherstruct(addr, size, shminfo_scgsv);
18455e2cb41SEdwin Groothuis break;
18555e2cb41SEdwin Groothuis case X_SEMINFO:
18655e2cb41SEdwin Groothuis sysctlgatherstruct(addr, size, seminfo_scgsv);
18755e2cb41SEdwin Groothuis break;
18855e2cb41SEdwin Groothuis case X_MSGINFO:
18955e2cb41SEdwin Groothuis sysctlgatherstruct(addr, size, msginfo_scgsv);
19055e2cb41SEdwin Groothuis break;
19155e2cb41SEdwin Groothuis default:
19255e2cb41SEdwin Groothuis tsiz = size;
19355e2cb41SEdwin Groothuis rv = sysctlbyname(sym2sysctl[idx], addr, &tsiz,
19455e2cb41SEdwin Groothuis NULL, 0);
19555e2cb41SEdwin Groothuis if (rv == -1)
19655e2cb41SEdwin Groothuis err(1, "sysctlbyname: %s", sym2sysctl[idx]);
19755e2cb41SEdwin Groothuis if (tsiz != size)
19855e2cb41SEdwin Groothuis errx(1, "%s size mismatch "
1998dc79f22SXin LI "(expected %zu, got %zu)",
20055e2cb41SEdwin Groothuis sym2sysctl[idx], size, tsiz);
20155e2cb41SEdwin Groothuis break;
20255e2cb41SEdwin Groothuis }
20355e2cb41SEdwin Groothuis }
20455e2cb41SEdwin Groothuis }
205