Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 24 May 2001 17:19:34 -0700
From:      Dima Dorfman <dima@unixfreak.org>
To:        Thomas Moestl <tmm@freebsd.org>, audit@freebsd.org
Subject:   Re: Patch to remove setgid bit from ipcs(1) 
Message-ID:  <20010525001934.D1C663E28@bazooka.unixfreak.org>
In-Reply-To: <20010524214918.A2640@crow.dom2ip.de>; from tmm@freebsd.org on "Thu, 24 May 2001 21:49:18 %2B0200"

next in thread | previous in thread | raw e-mail | index | archive | help
Thomas Moestl <tmm@freebsd.org> writes:
> On Wed, 2001/05/23 at 19:40:51 -0700, Dima Dorfman wrote:
> > 
> > +SYSCTL_PROC(_kern_ipc, OID_AUTO, msqids, CTLFLAG_ANYBODY | CTLFLAG_RD,
> > +    NULL, 0, sysctl_msqids, "", "Message queue IDs");
> 
> <nitpick>
> There are some occurances of CTLFLAG_ANYBODY still.
> </nitpick>

Doh, I thought I'd gotten rid of all of those.. :-/  Thanks!

> [ tsiz should be size_t ]
> [ void pointer arith ]

Fixed.  I also fixed some other warnings you didn't mention, again by
compiling with BDECFLAS.

Updated patch attached.

					Dima Dorfman
					dima@unixfreak.org


Index: sys/kern/sysv_msg.c
===================================================================
RCS file: /stl/src/FreeBSD/src/sys/kern/sysv_msg.c,v
retrieving revision 1.30
diff -u -r1.30 sysv_msg.c
--- sys/kern/sysv_msg.c	2001/02/21 06:39:54	1.30
+++ sys/kern/sysv_msg.c	2001/05/25 00:15:10
@@ -1166,3 +1166,21 @@
 	p->p_retval[0] = msgsz;
 	return(0);
 }
+
+static int
+sysctl_msqids(SYSCTL_HANDLER_ARGS)
+{
+
+	return (SYSCTL_OUT(req, msqids,
+	    sizeof(struct msqid_ds) * msginfo.msgmni));
+}
+
+SYSCTL_DECL(_kern_ipc);
+SYSCTL_INT(_kern_ipc, OID_AUTO, msgmax, CTLFLAG_RD, &msginfo.msgmax, 0, "");
+SYSCTL_INT(_kern_ipc, OID_AUTO, msgmni, CTLFLAG_RD, &msginfo.msgmni, 0, "");
+SYSCTL_INT(_kern_ipc, OID_AUTO, msgmnb, CTLFLAG_RD, &msginfo.msgmnb, 0, "");
+SYSCTL_INT(_kern_ipc, OID_AUTO, msgtql, CTLFLAG_RD, &msginfo.msgtql, 0, "");
+SYSCTL_INT(_kern_ipc, OID_AUTO, msgssz, CTLFLAG_RD, &msginfo.msgssz, 0, "");
+SYSCTL_INT(_kern_ipc, OID_AUTO, msgseg, CTLFLAG_RD, &msginfo.msgseg, 0, "")
+SYSCTL_PROC(_kern_ipc, OID_AUTO, msqids, CTLFLAG_RD,
+    NULL, 0, sysctl_msqids, "", "Message queue IDs");
Index: sys/kern/sysv_sem.c
===================================================================
RCS file: /stl/src/FreeBSD/src/sys/kern/sysv_sem.c,v
retrieving revision 1.32
diff -u -r1.32 sysv_sem.c
--- sys/kern/sysv_sem.c	2001/02/21 06:39:54	1.32
+++ sys/kern/sysv_sem.c	2001/05/25 00:15:10
@@ -28,6 +28,7 @@
 static int sysvsem_modload __P((struct module *, int, void *));
 static int semunload __P((void));
 static void semexit_myhook __P((struct proc *p));
+static int sysctl_sema __P((SYSCTL_HANDLER_ARGS));
 
 #ifndef _SYS_SYSPROTO_H_
 struct __semctl_args;
