svn commit: r329177 - in stable/11/sys: compat/freebsd32 kern
Brooks Davis
brooks at FreeBSD.org
Mon Feb 12 18:40:20 UTC 2018
Author: brooks
Date: Mon Feb 12 18:40:19 2018
New Revision: 329177
URL: https://svnweb.freebsd.org/changeset/base/329177
Log:
MFC r328799:
Add kern.ipc.{msqids,semsegs,sema} sysctls for FreeBSD32.
Stop leaking kernel pointers though theses sysctls and make sure that the
padding in the structures is zeroed on allocation to avoid other leaks.
Reviewed by: gordon, kib
Obtained from: CheriBSD
Sponsored by: DARPA, AFRL
Differential Revision: https://reviews.freebsd.org/D13459
Modified:
stable/11/sys/compat/freebsd32/freebsd32_ipc.h
stable/11/sys/kern/sysv_msg.c
stable/11/sys/kern/sysv_sem.c
stable/11/sys/kern/sysv_shm.c
Directory Properties:
stable/11/ (props changed)
Modified: stable/11/sys/compat/freebsd32/freebsd32_ipc.h
==============================================================================
--- stable/11/sys/compat/freebsd32/freebsd32_ipc.h Mon Feb 12 18:30:20 2018 (r329176)
+++ stable/11/sys/compat/freebsd32/freebsd32_ipc.h Mon Feb 12 18:40:19 2018 (r329177)
@@ -47,6 +47,18 @@ struct semid_ds32 {
int32_t sem_ctime;
};
+#ifdef _KERNEL
+struct semid_kernel32 {
+ /* Data structure exposed to user space. */
+ struct semid_ds32 u;
+
+ /* Kernel-private components of the semaphore. */
+ int32_t label;
+ int32_t cred;
+};
+#endif /* _KERNEL */
+
+
union semun32 {
int val;
uint32_t buf;
@@ -67,6 +79,17 @@ struct msqid_ds32 {
int32_t msg_ctime;
};
+#ifdef _KERNEL
+struct msqid_kernel32 {
+ /* Data structure exposed to user space. */
+ struct msqid_ds32 u;
+
+ /* Kernel-private components of the message queue. */
+ uint32_t label;
+ uint32_t cred;
+};
+#endif
+
struct shmid_ds32 {
struct ipc_perm32 shm_perm;
int32_t shm_segsz;
@@ -77,6 +100,15 @@ struct shmid_ds32 {
int32_t shm_dtime;
int32_t shm_ctime;
};
+
+#ifdef _KERNEL
+struct shmid_kernel32 {
+ struct shmid_ds32 u;
+ int32_t *object;
+ int32_t *label;
+ int32_t *cred;
+};
+#endif
struct shm_info32 {
int32_t used_ids;
Modified: stable/11/sys/kern/sysv_msg.c
==============================================================================
--- stable/11/sys/kern/sysv_msg.c Mon Feb 12 18:30:20 2018 (r329176)
+++ stable/11/sys/kern/sysv_msg.c Mon Feb 12 18:40:19 2018 (r329177)
@@ -220,7 +220,7 @@ msginit()
msgmaps = malloc(sizeof(struct msgmap) * msginfo.msgseg, M_MSG, M_WAITOK);
msghdrs = malloc(sizeof(struct msg) * msginfo.msgtql, M_MSG, M_WAITOK);
msqids = malloc(sizeof(struct msqid_kernel) * msginfo.msgmni, M_MSG,
- M_WAITOK);
+ M_WAITOK | M_ZERO);
/*
* msginfo.msgssz should be a power of two for efficiency reasons.
@@ -1417,7 +1417,12 @@ static int
sysctl_msqids(SYSCTL_HANDLER_ARGS)
{
struct msqid_kernel tmsqk;
+#ifdef COMPAT_FREEBSD32
+ struct msqid_kernel32 tmsqk32;
+#endif
struct prison *pr, *rpr;
+ void *outaddr;
+ size_t outsize;
int error, i;
pr = req->td->td_ucred->cr_prison;
@@ -1434,7 +1439,40 @@ sysctl_msqids(SYSCTL_HANDLER_ARGS)
tmsqk.u.msg_perm.key = IPC_PRIVATE;
}
mtx_unlock(&msq_mtx);
- error = SYSCTL_OUT(req, &tmsqk, sizeof(tmsqk));
+#ifdef COMPAT_FREEBSD32
+ if (SV_CURPROC_FLAG(SV_ILP32)) {
+ bzero(&tmsqk32, sizeof(tmsqk32));
+ freebsd32_ipcperm_out(&tmsqk.u.msg_perm,
+ &tmsqk32.u.msg_perm);
+ /* Don't copy u.msg_first or u.msg_last */
+ CP(tmsqk, tmsqk32, u.msg_cbytes);
+ CP(tmsqk, tmsqk32, u.msg_qnum);
+ CP(tmsqk, tmsqk32, u.msg_qbytes);
+ CP(tmsqk, tmsqk32, u.msg_lspid);
+ CP(tmsqk, tmsqk32, u.msg_lrpid);
+ CP(tmsqk, tmsqk32, u.msg_stime);
+ CP(tmsqk, tmsqk32, u.msg_rtime);
+ CP(tmsqk, tmsqk32, u.msg_ctime);
+ /* Don't copy label or cred */
+ outaddr = &tmsqk32;
+ outsize = sizeof(tmsqk32);
+ } else
+#endif
+ {
+ /* Don't leak kernel pointers */
+ tmsqk.u.msg_first = NULL;
+ tmsqk.u.msg_last = NULL;
+ tmsqk.label = NULL;
+ tmsqk.cred = NULL;
+ /*
+ * XXX: some padding also exists, but we take care to
+ * allocate our pool of msqid_kernel structs with
+ * zeroed memory so this should be OK.
+ */
+ outaddr = &tmsqk;
+ outsize = sizeof(tmsqk);
+ }
+ error = SYSCTL_OUT(req, outaddr, outsize);
if (error != 0)
break;
}
Modified: stable/11/sys/kern/sysv_sem.c
==============================================================================
--- stable/11/sys/kern/sysv_sem.c Mon Feb 12 18:30:20 2018 (r329176)
+++ stable/11/sys/kern/sysv_sem.c Mon Feb 12 18:40:19 2018 (r329177)
@@ -271,7 +271,7 @@ seminit(void)
sem = malloc(sizeof(struct sem) * seminfo.semmns, M_SEM, M_WAITOK);
sema = malloc(sizeof(struct semid_kernel) * seminfo.semmni, M_SEM,
- M_WAITOK);
+ M_WAITOK | M_ZERO);
sema_mtx = malloc(sizeof(struct mtx) * seminfo.semmni, M_SEM,
M_WAITOK | M_ZERO);
semu = malloc(seminfo.semmnu * seminfo.semusz, M_SEM, M_WAITOK);
@@ -1467,6 +1467,11 @@ sysctl_sema(SYSCTL_HANDLER_ARGS)
{
struct prison *pr, *rpr;
struct semid_kernel tsemak;
+#ifdef COMPAT_FREEBSD32
+ struct semid_kernel32 tsemak32;
+#endif
+ void *outaddr;
+ size_t outsize;
int error, i;
pr = req->td->td_ucred->cr_prison;
@@ -1483,7 +1488,28 @@ sysctl_sema(SYSCTL_HANDLER_ARGS)
tsemak.u.sem_perm.key = IPC_PRIVATE;
}
mtx_unlock(&sema_mtx[i]);
- error = SYSCTL_OUT(req, &tsemak, sizeof(tsemak));
+#ifdef COMPAT_FREEBSD32
+ if (SV_CURPROC_FLAG(SV_ILP32)) {
+ bzero(&tsemak32, sizeof(tsemak32));
+ freebsd32_ipcperm_out(&tsemak.u.sem_perm,
+ &tsemak32.u.sem_perm);
+ /* Don't copy u.sem_base */
+ CP(tsemak, tsemak32, u.sem_nsems);
+ CP(tsemak, tsemak32, u.sem_otime);
+ CP(tsemak, tsemak32, u.sem_ctime);
+ /* Don't copy label or cred */
+ outaddr = &tsemak32;
+ outsize = sizeof(tsemak32);
+ } else
+#endif
+ {
+ tsemak.u.sem_base = NULL;
+ tsemak.label = NULL;
+ tsemak.cred = NULL;
+ outaddr = &tsemak;
+ outsize = sizeof(tsemak);
+ }
+ error = SYSCTL_OUT(req, outaddr, outsize);
if (error != 0)
break;
}
Modified: stable/11/sys/kern/sysv_shm.c
==============================================================================
--- stable/11/sys/kern/sysv_shm.c Mon Feb 12 18:30:20 2018 (r329176)
+++ stable/11/sys/kern/sysv_shm.c Mon Feb 12 18:40:19 2018 (r329177)
@@ -844,7 +844,8 @@ shmrealloc(void)
if (shmalloced >= shminfo.shmmni)
return;
- newsegs = malloc(shminfo.shmmni * sizeof(*newsegs), M_SHM, M_WAITOK);
+ newsegs = malloc(shminfo.shmmni * sizeof(*newsegs), M_SHM,
+ M_WAITOK | M_ZERO);
for (i = 0; i < shmalloced; i++)
bcopy(&shmsegs[i], &newsegs[i], sizeof(newsegs[0]));
for (; i < shminfo.shmmni; i++) {
@@ -922,7 +923,8 @@ shminit(void)
}
}
shmalloced = shminfo.shmmni;
- shmsegs = malloc(shmalloced * sizeof(shmsegs[0]), M_SHM, M_WAITOK);
+ shmsegs = malloc(shmalloced * sizeof(shmsegs[0]), M_SHM,
+ M_WAITOK|M_ZERO);
for (i = 0; i < shmalloced; i++) {
shmsegs[i].u.shm_perm.mode = SHMSEG_FREE;
shmsegs[i].u.shm_perm.seq = 0;
@@ -1009,7 +1011,12 @@ static int
sysctl_shmsegs(SYSCTL_HANDLER_ARGS)
{
struct shmid_kernel tshmseg;
+#ifdef COMPAT_FREEBSD32
+ struct shmid_kernel32 tshmseg32;
+#endif
struct prison *pr, *rpr;
+ void *outaddr;
+ size_t outsize;
int error, i;
SYSVSHM_LOCK();
@@ -1026,7 +1033,31 @@ sysctl_shmsegs(SYSCTL_HANDLER_ARGS)
if (tshmseg.cred->cr_prison != pr)
tshmseg.u.shm_perm.key = IPC_PRIVATE;
}
- error = SYSCTL_OUT(req, &tshmseg, sizeof(tshmseg));
+#ifdef COMPAT_FREEBSD32
+ if (SV_CURPROC_FLAG(SV_ILP32)) {
+ bzero(&tshmseg32, sizeof(tshmseg32));
+ freebsd32_ipcperm_out(&tshmseg.u.shm_perm,
+ &tshmseg32.u.shm_perm);
+ CP(tshmseg, tshmseg32, u.shm_segsz);
+ CP(tshmseg, tshmseg32, u.shm_lpid);
+ CP(tshmseg, tshmseg32, u.shm_cpid);
+ CP(tshmseg, tshmseg32, u.shm_nattch);
+ CP(tshmseg, tshmseg32, u.shm_atime);
+ CP(tshmseg, tshmseg32, u.shm_dtime);
+ CP(tshmseg, tshmseg32, u.shm_ctime);
+ /* Don't copy object, label, or cred */
+ outaddr = &tshmseg32;
+ outsize = sizeof(tshmseg32);
+ } else
+#endif
+ {
+ tshmseg.object = NULL;
+ tshmseg.label = NULL;
+ tshmseg.cred = NULL;
+ outaddr = &tshmseg;
+ outsize = sizeof(tshmseg);
+ }
+ error = SYSCTL_OUT(req, outaddr, outsize);
if (error != 0)
break;
}
More information about the svn-src-stable
mailing list