From owner-freebsd-audit Sun May 20 16:18:10 2001 Delivered-To: freebsd-audit@freebsd.org Received: from bazooka.unixfreak.org (bazooka.unixfreak.org [63.198.170.138]) by hub.freebsd.org (Postfix) with ESMTP id 15A3937B424 for ; Sun, 20 May 2001 16:17:56 -0700 (PDT) (envelope-from dima@unixfreak.org) Received: from spike.unixfreak.org (spike [63.198.170.139]) by bazooka.unixfreak.org (Postfix) with ESMTP id 10A2B3E0B for ; Sun, 20 May 2001 16:17:52 -0700 (PDT) To: audit@freebsd.org Subject: Patch to remove setgid bit from ipcs(1) Date: Sun, 20 May 2001 16:17:51 -0700 From: Dima Dorfman Message-Id: <20010520231752.10A2B3E0B@bazooka.unixfreak.org> Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG Hi folks, Please review the attached patch to convert ipcs(1) to use sysctl's to get the information it needs. The patch also adds a number of sysctl's to kern/sysv*.c in order to facilitate ipcs' needs. This patch is identical to the one I sent to -hackers except for changing the new -y flag to be more consistent with the rest of the world. As before, the patch maintains ipcs' ability to use kvm to get the information it needs. Please review. Thanks in advance, 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/20 22:54:55 @@ -1166,3 +1166,17 @@ 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_STRUCT(_kern_ipc, OID_AUTO, msginfo, CTLFLAG_RD, &msginfo, msginfo, + "System V message info"); +SYSCTL_PROC(_kern_ipc, OID_AUTO, msqids, CTLFLAG_ANYBODY | 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/20 22:54:55 @@ -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,9 @@ 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_STRUCT(_kern_ipc, OID_AUTO, seminfo, CTLFLAG_RD, &seminfo, seminfo, ""); +SYSCTL_PROC(_kern_ipc, OID_AUTO, sema, CTLFLAG_RD | CTLFLAG_ANYBODY, + NULL, 0, sysctl_sema, "", ""); #if 0 RO seminfo.semmap /* SEMMAP unused */ @@ -1065,4 +1069,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.56 diff -u -r1.56 sysv_shm.c --- sys/kern/sysv_shm.c 2001/05/19 01:28:03 1.56 +++ sys/kern/sysv_shm.c 2001/05/20 22:54:55 @@ -102,6 +102,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 @@ -142,6 +143,9 @@ SYSCTL_INT(_kern_ipc, OID_AUTO, shmseg, CTLFLAG_RD, &shminfo.shmseg, 0, ""); 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_STRUCT(_kern_ipc, OID_AUTO, shminfo, CTLFLAG_RD, &shminfo, shminfo, ""); +SYSCTL_PROC(_kern_ipc, OID_AUTO, shmsegs, CTLFLAG_ANYBODY | CTLFLAG_RD, + NULL, 0, sysctl_shmsegs, "", ""); static int shm_find_segment_by_key(key) @@ -708,6 +716,13 @@ shm_committed = 0; shmexit_hook = &shmexit_myhook; shmfork_hook = &shmfork_myhook; +} + +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/20 22:54:55 @@ -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/20 22:54:55 @@ -30,6 +30,7 @@ "$FreeBSD: src/usr.bin/ipcs/ipcs.c,v 1.14 2000/05/01 10:49:41 peter Exp $"; #endif /* not lint */ +#include #include #include #include @@ -43,12 +44,14 @@ #include #include #include +#include #define _KERNEL #include #include #include #include +int use_sysctl = 1; struct semid_ds *sema; struct seminfo seminfo; struct msginfo msginfo; @@ -56,6 +59,7 @@ struct shminfo shminfo; struct shmid_ds *shmsegs; +void kget __P((int idx, void *addr, size_t size)); void usage __P((void)); static struct nlist symbols[] = { @@ -63,16 +67,14 @@ #define X_SEMA 0 {"_seminfo"}, #define X_SEMINFO 1 - {"_semu"}, -#define X_SEMU 2 {"_msginfo"}, -#define X_MSGINFO 3 +#define X_MSGINFO 2 {"_msqids"}, -#define X_MSQIDS 4 +#define X_MSQIDS 3 {"_shminfo"}, -#define X_SHMINFO 5 +#define X_SHMINFO 4 {"_shmsegs"}, -#define X_SHMSEGS 6 +#define X_SHMSEGS 5 {NULL} }; @@ -137,7 +139,7 @@ char *core = NULL, *namelist = NULL; 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 +186,45 @@ 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()); + use_sysctl = 0; - if ((kd = kvm_open(namelist, core, NULL, O_RDONLY, "ipcs")) == NULL) - exit(1); + if (!use_sysctl) { + if ((kd = kvm_open(namelist, core, NULL, O_RDONLY, "ipcs")) + == NULL) + exit(1); - switch (kvm_nlist(kd, symbols)) { - case 0: - break; - case -1: - errx(1, "unable to read kernel symbol table"); - default: + 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 +242,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 +314,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 +332,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 +402,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 +432,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 +484,82 @@ 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 +kget(idx, addr, size) + int idx; + void *addr; + size_t size; +{ + char *symn; /* symbol name */ + int rv, tsiz; + unsigned long kaddr; + 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(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 (rv != tsiz) + errx(1, "%s: %s", symn, kvm_geterr(kd)); + if (kvm_read(kd, kaddr, addr, size) != size) + errx(1, "%s: %s", symn, kvm_geterr(kd)); + } else { + tsiz = size; + if (sysctlbyname(sym2sysctl[idx], addr, &tsiz, NULL, 0) + == -1) + err(1, "sysctlbyname: %s", sym2sysctl[idx]); + } +} + +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