Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 26 Apr 2016 18:17:44 +0000 (UTC)
From:      Jamie Gritton <jamie@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r298656 - head/sys/kern
Message-ID:  <201604261817.u3QIHi2e094653@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jamie
Date: Tue Apr 26 18:17:44 2016
New Revision: 298656
URL: https://svnweb.freebsd.org/changeset/base/298656

Log:
  Redo the changes to the SYSV IPC sysctl functions from r298585, so they
  don't (mis)use sbufs.
  
  PR:		48471

Modified:
  head/sys/kern/sysv_msg.c
  head/sys/kern/sysv_sem.c
  head/sys/kern/sysv_shm.c

Modified: head/sys/kern/sysv_msg.c
==============================================================================
--- head/sys/kern/sysv_msg.c	Tue Apr 26 18:11:45 2016	(r298655)
+++ head/sys/kern/sysv_msg.c	Tue Apr 26 18:17:44 2016	(r298656)
@@ -65,7 +65,6 @@ __FBSDID("$FreeBSD$");
 #include <sys/mount.h>
 #include <sys/msg.h>
 #include <sys/racct.h>
-#include <sys/sbuf.h>
 #include <sys/sx.h>
 #include <sys/syscall.h>
 #include <sys/syscallsubr.h>
@@ -1423,38 +1422,28 @@ sys_msgrcv(td, uap)
 static int
 sysctl_msqids(SYSCTL_HANDLER_ARGS)
 {
-	struct sbuf sb;
-	struct msqid_kernel tmp, empty;
-	struct msqid_kernel *msqkptr;
-	struct prison *rpr;
+	struct msqid_kernel tmsqk;
+	struct prison *pr, *rpr;
 	int error, i;
 
-	error = sysctl_wire_old_buffer(req, 0);
-	if (error != 0)
-		goto done;
+	pr = req->td->td_ucred->cr_prison;
 	rpr = msg_find_prison(req->td->td_ucred);
-	sbuf_new_for_sysctl(&sb, NULL, sizeof(struct msqid_kernel) *
-	    msginfo.msgmni, req);
-
-	bzero(&empty, sizeof(empty));
+	error = 0;
 	for (i = 0; i < msginfo.msgmni; i++) {
-		msqkptr = &msqids[i];
-		if (msqkptr->u.msg_qbytes == 0 || rpr == NULL ||
-		    msq_prison_cansee(rpr, msqkptr) != 0) {
-			msqkptr = &empty;
-		} else if (req->td->td_ucred->cr_prison !=
-		    msqkptr->cred->cr_prison) {
-			bcopy(msqkptr, &tmp, sizeof(tmp));
-			msqkptr = &tmp;
-			msqkptr->u.msg_perm.key = IPC_PRIVATE;
+		mtx_lock(&msq_mtx);
+		if (msqids[i].u.msg_qbytes == 0 || rpr == NULL ||
+		    msq_prison_cansee(rpr, &msqids[i]) != 0)
+			bzero(&tmsqk, sizeof(tmsqk));
+		else {
+			tmsqk = msqids[i];
+			if (tmsqk.cred->cr_prison != pr)
+				tmsqk.u.msg_perm.key = IPC_PRIVATE;
 		}
-
-		sbuf_bcat(&sb, msqkptr, sizeof(*msqkptr));
+		mtx_unlock(&msq_mtx);
+		error = SYSCTL_OUT(req, &tmsqk, sizeof(tmsqk));
+		if (error != 0)
+			break;
 	}
-	error = sbuf_finish(&sb);
-	sbuf_delete(&sb);
-
-done:
 	return (error);
 }
 
@@ -1470,7 +1459,8 @@ SYSCTL_INT(_kern_ipc, OID_AUTO, msgssz, 
     "Size of a message segment");
 SYSCTL_INT(_kern_ipc, OID_AUTO, msgseg, CTLFLAG_RDTUN, &msginfo.msgseg, 0,
     "Number of message segments");
-SYSCTL_PROC(_kern_ipc, OID_AUTO, msqids, CTLTYPE_OPAQUE | CTLFLAG_RD,
+SYSCTL_PROC(_kern_ipc, OID_AUTO, msqids,
+    CTLTYPE_OPAQUE | CTLFLAG_RD | CTLFLAG_MPSAFE,
     NULL, 0, sysctl_msqids, "", "Message queue IDs");
 
 static int

Modified: head/sys/kern/sysv_sem.c
==============================================================================
--- head/sys/kern/sysv_sem.c	Tue Apr 26 18:11:45 2016	(r298655)
+++ head/sys/kern/sysv_sem.c	Tue Apr 26 18:17:44 2016	(r298656)
@@ -52,7 +52,6 @@ __FBSDID("$FreeBSD$");
 #include <sys/module.h>
 #include <sys/mutex.h>
 #include <sys/racct.h>
-#include <sys/sbuf.h>
 #include <sys/sem.h>
 #include <sys/sx.h>
 #include <sys/syscall.h>
@@ -220,7 +219,8 @@ SYSCTL_INT(_kern_ipc, OID_AUTO, semvmx, 
     "Semaphore maximum value");
 SYSCTL_INT(_kern_ipc, OID_AUTO, semaem, CTLFLAG_RWTUN, &seminfo.semaem, 0,
     "Adjust on exit max value");
-SYSCTL_PROC(_kern_ipc, OID_AUTO, sema, CTLTYPE_OPAQUE | CTLFLAG_RD,
+SYSCTL_PROC(_kern_ipc, OID_AUTO, sema,
+    CTLTYPE_OPAQUE | CTLFLAG_RD | CTLFLAG_MPSAFE,
     NULL, 0, sysctl_sema, "", "Semaphore id pool");
 
 static struct syscall_helper_data sem_syscalls[] = {
@@ -1465,38 +1465,28 @@ semexit_myhook(void *arg, struct proc *p
 static int
 sysctl_sema(SYSCTL_HANDLER_ARGS)
 {
-	struct prison *rpr;
-	struct sbuf sb;
-	struct semid_kernel tmp, empty;
-	struct semid_kernel *semakptr;
+	struct prison *pr, *rpr;
+	struct semid_kernel tsemak;
 	int error, i;
 
-	error = sysctl_wire_old_buffer(req, 0);
-	if (error != 0)
-		goto done;
+	pr = req->td->td_ucred->cr_prison;
 	rpr = sem_find_prison(req->td->td_ucred);
-	sbuf_new_for_sysctl(&sb, NULL, sizeof(struct semid_kernel) *
-	    seminfo.semmni, req);
-
-	bzero(&empty, sizeof(empty));
+	error = 0;
 	for (i = 0; i < seminfo.semmni; i++) {
-		semakptr = &sema[i];
-		if ((semakptr->u.sem_perm.mode & SEM_ALLOC) == 0 ||
-		    rpr == NULL || sem_prison_cansee(rpr, semakptr) != 0) {
-			semakptr = &empty;
-		} else if (req->td->td_ucred->cr_prison !=
-		    semakptr->cred->cr_prison) {
-			bcopy(semakptr, &tmp, sizeof(tmp));
-			semakptr = &tmp;
-			semakptr->u.sem_perm.key = IPC_PRIVATE;
+		mtx_lock(&sema_mtx[i]);
+		if ((sema[i].u.sem_perm.mode & SEM_ALLOC) == 0 ||
+		    rpr == NULL || sem_prison_cansee(rpr, &sema[i]) != 0)
+			bzero(&tsemak, sizeof(tsemak));
+		else {
+			tsemak = sema[i];
+			if (tsemak.cred->cr_prison != pr)
+				tsemak.u.sem_perm.key = IPC_PRIVATE;
 		}
-
-		sbuf_bcat(&sb, semakptr, sizeof(*semakptr));
+		mtx_unlock(&sema_mtx[i]);
+		error = SYSCTL_OUT(req, &tsemak, sizeof(tsemak));
+		if (error != 0)
+			break;
 	}
-	error = sbuf_finish(&sb);
-	sbuf_delete(&sb);
-
-done:
 	return (error);
 }
 

Modified: head/sys/kern/sysv_shm.c
==============================================================================
--- head/sys/kern/sysv_shm.c	Tue Apr 26 18:11:45 2016	(r298655)
+++ head/sys/kern/sysv_shm.c	Tue Apr 26 18:17:44 2016	(r298656)
@@ -80,7 +80,6 @@ __FBSDID("$FreeBSD$");
 #include <sys/racct.h>
 #include <sys/resourcevar.h>
 #include <sys/rwlock.h>
-#include <sys/sbuf.h>
 #include <sys/stat.h>
 #include <sys/syscall.h>
 #include <sys/syscallsubr.h>
@@ -1009,40 +1008,28 @@ shmunload(void)
 static int
 sysctl_shmsegs(SYSCTL_HANDLER_ARGS)
 {
-	struct prison *rpr;
-	struct sbuf sb;
-	struct shmid_kernel tmp, empty;
-	struct shmid_kernel *shmseg;
+	struct shmid_kernel tshmseg;
+	struct prison *pr, *rpr;
 	int error, i;
 
 	SYSVSHM_LOCK();
-
-	error = sysctl_wire_old_buffer(req, 0);
-	if (error != 0)
-		goto done;
+	pr = req->td->td_ucred->cr_prison;
 	rpr = shm_find_prison(req->td->td_ucred);
-	sbuf_new_for_sysctl(&sb, NULL, shmalloced * sizeof(shmsegs[0]), req);
-
-	bzero(&empty, sizeof(empty));
-	empty.u.shm_perm.mode = SHMSEG_FREE;
+	error = 0;
 	for (i = 0; i < shmalloced; i++) {
-		shmseg = &shmsegs[i];
-		if ((shmseg->u.shm_perm.mode & SHMSEG_ALLOCATED) == 0 ||
+		if ((shmsegs[i].u.shm_perm.mode & SHMSEG_ALLOCATED) == 0 ||
 		    rpr == NULL || shm_prison_cansee(rpr, &shmsegs[i]) != 0) {
-			shmseg = &empty;
-		} else if (req->td->td_ucred->cr_prison !=
-		    shmseg->cred->cr_prison) {
-			bcopy(shmseg, &tmp, sizeof(tmp));
-			shmseg = &tmp;
-			shmseg->u.shm_perm.key = IPC_PRIVATE;
+			bzero(&tshmseg, sizeof(tshmseg));
+			tshmseg.u.shm_perm.mode = SHMSEG_FREE;
+		} else {
+			tshmseg = shmsegs[i];
+			if (tshmseg.cred->cr_prison != pr)
+				tshmseg.u.shm_perm.key = IPC_PRIVATE;
 		}
-
-		sbuf_bcat(&sb, shmseg, sizeof(*shmseg));
+		error = SYSCTL_OUT(req, &tshmseg, sizeof(tshmseg));
+		if (error != 0)
+			break;
 	}
-	error = sbuf_finish(&sb);
-	sbuf_delete(&sb);
-
-done:
 	SYSVSHM_UNLOCK();
 	return (error);
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201604261817.u3QIHi2e094653>