Skip to content

Commit 87a1565

Browse files
committed
SysV IPC: provide in-kernel helpers to obtain ipcs(8)-like information
PR: 278949 Reviewed by: markj Tested by: Ricardo Branco <[email protected]> Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D45175
1 parent 5372516 commit 87a1565

File tree

6 files changed

+111
-0
lines changed

6 files changed

+111
-0
lines changed

sys/kern/sysv_msg.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1477,6 +1477,40 @@ sysctl_msqids(SYSCTL_HANDLER_ARGS)
14771477
return (error);
14781478
}
14791479

1480+
int
1481+
kern_get_msqids(struct thread *td, struct msqid_kernel **res, size_t *sz)
1482+
{
1483+
struct msqid_kernel *pmsqk;
1484+
struct prison *pr, *rpr;
1485+
int i, mi;
1486+
1487+
*sz = mi = msginfo.msgmni;
1488+
if (res == NULL)
1489+
return (0);
1490+
1491+
pr = td->td_ucred->cr_prison;
1492+
rpr = msg_find_prison(td->td_ucred);
1493+
*res = malloc(sizeof(struct msqid_kernel) * mi, M_TEMP, M_WAITOK);
1494+
for (i = 0; i < mi; i++) {
1495+
pmsqk = &(*res)[i];
1496+
mtx_lock(&msq_mtx);
1497+
if (msqids[i].u.msg_qbytes == 0 || rpr == NULL ||
1498+
msq_prison_cansee(rpr, &msqids[i]) != 0)
1499+
bzero(pmsqk, sizeof(*pmsqk));
1500+
else {
1501+
*pmsqk = msqids[i];
1502+
if (pmsqk->cred->cr_prison != pr)
1503+
pmsqk->u.msg_perm.key = IPC_PRIVATE;
1504+
}
1505+
mtx_unlock(&msq_mtx);
1506+
pmsqk->u.__msg_first = NULL;
1507+
pmsqk->u.__msg_last = NULL;
1508+
pmsqk->label = NULL;
1509+
pmsqk->cred = NULL;
1510+
}
1511+
return (0);
1512+
}
1513+
14801514
SYSCTL_INT(_kern_ipc, OID_AUTO, msgmax, CTLFLAG_RD, &msginfo.msgmax, 0,
14811515
"Maximum message size");
14821516
SYSCTL_INT(_kern_ipc, OID_AUTO, msgmni, CTLFLAG_RDTUN, &msginfo.msgmni, 0,

sys/kern/sysv_sem.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1574,6 +1574,39 @@ sysctl_sema(SYSCTL_HANDLER_ARGS)
15741574
return (error);
15751575
}
15761576

1577+
int
1578+
kern_get_sema(struct thread *td, struct semid_kernel **res, size_t *sz)
1579+
{
1580+
struct prison *pr, *rpr;
1581+
struct semid_kernel *psemak;
1582+
int i, mi;
1583+
1584+
*sz = mi = seminfo.semmni;
1585+
if (res == NULL)
1586+
return (0);
1587+
1588+
pr = td->td_ucred->cr_prison;
1589+
rpr = sem_find_prison(td->td_ucred);
1590+
*res = malloc(sizeof(struct semid_kernel) * mi, M_TEMP, M_WAITOK);
1591+
for (i = 0; i < mi; i++) {
1592+
psemak = &(*res)[i];
1593+
mtx_lock(&sema_mtx[i]);
1594+
if ((sema[i].u.sem_perm.mode & SEM_ALLOC) == 0 ||
1595+
rpr == NULL || sem_prison_cansee(rpr, &sema[i]) != 0)
1596+
bzero(psemak, sizeof(*psemak));
1597+
else {
1598+
*psemak = sema[i];
1599+
if (psemak->cred->cr_prison != pr)
1600+
psemak->u.sem_perm.key = IPC_PRIVATE;
1601+
}
1602+
mtx_unlock(&sema_mtx[i]);
1603+
psemak->u.__sem_base = NULL;
1604+
psemak->label = NULL;
1605+
psemak->cred = NULL;
1606+
}
1607+
return (0);
1608+
}
1609+
15771610
static int
15781611
sem_prison_check(void *obj, void *data)
15791612
{

sys/kern/sysv_shm.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1089,6 +1089,42 @@ sysctl_shmsegs(SYSCTL_HANDLER_ARGS)
10891089
return (error);
10901090
}
10911091

1092+
int
1093+
kern_get_shmsegs(struct thread *td, struct shmid_kernel **res, size_t *sz)
1094+
{
1095+
struct shmid_kernel *pshmseg;
1096+
struct prison *pr, *rpr;
1097+
int i;
1098+
1099+
SYSVSHM_LOCK();
1100+
*sz = shmalloced;
1101+
if (res == NULL)
1102+
goto out;
1103+
1104+
pr = td->td_ucred->cr_prison;
1105+
rpr = shm_find_prison(td->td_ucred);
1106+
*res = malloc(sizeof(struct shmid_kernel) * shmalloced, M_TEMP,
1107+
M_WAITOK);
1108+
for (i = 0; i < shmalloced; i++) {
1109+
pshmseg = &(*res)[i];
1110+
if ((shmsegs[i].u.shm_perm.mode & SHMSEG_ALLOCATED) == 0 ||
1111+
rpr == NULL || shm_prison_cansee(rpr, &shmsegs[i]) != 0) {
1112+
bzero(pshmseg, sizeof(*pshmseg));
1113+
pshmseg->u.shm_perm.mode = SHMSEG_FREE;
1114+
} else {
1115+
*pshmseg = shmsegs[i];
1116+
if (pshmseg->cred->cr_prison != pr)
1117+
pshmseg->u.shm_perm.key = IPC_PRIVATE;
1118+
}
1119+
pshmseg->object = NULL;
1120+
pshmseg->label = NULL;
1121+
pshmseg->cred = NULL;
1122+
}
1123+
out:
1124+
SYSVSHM_UNLOCK();
1125+
return (0);
1126+
}
1127+
10921128
static int
10931129
shm_prison_check(void *obj, void *data)
10941130
{

sys/sys/msg.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,9 @@ struct msqid_kernel {
152152
#ifdef _KERNEL
153153
extern struct msginfo msginfo;
154154

155+
int kern_get_msqids(struct thread *td, struct msqid_kernel **res,
156+
size_t *sz);
157+
155158
#else /* _KERNEL */
156159

157160
__BEGIN_DECLS

sys/sys/sem.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,9 @@ extern struct seminfo seminfo;
142142
*/
143143
void semexit(struct proc *p);
144144

145+
int kern_get_sema(struct thread *td, struct semid_kernel **res,
146+
size_t *sz);
147+
145148
#else /* !_KERNEL */
146149

147150
__BEGIN_DECLS

sys/sys/shm.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,8 @@ extern struct shminfo shminfo;
158158

159159
void shmexit(struct vmspace *);
160160
void shmfork(struct proc *, struct proc *);
161+
int kern_get_shmsegs(struct thread *td, struct shmid_kernel **res,
162+
size_t *sz);
161163

162164
#else /* !_KERNEL */
163165

0 commit comments

Comments
 (0)