@@ -148,6 +149,8 @@
 SYSCTL_INT(_kern_ipc, OID_AUTO, semusz, CTLFLAG_RD, &seminfo.semusz, 0, "");
 SYSCTL_INT(_kern_ipc, OID_AUTO, semvmx, CTLFLAG_RW, &seminfo.semvmx, 0, "");
 SYSCTL_INT(_kern_ipc, OID_AUTO, semaem, CTLFLAG_RW, &seminfo.semaem, 0, "");
+SYSCTL_PROC(_kern_ipc, OID_AUTO, sema, CTLFLAG_RD,
+    NULL, 0, sysctl_sema, "", "");
 
 #if 0
 RO seminfo.semmap	/* SEMMAP unused */
@@ -1065,4 +1068,12 @@
 #endif
 	suptr->un_proc = NULL;
 	*supptr = suptr->un_next;
+}
+
+static int
+sysctl_sema(SYSCTL_HANDLER_ARGS)
+{
+
+	return (SYSCTL_OUT(req, sema,
+	    sizeof(struct semid_ds) * seminfo.semmni));
 }
Index: sys/kern/sysv_shm.c
===================================================================
RCS file: /stl/src/FreeBSD/src/sys/kern/sysv_shm.c,v
retrieving revision 1.60
diff -u -r1.60 sysv_shm.c
--- sys/kern/sysv_shm.c	2001/05/23 23:38:05	1.60
+++ sys/kern/sysv_shm.c	2001/05/25 00:15:10
@@ -104,6 +104,7 @@
 static int shmunload __P((void));
 static void shmexit_myhook __P((struct proc *p));
 static void shmfork_myhook __P((struct proc *p1, struct proc *p2));
+static int sysctl_shmsegs __P((SYSCTL_HANDLER_ARGS));
 
 /*
  * Tuneable values.
@@ -145,6 +146,8 @@
 SYSCTL_INT(_kern_ipc, OID_AUTO, shmall, CTLFLAG_RW, &shminfo.shmall, 0, "");
 SYSCTL_INT(_kern_ipc, OID_AUTO, shm_use_phys, CTLFLAG_RW,
     &shm_use_phys, 0, "");
+SYSCTL_PROC(_kern_ipc, OID_AUTO, shmsegs, CTLFLAG_RD,
+    NULL, 0, sysctl_shmsegs, "", "");
 
 static int
 shm_find_segment_by_key(key)
@@ -740,6 +743,13 @@
 	shmexit_hook = NULL;
 	shmfork_hook = NULL;
 	return (0);
+}
+
+static int
+sysctl_shmsegs(SYSCTL_HANDLER_ARGS)
+{
+
+	return (SYSCTL_OUT(req, shmsegs, shmalloced * sizeof(shmsegs[0])));
 }
 
 static int
Index: usr.bin/ipcs/ipcs.1
===================================================================
RCS file: /stl/src/FreeBSD/src/usr.bin/ipcs/ipcs.1,v
retrieving revision 1.11
diff -u -r1.11 ipcs.1
--- usr.bin/ipcs/ipcs.1	2000/12/14 11:49:46	1.11
+++ usr.bin/ipcs/ipcs.1	2001/05/25 00:15:10
@@ -37,7 +37,7 @@
 .Nd report System V interprocess communication facilities status
 .Sh SYNOPSIS
 .Nm
-.Op Fl abcmopqstMQST
+.Op Fl abcmopqstMQSTy
 .Op Fl C Ar system
 .Op Fl N Ar core
 .Sh DESCRIPTION
@@ -101,12 +101,16 @@
 Extract the name list from the specified system instead of the
 default
 .Dq Pa /kernel .
+Implies
+.Fl y .
 .It Fl M
 Display system information about shared memory.
 .It Fl N Ar core
 Extract values associated with the name list from the specified
 core instead of the default
 .Dq Pa /dev/kmem .
+Implies
+.Fl y .
 .It Fl Q
 Display system information about messages queues.
 .It Fl S
@@ -114,6 +118,19 @@
 .It Fl T
 Display system information about shared memory, message queues
 and semaphores.
+.It Fl y
+Use the
+.Xr kvm 3
+interface instead of the
+.Xr sysctl 3
+interface to extract the required information.
+If
+.Nm
+is to operate on the running system,
+using
+.Xr kvm 3
+will require read privileges to
+.Pa /dev/kmem .
 .El
 .Pp
 If none of the
Index: usr.bin/ipcs/ipcs.c
===================================================================
RCS file: /stl/src/FreeBSD/src/usr.bin/ipcs/ipcs.c,v
retrieving revision 1.14
diff -u -r1.14 ipcs.c
--- usr.bin/ipcs/ipcs.c	2000/05/01 10:49:41	1.14
+++ usr.bin/ipcs/ipcs.c	2001/05/25 00:15:10
@@ -30,11 +30,14 @@
   "$FreeBSD: src/usr.bin/ipcs/ipcs.c,v 1.14 2000/05/01 10:49:41 peter Exp $";
 #endif /* not lint */
 
+#include <assert.h>
 #include <err.h>
 #include <fcntl.h>
 #include <kvm.h>
 #include <nlist.h>
+#include <limits.h>
 #include <paths.h>
+#include <stddef.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
@@ -43,12 +46,21 @@
 #include <sys/param.h>
 #include <sys/time.h>
 #include <sys/proc.h>
+#include <sys/sysctl.h>
 #define _KERNEL
 #include <sys/ipc.h>
 #include <sys/sem.h>
 #include <sys/shm.h>
 #include <sys/msg.h>
 
+/* SysCtlGatherStruct structure. */
+struct scgs_vector {
+	const char *sysctl;
+	off_t offset;
+	size_t size;
+};
+
+int	use_sysctl = 1;
 struct semid_ds	*sema;
 struct seminfo	seminfo;
 struct msginfo	msginfo;
@@ -56,26 +68,66 @@
 struct shminfo	shminfo;
 struct shmid_ds	*shmsegs;
 
+void	sysctlgatherstruct __P((void *addr, size_t size,
+    struct scgs_vector *vec));
+void	kget __P((int idx, void *addr, size_t size));
 void	usage __P((void));
 
 static struct nlist symbols[] = {
-	{"_sema"},
+	{"sema"},
 #define X_SEMA		0
-	{"_seminfo"},
+	{"seminfo"},
 #define X_SEMINFO	1
-	{"_semu"},
-#define X_SEMU		2
-	{"_msginfo"},
-#define X_MSGINFO	3
-	{"_msqids"},
-#define X_MSQIDS	4
-	{"_shminfo"},
-#define X_SHMINFO	5
-	{"_shmsegs"},
-#define X_SHMSEGS	6
+	{"msginfo"},
+#define X_MSGINFO	2
+	{"msqids"},
+#define X_MSQIDS	3
+	{"shminfo"},
+#define X_SHMINFO	4
+	{"shmsegs"},
+#define X_SHMSEGS	5
 	{NULL}
 };
 
+#define	SHMINFO_XVEC				\
+X(shmmax, sizeof(int))				\
+X(shmmin, sizeof(int))				\
+X(shmmni, sizeof(int))				\
+X(shmseg, sizeof(int))				\
+X(shmall, sizeof(int))
+
+#define	SEMINFO_XVEC				\
+X(semmap, sizeof(int))				\
+X(semmni, sizeof(int))				\
+X(semmns, sizeof(int))				\
+X(semmnu, sizeof(int))				\
+X(semmsl, sizeof(int))				\
+X(semopm, sizeof(int))				\
+X(semume, sizeof(int))				\
+X(semusz, sizeof(int))				\
+X(semvmx, sizeof(int))				\
+X(semaem, sizeof(int))
+
+#define	MSGINFO_XVEC				\
+X(msgmax, sizeof(int))				\
+X(msgmni, sizeof(int))				\
+X(msgmnb, sizeof(int))				\
+X(msgtql, sizeof(int))				\
+X(msgssz, sizeof(int))				\
+X(msgseg, sizeof(int))
+
+#define	X(a, b)	{ "kern.ipc." #a, offsetof(TYPEC, a), (b) },
+#define	TYPEC	struct shminfo
+struct scgs_vector shminfo_scgsv[] = { SHMINFO_XVEC { NULL } };
+#undef	TYPEC
+#define	TYPEC	struct seminfo
+struct scgs_vector seminfo_scgsv[] = { SEMINFO_XVEC { NULL } };
+#undef	TYPEC
+#define	TYPEC	struct msginfo
+struct scgs_vector msginfo_scgsv[] = { MSGINFO_XVEC { NULL } };
+#undef	TYPEC
+#undef	X
+
 static kvm_t *kd;
 
 char   *
@@ -135,9 +187,10 @@
 	int     display = SHMINFO | MSGINFO | SEMINFO;
 	int     option = 0;
 	char   *core = NULL, *namelist = NULL;
+	char	kvmoferr[_POSIX2_LINE_MAX];  /* Error buf for kvm_openfiles. */
 	int     i;
 
-	while ((i = getopt(argc, argv, "MmQqSsabC:cN:optT")) != -1)
+	while ((i = getopt(argc, argv, "MmQqSsabC:cN:optTy")) != -1)
 		switch (i) {
 		case 'M':
 			display = SHMTOTAL;
@@ -184,39 +237,44 @@
 		case 't':
 			option |= TIME;
 			break;
+		case 'y':
+			use_sysctl = 0;
+			break;
 		default:
 			usage();
 		}
 
 	/*
-	 * Discard setgid privileges if not the running kernel so that bad
-	 * guys can't print interesting stuff from kernel memory.
+	 * If paths to the exec file or core file were specified, we
+	 * aren't operating on the running kernel, so we can't use
+	 * sysctl.
 	 */
 	if (namelist != NULL || core != NULL)
-		setgid(getgid());
-
-	if ((kd = kvm_open(namelist, core, NULL, O_RDONLY, "ipcs")) == NULL)
-		exit(1);
+		use_sysctl = 0;
 
-	switch (kvm_nlist(kd, symbols)) {
-	case 0:
-		break;
-	case -1:
-		errx(1, "unable to read kernel symbol table");
-	default:
+	if (!use_sysctl) {
+		kd = kvm_openfiles(namelist, core, NULL, O_RDONLY, kvmoferr);
+		if (kd == NULL)
+			errx(1, "kvm_openfiles: %s", kvmoferr);
+		switch (kvm_nlist(kd, symbols)) {
+		case 0:
+			break;
+		case -1:
+			errx(1, "unable to read kernel symbol table");
+		default:
 #ifdef notdef		/* they'll be told more civilly later */
-		warnx("nlist failed");
-		for (i = 0; symbols[i].n_name != NULL; i++)
-			if (symbols[i].n_value == 0)
-				warnx("symbol %s not found",
-				    symbols[i].n_name);
-		break;
+			warnx("nlist failed");
+			for (i = 0; symbols[i].n_name != NULL; i++)
+				if (symbols[i].n_value == 0)
+					warnx("symbol %s not found",
+					    symbols[i].n_name);
+			break;
 #endif
+		}
 	}
 
-	if ((display & (MSGINFO | MSGTOTAL)) &&
-	    kvm_read(kd, symbols[X_MSGINFO].n_value, &msginfo, sizeof(msginfo))== sizeof(msginfo)) {
-
+	kget(X_MSGINFO, &msginfo, sizeof(msginfo));
+	if ((display & (MSGINFO | MSGTOTAL))) {
 		if (display & MSGTOTAL) {
 			printf("msginfo:\n");
 			printf("\tmsgmax: %6d\t(max characters in a message)\n",
@@ -234,10 +292,12 @@
 		}
 		if (display & MSGINFO) {
 			struct msqid_ds *xmsqids;
+			size_t xmsqids_len;
+
 
-			kvm_read(kd, symbols[X_MSQIDS].n_value, &msqids, sizeof(msqids));
-			xmsqids = malloc(sizeof(struct msqid_ds) * msginfo.msgmni);
-			kvm_read(kd, (u_long) msqids, xmsqids, sizeof(struct msqid_ds) * msginfo.msgmni);
+			xmsqids_len = sizeof(struct msqid_ds) * msginfo.msgmni;
+			xmsqids = malloc(xmsqids_len);
+			kget(X_MSQIDS, xmsqids, xmsqids_len);
 
 			printf("Message Queues:\n");
 			printf("T     ID     KEY        MODE       OWNER    GROUP");
@@ -304,8 +364,9 @@
 			fprintf(stderr,
 			    "SVID messages facility not configured in the system\n");
 		}
-	if ((display & (SHMINFO | SHMTOTAL)) &&
-	    kvm_read(kd, symbols[X_SHMINFO].n_value, &shminfo, sizeof(shminfo))) {
+
+	kget(X_SHMINFO, &shminfo, sizeof(shminfo));
+	if ((display & (SHMINFO | SHMTOTAL))) {
 		if (display & SHMTOTAL) {
 			printf("shminfo:\n");
 			printf("\tshmmax: %7d\t(max shared memory segment size)\n",
@@ -321,11 +382,11 @@
 		}
 		if (display & SHMINFO) {
 			struct shmid_ds *xshmids;
+			size_t xshmids_len;
 
-			kvm_read(kd, symbols[X_SHMSEGS].n_value, &shmsegs, sizeof(shmsegs));
-			xshmids = malloc(sizeof(struct shmid_ds) * shminfo.shmmni);
-			kvm_read(kd, (u_long) shmsegs, xshmids, sizeof(struct shmid_ds) *
-			    shminfo.shmmni);
+			xshmids_len = sizeof(struct shmid_ds) * shminfo.shmmni;
+			xshmids = malloc(xshmids_len);
+			kget(X_SHMSEGS, xshmids, xshmids_len);
 
 			printf("Shared Memory:\n");
 			printf("T     ID     KEY        MODE       OWNER    GROUP");
@@ -391,9 +452,11 @@
 			fprintf(stderr,
 			    "SVID shared memory facility not configured in the system\n");
 		}
-	if ((display & (SEMINFO | SEMTOTAL)) &&
-	    kvm_read(kd, symbols[X_SEMINFO].n_value, &seminfo, sizeof(seminfo))) {
+
+	kget(X_SEMINFO, &seminfo, sizeof(seminfo));
+	if ((display & (SEMINFO | SEMTOTAL))) {
 		struct semid_ds *xsema;
+		size_t xsema_len;
 
 		if (display & SEMTOTAL) {
 			printf("seminfo:\n");
@@ -419,9 +482,9 @@
 			    seminfo.semaem);
 		}
 		if (display & SEMINFO) {
-			kvm_read(kd, symbols[X_SEMA].n_value, &sema, sizeof(sema));
-			xsema = malloc(sizeof(struct semid_ds) * seminfo.semmni);
-			kvm_read(kd, (u_long) sema, xsema, sizeof(struct semid_ds) * seminfo.semmni);
+			xsema_len = sizeof(struct semid_ds) * seminfo.semmni;
+			xsema = malloc(xsema_len);
+			kget(X_SEMA, xsema, xsema_len);
 
 			printf("Semaphores:\n");
 			printf("T     ID     KEY        MODE       OWNER    GROUP");
@@ -471,16 +534,124 @@
 		if (display & (SEMINFO | SEMTOTAL)) {
 			fprintf(stderr, "SVID semaphores facility not configured in the system\n");
 		}
-	kvm_close(kd);
+	if (!use_sysctl)
+		kvm_close(kd);
 
 	exit(0);
 }
 
 void
+sysctlgatherstruct(addr, size, vecarr)
+	void *addr;
+	size_t size;
+	struct scgs_vector *vecarr;
+{
+	struct scgs_vector *xp;
+	size_t tsiz;
+	int rv;
+
+	for (xp = vecarr; xp->sysctl != NULL; xp++) {
+		assert(xp->offset <= size);
+		tsiz = xp->size;
+		rv = sysctlbyname(xp->sysctl, (char *)addr + xp->offset,
+		    &tsiz, NULL, 0);
+		if (rv == -1)
+			errx(1, "sysctlbyname: %s", xp->sysctl);
+		if (tsiz != xp->size)
+			errx(1, "%s size mismatch (expected %d, got %d)",
+			    xp->sysctl, xp->size, tsiz);
+	}
+}
+
+void
+kget(idx, addr, size)
+	int idx;
+	void *addr;
+	size_t size;
+{
+	char *symn;			/* symbol name */
+	size_t tsiz;
+	int rv;
+	unsigned long kaddr;
+	const char *sym2sysctl[] = {	/* symbol to sysctl name table */
+		"kern.ipc.sema",
+		"kern.ipc.seminfo",
+		"kern.ipc.msginfo",
+		"kern.ipc.msqids",
+		"kern.ipc.shminfo",
+		"kern.ipc.shmsegs" };
+
+	assert((unsigned)idx <= sizeof(sym2sysctl) / sizeof(*sym2sysctl));
+	if (!use_sysctl) {
+		symn = symbols[idx].n_name;
+		if (*symn == '_')
+			symn++;
+		if (symbols[idx].n_type == 0 || symbols[idx].n_value == 0)
+			errx(1, "symbol %s undefined", symn);
+		/*
+		 * For some symbols, the value we retreieve is
+		 * actually a pointer; since we want the actual value,
+		 * we have to manually dereference it.
+		 */
+		switch (idx) {
+		case X_MSQIDS:
+			tsiz = sizeof(msqids);
+			rv = kvm_read(kd, symbols[idx].n_value,
+			    &msqids, tsiz);
+			kaddr = (u_long)msqids;
+			break;
+		case X_SHMSEGS:
+			tsiz = sizeof(shmsegs);
+			rv = kvm_read(kd, symbols[idx].n_value,
+			    &shmsegs, tsiz);
+			kaddr = (u_long)shmsegs;
+			break;
+		case X_SEMA:
+			tsiz = sizeof(sema);
+			rv = kvm_read(kd, symbols[idx].n_value,
+			    &sema, tsiz);
+			kaddr = (u_long)sema;
+			break;
+		default:
+			rv = tsiz = 0;
+			kaddr = symbols[idx].n_value;
+			break;
+		}
+		if ((unsigned)rv != tsiz)
+			errx(1, "%s: %s", symn, kvm_geterr(kd));
+		if ((unsigned)kvm_read(kd, kaddr, addr, size) != size)
+			errx(1, "%s: %s", symn, kvm_geterr(kd));
+	} else {
+		switch (idx) {
+		case X_SHMINFO:
+			sysctlgatherstruct(addr, size, shminfo_scgsv);
+			break;
+		case X_SEMINFO:
+			sysctlgatherstruct(addr, size, seminfo_scgsv);
+			break;
+		case X_MSGINFO:
+			sysctlgatherstruct(addr, size, msginfo_scgsv);
+			break;
+		default:
+			tsiz = size;
+			rv = sysctlbyname(sym2sysctl[idx], addr, &tsiz,
+			    NULL, 0);
+			if (rv == -1)
+				err(1, "sysctlbyname: %s", sym2sysctl[idx]);
+			if (tsiz != size)
+				errx(1, "%s size mismatch "
+				    "(expected %d, got %d)",
+				    sym2sysctl[idx], size, tsiz);
+			break;
+		}
+	}
+}
+
+void
 usage()
 {
 
 	fprintf(stderr,
-	    "usage: ipcs [-abcmopqst] [-C corefile] [-N namelist]\n");
+	    "usage: ipcs [-abcmopqsty] [-C corefile] [-N namelist]\n");
 	exit(1);
 }


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-audit" in the body of the message




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