From owner-freebsd-audit Sun May 6 11:34:31 2001 Delivered-To: freebsd-audit@freebsd.org Received: from nebula.cybercable.fr (d189.dhcp212-126.cybercable.fr [212.198.126.189]) by hub.freebsd.org (Postfix) with ESMTP id 2AD2437B422 for ; Sun, 6 May 2001 11:34:27 -0700 (PDT) (envelope-from mux@qualys.com) Received: (from mux@localhost) by nebula.cybercable.fr (8.11.3/8.11.3) id f46IYML06718 for audit@FreeBSD.org; Sun, 6 May 2001 20:34:22 +0200 (CEST) (envelope-from mux) Date: Sun, 6 May 2001 20:34:22 +0200 From: Maxime Henrion To: audit@FreeBSD.org Subject: Patch for wall.c from OpenBSD Message-ID: <20010506203422.D673@nebula.cybercable.fr> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="R3G7APHDIzY6R/pk" Content-Disposition: inline User-Agent: Mutt/1.2.5i Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG --R3G7APHDIzY6R/pk Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hi, This patch makes wall open the file with the egid. It was taken from the OpenBSD commits of Kris mailbox. I have ripped out the err() -> errx() changes and fixed the non-style(9) compliant declaration. Maxime -- Don't be fooled by cheap finnish imitations ; BSD is the One True Code Key fingerprint = F9B6 1D5A 4963 331C 88FC CA6A AB50 1EF2 8CBE 99D6 Public Key : http://www.epita.fr/~henrio_m/ --R3G7APHDIzY6R/pk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="wall.c.diff" *** /usr/src/usr.bin/wall/wall.c Fri Mar 2 08:30:37 2001 --- wall.c Sun May 6 20:29:49 2001 *************** *** 189,194 **** --- 189,195 ---- int fd; char *p, *tty, hostname[MAXHOSTNAMELEN], lbuf[256], tmpname[64]; const char *whom; + gid_t egid; (void)snprintf(tmpname, sizeof(tmpname), "%s/wall.XXXXXX", _PATH_TMP); if ((fd = mkstemp(tmpname)) == -1 || !(fp = fdopen(fd, "r+"))) *************** *** 225,232 **** } (void)fprintf(fp, "%79s\r\n", " "); ! if (fname && !(freopen(fname, "r", stdin))) ! err(1, "can't read %s", fname); while (fgets(lbuf, sizeof(lbuf), stdin)) for (cnt = 0, p = lbuf; (ch = *p) != '\0'; ++p, ++cnt) { if (ch == '\r') { --- 226,238 ---- } (void)fprintf(fp, "%79s\r\n", " "); ! if (fname) { ! egid = getegid(); ! setegid(getgid()); ! if (freopen(fname, "r", stdin) == NULL) ! err(1, "can't read %s", fname); ! setegid(egid); ! } while (fgets(lbuf, sizeof(lbuf), stdin)) for (cnt = 0, p = lbuf; (ch = *p) != '\0'; ++p, ++cnt) { if (ch == '\r') { --R3G7APHDIzY6R/pk-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Sun May 6 11:37:52 2001 Delivered-To: freebsd-audit@freebsd.org Received: from rover.village.org (rover.bsdimp.com [204.144.255.66]) by hub.freebsd.org (Postfix) with ESMTP id 5EBA237B424 for ; Sun, 6 May 2001 11:37:50 -0700 (PDT) (envelope-from imp@billy-club.village.org) Received: from billy-club.village.org (billy-club.village.org [10.0.0.3]) by rover.village.org (8.11.2/8.11.0) with ESMTP id f46Iblj62772; Sun, 6 May 2001 12:37:48 -0600 (MDT) (envelope-from imp@billy-club.village.org) Received: from billy-club.village.org (localhost [127.0.0.1]) by billy-club.village.org (8.11.2/8.8.3) with ESMTP id f46IcPl54954; Sun, 6 May 2001 12:38:25 -0600 (MDT) Message-Id: <200105061838.f46IcPl54954@billy-club.village.org> To: Maxime Henrion Subject: Re: Patch for wall.c from OpenBSD Cc: audit@FreeBSD.ORG In-reply-to: Your message of "Sun, 06 May 2001 20:34:22 +0200." <20010506203422.D673@nebula.cybercable.fr> References: <20010506203422.D673@nebula.cybercable.fr> Date: Sun, 06 May 2001 12:38:25 -0600 From: Warner Losh Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG In message <20010506203422.D673@nebula.cybercable.fr> Maxime Henrion writes: : This patch makes wall open the file with the egid. It was taken from : the OpenBSD commits of Kris mailbox. I have ripped out the err() -> : errx() changes and fixed the non-style(9) compliant declaration. This patch looks good to me. It does assume that wall is at most setgid (since it doesn't drop the uid), but that's likely a safe assumption. Warner To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Tue May 8 0:19:50 2001 Delivered-To: freebsd-audit@freebsd.org Received: from obsecurity.dyndns.org (adsl-63-207-60-108.dsl.lsan03.pacbell.net [63.207.60.108]) by hub.freebsd.org (Postfix) with ESMTP id 504B237B422 for ; Tue, 8 May 2001 00:19:46 -0700 (PDT) (envelope-from kris@obsecurity.org) Received: by obsecurity.dyndns.org (Postfix, from userid 1000) id 8FB2767AF7; Tue, 8 May 2001 00:19:45 -0700 (PDT) Date: Tue, 8 May 2001 00:19:45 -0700 From: Kris Kennaway To: audit@FreeBSD.org Subject: fstat patches Message-ID: <20010508001945.A86617@xor.obsecurity.org> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-md5; protocol="application/pgp-signature"; boundary="WIyZ46R2i8wDzkSu" Content-Disposition: inline User-Agent: Mutt/1.2.5i Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG --WIyZ46R2i8wDzkSu Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable These are taken from OpenBSD. Please review: I don't know if the setegid() changes actually serve a purpose..can anyone explain it to me? Kris Index: fstat.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /mnt/ncvs/src/usr.bin/fstat/fstat.c,v retrieving revision 1.29 diff -u -r1.29 fstat.c --- fstat.c 2001/05/01 08:46:00 1.29 +++ fstat.c 2001/05/08 07:16:33 @@ -231,11 +231,17 @@ * Discard setgid privileges if not the running kernel so that bad * guys can't print interesting stuff from kernel memory. */ - if (nlistf !=3D NULL || memf !=3D NULL) + if (nlistf !=3D NULL || memf !=3D NULL) { + setegid(getgid()); setgid(getgid()); + } =20 if ((kd =3D kvm_openfiles(nlistf, memf, NULL, O_RDONLY, buf)) =3D=3D NULL) errx(1, "%s", buf); + + setegid(getgid()); + setgid(getgid()); + #ifdef notdef if (kvm_nlist(kd, nl) !=3D 0) errx(1, "no namelist: %s", kvm_geterr(kd)); @@ -479,7 +485,7 @@ break; =09 default: { - static char unknown[10]; + static char unknown[20]; sprintf(badtype =3D unknown, "?(%x)", vn.v_tag); break;; } @@ -697,7 +703,7 @@ struct inpcb inpcb; struct unpcb unpcb; int len; - char dname[32], *strcpy(); + char dname[32]; =20 PREFIX(i); =20 @@ -722,7 +728,7 @@ } =20 if ((len =3D kvm_read(kd, (u_long)dom.dom_name, dname, - sizeof(dname) - 1)) < 0) { + sizeof(dname) - 1)) !=3D sizeof(dname) -1) { dprintf(stderr, "can't read domain name at %p\n", (void *)dom.dom_name); dname[0] =3D '\0'; --WIyZ46R2i8wDzkSu Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.5 (FreeBSD) Comment: For info see http://www.gnupg.org iD8DBQE6954QWry0BWjoQKURAsnRAJoCfTy2j6RqQPWkf12ex8TANtTmKwCeMm31 kLEReyjFUAKFIvxXdFatMRs= =kSJz -----END PGP SIGNATURE----- --WIyZ46R2i8wDzkSu-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Tue May 8 0:33:30 2001 Delivered-To: freebsd-audit@freebsd.org Received: from obsecurity.dyndns.org (adsl-63-207-60-108.dsl.lsan03.pacbell.net [63.207.60.108]) by hub.freebsd.org (Postfix) with ESMTP id 7C6EF37B422 for ; Tue, 8 May 2001 00:33:25 -0700 (PDT) (envelope-from kris@obsecurity.org) Received: by obsecurity.dyndns.org (Postfix, from userid 1000) id 1962567AF7; Tue, 8 May 2001 00:33:25 -0700 (PDT) Date: Tue, 8 May 2001 00:33:24 -0700 From: Kris Kennaway To: audit@FreeBSD.org Subject: ipcs patch Message-ID: <20010508003324.A87133@xor.obsecurity.org> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-md5; protocol="application/pgp-signature"; boundary="M9NhX3UHpAaciwkO" Content-Disposition: inline User-Agent: Mutt/1.2.5i Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG --M9NhX3UHpAaciwkO Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable This is partly taken from OpenBSD, the fixes to the alignment of the output are mine. Kris Index: ipcs.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /mnt/ncvs/src/usr.bin/ipcs/ipcs.c,v retrieving revision 1.14 diff -u -r1.14 ipcs.c --- ipcs.c 2000/05/01 10:49:41 1.14 +++ ipcs.c 2001/05/08 07:31:56 @@ -192,12 +192,17 @@ * Discard setgid privileges if not the running kernel so that bad * guys can't print interesting stuff from kernel memory. */ - if (namelist !=3D NULL || core !=3D NULL) + if (namelist !=3D NULL || core !=3D NULL) { + setegid(getgid()); setgid(getgid()); + } =20 if ((kd =3D kvm_open(namelist, core, NULL, O_RDONLY, "ipcs")) =3D=3D NULL) exit(1); =20 + setegid(getgid()); + setgid(getgid()); + switch (kvm_nlist(kd, symbols)) { case 0: break; @@ -240,7 +245,7 @@ kvm_read(kd, (u_long) msqids, xmsqids, sizeof(struct msqid_ds) * msginf= o.msgmni); =20 printf("Message Queues:\n"); - printf("T ID KEY MODE OWNER GROUP"); + printf("T ID KEY MODE OWNER GROUP"); if (option & CREATOR) printf(" CREATOR CGROUP"); if (option & OUTSTANDING) @@ -262,7 +267,7 @@ cvt_time(msqptr->msg_rtime, rtime_buf); cvt_time(msqptr->msg_ctime, ctime_buf); =20 - printf("q %6d %10d %s %8s %8s", + printf("q %8d %10d %s %8s %8s", IXSEQ_TO_IPCID(i, msqptr->msg_perm), msqptr->msg_perm.key, fmt_perm(msqptr->msg_perm.mode), @@ -328,7 +333,7 @@ shminfo.shmmni); =20 printf("Shared Memory:\n"); - printf("T ID KEY MODE OWNER GROUP"); + printf("T ID KEY MODE OWNER GROUP"); if (option & CREATOR) printf(" CREATOR CGROUP"); if (option & OUTSTANDING) @@ -350,7 +355,7 @@ cvt_time(shmptr->shm_dtime, dtime_buf); cvt_time(shmptr->shm_ctime, ctime_buf); =20 - printf("m %6d %10d %s %8s %8s", + printf("m %8d %10d %s %8s %8s", IXSEQ_TO_IPCID(i, shmptr->shm_perm), shmptr->shm_perm.key, fmt_perm(shmptr->shm_perm.mode), @@ -424,7 +429,7 @@ kvm_read(kd, (u_long) sema, xsema, sizeof(struct semid_ds) * seminfo.se= mmni); =20 printf("Semaphores:\n"); - printf("T ID KEY MODE OWNER GROUP"); + printf("T ID KEY MODE OWNER GROUP"); if (option & CREATOR) printf(" CREATOR CGROUP"); if (option & BIGGEST) @@ -440,7 +445,7 @@ cvt_time(semaptr->sem_otime, otime_buf); cvt_time(semaptr->sem_ctime, ctime_buf); =20 - printf("s %6d %10d %s %8s %8s", + printf("s %8d %10d %s %8s %8s", IXSEQ_TO_IPCID(i, semaptr->sem_perm), semaptr->sem_perm.key, fmt_perm(semaptr->sem_perm.mode), --M9NhX3UHpAaciwkO Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.5 (FreeBSD) Comment: For info see http://www.gnupg.org iD8DBQE696FEWry0BWjoQKURAnBdAKDbNKA2wwNZXVowqPA16pYD+ncdbACgjT4l tCRhsTfvzTtf772nKTHH6yY= =By7g -----END PGP SIGNATURE----- --M9NhX3UHpAaciwkO-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Tue May 8 0:42: 0 2001 Delivered-To: freebsd-audit@freebsd.org Received: from ringworld.nanolink.com (ringworld.nanolink.com [195.24.48.13]) by hub.freebsd.org (Postfix) with SMTP id EADB737B42C for ; Tue, 8 May 2001 00:41:57 -0700 (PDT) (envelope-from roam@orbitel.bg) Received: (qmail 59324 invoked by uid 1000); 8 May 2001 07:40:09 -0000 Date: Tue, 8 May 2001 10:40:09 +0300 From: Peter Pentchev To: Kris Kennaway Cc: audit@FreeBSD.org Subject: Re: fstat patches Message-ID: <20010508104009.A59278@ringworld.oblivion.bg> Mail-Followup-To: Kris Kennaway , audit@FreeBSD.org References: <20010508001945.A86617@xor.obsecurity.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5i In-Reply-To: <20010508001945.A86617@xor.obsecurity.org>; from kris@obsecurity.org on Tue, May 08, 2001 at 12:19:45AM -0700 Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG On Tue, May 08, 2001 at 12:19:45AM -0700, Kris Kennaway wrote: > These are taken from OpenBSD. Please review: I don't know if the > setegid() changes actually serve a purpose..can anyone explain it to > me? Well, now that you're looking at fstat(1), could you also take a look at PR bin/26637, making fstat display FIFO's instead of reporting them as unknown struct file's? G'luck, Peter -- This sentence is false. To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Tue May 8 0:48: 0 2001 Delivered-To: freebsd-audit@freebsd.org Received: from obsecurity.dyndns.org (adsl-63-207-60-108.dsl.lsan03.pacbell.net [63.207.60.108]) by hub.freebsd.org (Postfix) with ESMTP id 2843137B424 for ; Tue, 8 May 2001 00:47:58 -0700 (PDT) (envelope-from kris@obsecurity.org) Received: by obsecurity.dyndns.org (Postfix, from userid 1000) id A75D167AF7; Tue, 8 May 2001 00:47:57 -0700 (PDT) Date: Tue, 8 May 2001 00:47:57 -0700 From: Kris Kennaway To: Peter Pentchev Cc: Kris Kennaway , audit@FreeBSD.ORG Subject: Re: fstat patches Message-ID: <20010508004757.A87304@xor.obsecurity.org> References: <20010508001945.A86617@xor.obsecurity.org> <20010508104009.A59278@ringworld.oblivion.bg> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-md5; protocol="application/pgp-signature"; boundary="r5Pyd7+fXNt84Ff3" Content-Disposition: inline User-Agent: Mutt/1.2.5i In-Reply-To: <20010508104009.A59278@ringworld.oblivion.bg>; from roam@orbitel.bg on Tue, May 08, 2001 at 10:40:09AM +0300 Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG --r5Pyd7+fXNt84Ff3 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Tue, May 08, 2001 at 10:40:09AM +0300, Peter Pentchev wrote: > On Tue, May 08, 2001 at 12:19:45AM -0700, Kris Kennaway wrote: > > These are taken from OpenBSD. Please review: I don't know if the > > setegid() changes actually serve a purpose..can anyone explain it to > > me? >=20 > Well, now that you're looking at fstat(1), could you also take a look > at PR bin/26637, making fstat display FIFO's instead of reporting them > as unknown struct file's? Sorry, I don't have the time to get into the code right now. Kris --r5Pyd7+fXNt84Ff3 Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.5 (FreeBSD) Comment: For info see http://www.gnupg.org iD8DBQE696StWry0BWjoQKURAgdsAJ9VITVOl+cy30dWl8YDV84MU03PggCfdtXp dfT+ZWCxV4/2OavTXnwOc+A= =sHBL -----END PGP SIGNATURE----- --r5Pyd7+fXNt84Ff3-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Tue May 8 1:39:34 2001 Delivered-To: freebsd-audit@freebsd.org Received: from harmony.village.org (rover.bsdimp.com [204.144.255.66]) by hub.freebsd.org (Postfix) with ESMTP id B3ACC37B424 for ; Tue, 8 May 2001 01:39:32 -0700 (PDT) (envelope-from imp@harmony.village.org) Received: from harmony.village.org (localhost.village.org [127.0.0.1]) by harmony.village.org (8.11.3/8.11.1) with ESMTP id f488dPb79246; Tue, 8 May 2001 02:39:29 -0600 (MDT) (envelope-from imp@harmony.village.org) Message-Id: <200105080839.f488dPb79246@harmony.village.org> To: Kris Kennaway Subject: Re: fstat patches Cc: audit@FreeBSD.org In-reply-to: Your message of "Tue, 08 May 2001 00:19:45 PDT." <20010508001945.A86617@xor.obsecurity.org> References: <20010508001945.A86617@xor.obsecurity.org> Date: Tue, 08 May 2001 02:39:25 -0600 From: Warner Losh Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG In message <20010508001945.A86617@xor.obsecurity.org> Kris Kennaway writes: : These are taken from OpenBSD. Please review: I don't know if the : setegid() changes actually serve a purpose..can anyone explain it to : me? fstat is supposed to run setgid kmem. I think in FreeBSD the setegid is a noop for this situation. Theo is fond of tossing them in. OpenBSD has slightly different set*id semantics and it would be best to verify my analysis by checking there. our setgid says: The setgid() function sets the real and effective group IDs and the saved set-group-ID of the current process to the specified value. The setgid() function is permitted if the specified ID is equal to the real group ID or the effective group ID of the process, or if the effective user ID is that of the super user. Warner To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Tue May 8 2:11:28 2001 Delivered-To: freebsd-audit@freebsd.org Received: from obsecurity.dyndns.org (adsl-63-207-60-108.dsl.lsan03.pacbell.net [63.207.60.108]) by hub.freebsd.org (Postfix) with ESMTP id CDA0137B422 for ; Tue, 8 May 2001 02:11:25 -0700 (PDT) (envelope-from kris@obsecurity.org) Received: by obsecurity.dyndns.org (Postfix, from userid 1000) id 6952667AF7; Tue, 8 May 2001 02:11:25 -0700 (PDT) Date: Tue, 8 May 2001 02:11:25 -0700 From: Kris Kennaway To: Warner Losh Cc: Kris Kennaway , audit@FreeBSD.org Subject: Re: fstat patches Message-ID: <20010508021125.A89909@xor.obsecurity.org> References: <20010508001945.A86617@xor.obsecurity.org> <200105080839.f488dPb79246@harmony.village.org> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-md5; protocol="application/pgp-signature"; boundary="ReaqsoxgOBHFXBhH" Content-Disposition: inline User-Agent: Mutt/1.2.5i In-Reply-To: <200105080839.f488dPb79246@harmony.village.org>; from imp@harmony.village.org on Tue, May 08, 2001 at 02:39:25AM -0600 Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG --ReaqsoxgOBHFXBhH Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Tue, May 08, 2001 at 02:39:25AM -0600, Warner Losh wrote: > In message <20010508001945.A86617@xor.obsecurity.org> Kris Kennaway write= s: > : These are taken from OpenBSD. Please review: I don't know if the > : setegid() changes actually serve a purpose..can anyone explain it to > : me? >=20 > fstat is supposed to run setgid kmem. I think in FreeBSD the setegid > is a noop for this situation. Theo is fond of tossing them in. > OpenBSD has slightly different set*id semantics and it would be best > to verify my analysis by checking there. >=20 > our setgid says: > The setgid() function sets the real and effective group IDs and the = saved > set-group-ID of the current process to the specified value. The set= gid() > function is permitted if the specified ID is equal to the real group= ID > or the effective group ID of the process, or if the effective user I= D is > that of the super user. Yeah, I compared with the OpenBSD setuid(2) manpage and couldn't notice any different semantics..I'm not sure why they did this, but there was presumably some motivation for the change. Kris --ReaqsoxgOBHFXBhH Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.5 (FreeBSD) Comment: For info see http://www.gnupg.org iD8DBQE697g8Wry0BWjoQKURAswzAKCrfpjFc8uYXSwp6lbHYBwzng1eBwCfY9D1 WxBMeP3rHu0Nc9nqANTFpbw= =2Z4p -----END PGP SIGNATURE----- --ReaqsoxgOBHFXBhH-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Tue May 8 3:24:43 2001 Delivered-To: freebsd-audit@freebsd.org Received: from obsecurity.dyndns.org (adsl-63-207-60-108.dsl.lsan03.pacbell.net [63.207.60.108]) by hub.freebsd.org (Postfix) with ESMTP id C78A837B422 for ; Tue, 8 May 2001 03:24:37 -0700 (PDT) (envelope-from kris@obsecurity.org) Received: by obsecurity.dyndns.org (Postfix, from userid 1000) id 0321967AFA; Tue, 8 May 2001 03:24:33 -0700 (PDT) Date: Tue, 8 May 2001 03:24:33 -0700 From: Kris Kennaway To: audit@FreeBSD.org Subject: ping security fixes Message-ID: <20010508032432.A91836@xor.obsecurity.org> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-md5; protocol="application/pgp-signature"; boundary="mYCpIKhGyMATD0i+" Content-Disposition: inline User-Agent: Mutt/1.2.5i Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG --mYCpIKhGyMATD0i+ Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable This patch is taken from OpenBSD. I don't know if the IP option stuff is exploitable in theory -- we merged some option-parsing fixes a few years ago, but missed the rest which were committed to OpenBSD a few weeks later. The other buffer sizing issue doesn't seem to be exploitable on FreeBSD for two reasons: a) The receive buffer size is artificially limited to 48K b) The send buffer size is not resized from the default value, and ping limits the length of ICMP_ECHOREPLY packets it reads to 112 bytes longer than the packet it sent out (I don't know if this is a bug or not). OpenBSD had removed both of these limitations which allowed them to overflow that buffer by 68 bytes or so; even then I couldn't get it to do anything nasty because of where the buffer sits in memory. Anyway. Kris Index: ping.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /mnt/ncvs/src/sbin/ping/ping.c,v retrieving revision 1.55 diff -u -r1.55 ping.c --- ping.c 2001/03/09 13:20:23 1.55 +++ ping.c 2001/05/08 10:18:22 @@ -102,7 +102,7 @@ /* runs out of buffer space */ #define MAXIPLEN 60 #define MAXICMPLEN 76 -#define MAXPACKET (65536 - 60 - 8)/* max packet size */ +#define MAXPAYLOAD (IP_MAXPACKET - MAXIPLEN - 8) /* max ICMP payload size = */ #define MAXWAIT 10 /* max seconds to wait for response */ #define MAXALARM (60 * 60) /* max seconds for alarm timeout */ #define NROUTES 9 /* number of record route slots */ @@ -148,7 +148,7 @@ struct sockaddr whereto; /* who to ping */ int datalen =3D DEFDATALEN; int s; /* socket file descriptor */ -u_char outpack[MAXPACKET]; +u_char outpack[IP_MAXPACKET]; /* Max packet size =3D 65535 */ char BSPACE =3D '\b'; /* characters written for flood */ char DOT =3D '.'; char *hostname; @@ -341,7 +341,7 @@ err(EX_NOPERM, "-s flag"); } ultmp =3D strtoul(optarg, &ep, 0); - if (ultmp > MAXPACKET) + if (ultmp > MAXPAYLOAD) errx(EX_USAGE, "packet size too large: %lu", ultmp); if (*ep || ep =3D=3D optarg || !ultmp) @@ -785,7 +785,7 @@ register struct icmp *icp; register u_long l; register int i, j; - register u_char *cp,*dp; + register u_char *cp, *dp; static int old_rrlen; static char old_rr[MAX_IPOPTLEN]; struct ip *ip; @@ -926,7 +926,8 @@ hlen -=3D 2; j =3D *++cp; ++cp; - if (j > IPOPT_MINOFF) + i =3D 0; + if (j > IPOPT_MINOFF) { for (;;) { l =3D *++cp; l =3D (l<<8) + *++cp; @@ -939,11 +940,18 @@ ina.s_addr =3D ntohl(l); printf("\t%s", pr_addr(ina)); } - hlen -=3D 4; - j -=3D 4; - if (j <=3D IPOPT_MINOFF) - break; - (void)putchar('\n'); + hlen -=3D 4; + j -=3D 4; + i +=3D 4; + if (j <=3D IPOPT_MINOFF) + break; + if (i >=3D MAX_IPOPTLEN) { + (void)printf("\t(truncated route)"); + break; + } + (void)putchar('\n'); + } + =09 } break; case IPOPT_RR: @@ -1002,6 +1010,8 @@ break; default: (void)printf("\nunknown option %x", *cp); + hlen =3D hlen + cp[1] - 1; + cp =3D cp + cp[1] - 1; break; } if (!(options & F_FLOOD)) { @@ -1402,7 +1412,7 @@ =20 if (ii > 0) for (kk =3D 0; - kk <=3D MAXPACKET - (8 + PHDR_LEN + ii); + kk <=3D MAXPAYLOAD - (8 + PHDR_LEN + ii); kk +=3D ii) for (jj =3D 0; jj < ii; ++jj) bp[jj + kk] =3D pat[jj]; --mYCpIKhGyMATD0i+ Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.5 (FreeBSD) Comment: For info see http://www.gnupg.org iD8DBQE698lfWry0BWjoQKURAkc0AJ99zBCatUjGzBdTdrpvG3uuEfYuIgCgquRP GntaGMNMgXYgF19c1PX/v1g= =jH05 -----END PGP SIGNATURE----- --mYCpIKhGyMATD0i+-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Tue May 8 4: 4: 0 2001 Delivered-To: freebsd-audit@freebsd.org Received: from obsecurity.dyndns.org (adsl-63-207-60-108.dsl.lsan03.pacbell.net [63.207.60.108]) by hub.freebsd.org (Postfix) with ESMTP id E1B2937B423 for ; Tue, 8 May 2001 04:03:54 -0700 (PDT) (envelope-from kris@obsecurity.org) Received: by obsecurity.dyndns.org (Postfix, from userid 1000) id B8BF067AFA; Tue, 8 May 2001 04:03:48 -0700 (PDT) Date: Tue, 8 May 2001 04:03:48 -0700 From: Kris Kennaway To: audit@FreeBSD.org Subject: ping6 fixes Message-ID: <20010508040347.A93281@xor.obsecurity.org> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-md5; protocol="application/pgp-signature"; boundary="fdj2RfSjLxBAspz7" Content-Disposition: inline User-Agent: Mutt/1.2.5i Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG --fdj2RfSjLxBAspz7 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Turns out ping6 wasn't dropping root privs..I don't think this is necessarily a problem, but it's bad practise. The patch again uses seteuid() which is probably a NOP, but that's what KAME have now (obtained from OpenBSD), so we might as well do it. I also merged the superuser limitation on the '-s' flag. Still to do are to check/fix the SIGALRM signal handling fixes from ping. Kris Index: ping6.8 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /mnt/ncvs/src/sbin/ping6/ping6.8,v retrieving revision 1.9 diff -u -r1.9 ping6.8 --- ping6.8 2001/02/22 19:00:51 1.9 +++ ping6.8 2001/05/08 10:59:15 @@ -259,6 +259,7 @@ You may need to specify .Fl b as well to extend socket buffer size. +Only the super-user may use this option. .It Fl v Verbose output. .Tn ICMP Index: ping6.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /mnt/ncvs/src/sbin/ping6/ping6.c,v retrieving revision 1.8 diff -u -r1.8 ping6.c --- ping6.c 2000/12/04 13:38:59 1.8 +++ ping6.c 2001/05/08 11:01:00 @@ -126,6 +126,7 @@ #include #include #include +#include #include =20 #ifdef IPSEC @@ -423,6 +424,10 @@ usepktinfo++; break; case 's': /* size of packet to send */ + if (getuid()) { + errno =3D EPERM; + err(EX_NOPERM, "-s flag"); + }=09 datalen =3D strtol(optarg, &e, 10); if (datalen <=3D 0 || *optarg =3D=3D '\0' || *e !=3D '\0') errx(1, "illegal datalen value -- %s", optarg); @@ -630,6 +635,10 @@ err(1, "setsockopt(IPV6_RECVRTHDRDSTOPTS)"); #endif } + + /* revoke root privilege */ + seteuid(getuid()); + setuid(getuid()); =20 /* optval =3D 1; --fdj2RfSjLxBAspz7 Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.5 (FreeBSD) Comment: For info see http://www.gnupg.org iD8DBQE699KTWry0BWjoQKURAkr8AJ4zky/G9UblyQP8YD4g/YyzPgBrsQCglvj1 kNI4nDknMKitVu6uromo/Wg= =ra2m -----END PGP SIGNATURE----- --fdj2RfSjLxBAspz7-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Tue May 8 4:13:31 2001 Delivered-To: freebsd-audit@freebsd.org Received: from obsecurity.dyndns.org (adsl-63-207-60-108.dsl.lsan03.pacbell.net [63.207.60.108]) by hub.freebsd.org (Postfix) with ESMTP id B15F837B422 for ; Tue, 8 May 2001 04:13:25 -0700 (PDT) (envelope-from kris@obsecurity.org) Received: by obsecurity.dyndns.org (Postfix, from userid 1000) id D002367AFD; Tue, 8 May 2001 04:13:24 -0700 (PDT) Date: Tue, 8 May 2001 04:13:24 -0700 From: Kris Kennaway To: Maxime Henrion Cc: audit@FreeBSD.ORG Subject: Re: Patch for wall.c from OpenBSD Message-ID: <20010508041324.A93454@xor.obsecurity.org> References: <20010506203422.D673@nebula.cybercable.fr> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-md5; protocol="application/pgp-signature"; boundary="W/nzBZO5zC0uMSeA" Content-Disposition: inline User-Agent: Mutt/1.2.5i In-Reply-To: <20010506203422.D673@nebula.cybercable.fr>; from mux@qualys.com on Sun, May 06, 2001 at 08:34:22PM +0200 Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG --W/nzBZO5zC0uMSeA Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Sun, May 06, 2001 at 08:34:22PM +0200, Maxime Henrion wrote: > Hi, >=20 > This patch makes wall open the file with the egid. It was taken from > the OpenBSD commits of Kris mailbox. I have ripped out the err() -> > errx() changes and fixed the non-style(9) compliant declaration. Committed -- thanks! Kris --W/nzBZO5zC0uMSeA Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.5 (FreeBSD) Comment: For info see http://www.gnupg.org iD8DBQE699TTWry0BWjoQKURAt72AJ9dlwwOBAGjWRoUX5S5l7ZVWLxNgACfcjIf A8/wzF+zYrcqUoI38j3EdQ0= =E3EC -----END PGP SIGNATURE----- --W/nzBZO5zC0uMSeA-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Tue May 8 5:28:45 2001 Delivered-To: freebsd-audit@freebsd.org Received: from whale.sunbay.crimea.ua (whale.sunbay.crimea.ua [212.110.138.65]) by hub.freebsd.org (Postfix) with ESMTP id C83A137B423 for ; Tue, 8 May 2001 05:28:36 -0700 (PDT) (envelope-from ru@whale.sunbay.crimea.ua) Received: (from ru@localhost) by whale.sunbay.crimea.ua (8.11.2/8.11.2) id f48CSGb59888; Tue, 8 May 2001 15:28:16 +0300 (EEST) (envelope-from ru) Date: Tue, 8 May 2001 15:28:16 +0300 From: Ruslan Ermilov To: Kris Kennaway Cc: audit@FreeBSD.ORG Subject: Re: ping6 fixes Message-ID: <20010508152816.A58026@sunbay.com> References: <20010508040347.A93281@xor.obsecurity.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5i In-Reply-To: <20010508040347.A93281@xor.obsecurity.org>; from kris@obsecurity.org on Tue, May 08, 2001 at 04:03:48AM -0700 Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG On Tue, May 08, 2001 at 04:03:48AM -0700, Kris Kennaway wrote: [...] > + > + /* revoke root privilege */ > + seteuid(getuid()); > + setuid(getuid()); > > /* > optval = 1; I still think seteuid() here is superfluous, but see below. I've just checked that OpenBSD's setuid() behaves differently, as mandated by recent POSIX specs. The differences are as follows: In FreeBSD, setuid() function sets the real and effective user IDs and the saved set-user-ID of the current process to the specified value, if the specified ID is equal to the real user ID or the effective user ID of the process, or if the effective user ID is that of the super user. In OpenBSD, the behavior changes a little. The setuid() similarly sets the real and effective user IDs and the saved set-user-ID of the current process to the specified value, if the effective user ID is that of the super user, or if the specified user ID is the same as the effective user ID. (Here follows the difference.) If not, but the specified user ID is the same as the real user ID, setuid() will set the effective user ID to the real user ID. Under OpenBSD, the attached program succeeds: seteuid() to the fake (12345) UID setuid() to the real (1010) UID seteuid() back to the saved (0) UID Under FreeBSD, it fails with: seteuid() to the fake (12345) UID setuid() to the real (1001) UID seteuid() back to the saved (0) UID setuid: seteuid: Operation not permitted Cheers, -- Ruslan Ermilov Oracle Developer/DBA, ru@sunbay.com Sunbay Software AG, ru@FreeBSD.org FreeBSD committer, +380.652.512.251 Simferopol, Ukraine http://www.FreeBSD.org The Power To Serve http://www.oracle.com Enabling The Information Age To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Tue May 8 11:22:30 2001 Delivered-To: freebsd-audit@freebsd.org Received: from mailman.zeta.org.au (mailman.zeta.org.au [203.26.10.16]) by hub.freebsd.org (Postfix) with ESMTP id D510037B507; Tue, 8 May 2001 11:22:21 -0700 (PDT) (envelope-from bde@zeta.org.au) Received: from bde.zeta.org.au (bde.zeta.org.au [203.2.228.102]) by mailman.zeta.org.au (8.9.3/8.8.7) with ESMTP id EAA05606; Wed, 9 May 2001 04:22:14 +1000 Date: Wed, 9 May 2001 04:20:44 +1000 (EST) From: Bruce Evans X-Sender: bde@besplex.bde.org To: Ruslan Ermilov Cc: Kris Kennaway , audit@FreeBSD.ORG Subject: Re: ping6 fixes In-Reply-To: <20010508152816.A58026@sunbay.com> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG On Tue, 8 May 2001, Ruslan Ermilov wrote: > On Tue, May 08, 2001 at 04:03:48AM -0700, Kris Kennaway wrote: > [...] > > + > > + /* revoke root privilege */ > > + seteuid(getuid()); > > + setuid(getuid()); > > > > /* > > optval = 1; > > I still think seteuid() here is superfluous, but see below. > > I've just checked that OpenBSD's setuid() behaves differently, > as mandated by recent POSIX specs. The differences are as > follows: This doesn't seem to be anything recent. I'll check again tomorrow when I'm awake. Does POSIX now mandate _BROKEN^W_POSIX_SAVED_IDS? > ... > > Under OpenBSD, the attached program succeeds: None was attached :-). > seteuid() to the fake (12345) UID > setuid() to the real (1010) UID > seteuid() back to the saved (0) UID > > Under FreeBSD, it fails with: > > seteuid() to the fake (12345) UID > setuid() to the real (1001) UID > seteuid() back to the saved (0) UID > setuid: seteuid: Operation not permitted I think I now understand the purpose of seteuid() before seteuid(). It is to set the euid to a value such that the process has "appropriate privilege" for setuid() to set all the ids. "Appropriate privilege" is implementation-defined and context-dependent. FreeBSD defines it such that everyone has it for the context of setuid() to their real uid, so setuid(getuid()) always works "right". IIRC, this is mainly so that setuid(getuid()) can work at all (when ruid != euid) in the !_POSIX_SAVE_IDS case. When it works, it works "right" -- it must set the euid, and it should set any (non-POSIX) saved ids so that it works the same as on systems without any saved ids. I think this is all POSIX.1-199[0-6] conformant. BSD4.4-style saved ids can be viewed as things that control "appropriate privilege". Bruce To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Tue May 8 17: 5:10 2001 Delivered-To: freebsd-audit@freebsd.org Received: from nebula.cybercable.fr (d189.dhcp212-126.cybercable.fr [212.198.126.189]) by hub.freebsd.org (Postfix) with ESMTP id F3B4C37B422 for ; Tue, 8 May 2001 17:04:51 -0700 (PDT) (envelope-from mux@qualys.com) Received: (from mux@localhost) by nebula.cybercable.fr (8.11.3/8.11.3) id f4904oj42592 for audit@FreeBSD.org; Wed, 9 May 2001 02:04:50 +0200 (CEST) (envelope-from mux) Date: Wed, 9 May 2001 02:04:50 +0200 From: Maxime Henrion To: audit@FreeBSD.org Subject: binutils patch from OpenBSD Message-ID: <20010509020450.A38094@nebula.cybercable.fr> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="gBBFr7Ir9EOA20Yy" Content-Disposition: inline User-Agent: Mutt/1.2.5i Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG --gBBFr7Ir9EOA20Yy Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hi, Here is some more stuff merged from OpenBSD. It avoids calls to insecure choose_temp_base() and changes the make_tempname() interface so that it's able to create either files or directories. It also makes this new interface call the secure mkdtemp() and mkstemp() functions if available. Maxime -- Don't be fooled by cheap finnish imitations ; BSD is the One True Code Key fingerprint = F9B6 1D5A 4963 331C 88FC CA6A AB50 1EF2 8CBE 99D6 Public Key : http://www.epita.fr/~henrio_m/ --gBBFr7Ir9EOA20Yy Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="binutils.diff" diff -c /usr/src/contrib/binutils/binutils/ar.c binutils/ar.c *** /usr/src/contrib/binutils/binutils/ar.c Fri Jul 7 15:34:11 2000 --- binutils/ar.c Wed May 9 01:18:30 2001 *************** *** 1064,1070 **** old_name = xmalloc (strlen (bfd_get_filename (iarch)) + 1); strcpy (old_name, bfd_get_filename (iarch)); ! new_name = make_tempname (old_name); output_filename = new_name; --- 1064,1070 ---- old_name = xmalloc (strlen (bfd_get_filename (iarch)) + 1); strcpy (old_name, bfd_get_filename (iarch)); ! new_name = make_tempname (old_name, 0); output_filename = new_name; diff -c /usr/src/contrib/binutils/binutils/bucomm.c binutils/bucomm.c *** /usr/src/contrib/binutils/binutils/bucomm.c Fri Jul 7 15:34:12 2000 --- binutils/bucomm.c Wed May 9 01:36:05 2001 *************** *** 208,224 **** /* Return the name of a temporary file in the same directory as FILENAME. */ char * ! make_tempname (filename) char *filename; { static char template[] = "stXXXXXX"; char *tmpname; char *slash = strrchr (filename, '/'); #ifdef HAVE_DOS_BASED_FILE_SYSTEM { /* We could have foo/bar\\baz, or foo\\bar, or d:bar. */ char *bslash = strrchr (filename, '\\'); if (bslash > slash) slash = bslash; if (slash == NULL && filename[0] != '\0' && filename[1] == ':') --- 208,228 ---- /* Return the name of a temporary file in the same directory as FILENAME. */ char * ! make_tempname (filename, isdir) char *filename; + int isdir; { static char template[] = "stXXXXXX"; char *tmpname; char *slash = strrchr (filename, '/'); + char c; + int fd; #ifdef HAVE_DOS_BASED_FILE_SYSTEM { /* We could have foo/bar\\baz, or foo\\bar, or d:bar. */ char *bslash = strrchr (filename, '\\'); + if (bslash > slash) slash = bslash; if (slash == NULL && filename[0] != '\0' && filename[1] == ':') *************** *** 228,235 **** if (slash != (char *) NULL) { - char c; - c = *slash; *slash = 0; tmpname = xmalloc (strlen (filename) + sizeof (template) + 2); --- 232,237 ---- *************** *** 243,257 **** #endif strcat (tmpname, "/"); strcat (tmpname, template); - mktemp (tmpname); - *slash = c; } else { tmpname = xmalloc (sizeof (template)); strcpy (tmpname, template); mktemp (tmpname); } return tmpname; } --- 245,286 ---- #endif strcat (tmpname, "/"); strcat (tmpname, template); } else { tmpname = xmalloc (sizeof (template)); strcpy (tmpname, template); + } + + if (isdir) + { + #ifdef HAVE_MKDTEMP + if (mkdtemp (tmpname) != (char *) NULL) + #else mktemp (tmpname); + #if defined (_WIN32) && !defined (__CYGWIN32__) + if (mkdir (tmpname) != 0) + #else + if (mkdir (tmpname, 0700) != 0) + #endif + #endif + tmpname = NULL; } + else + { + #ifdef HAVE_MKSTEMP + fd = mkstemp (tmpname); + if (fd == -1) + tmpname = NULL; + else + close (fd); + #else + mktemp (tmpname); + #endif + } + if (slash != (char *) NULL) + *slash = c; + return tmpname; } diff -c /usr/src/contrib/binutils/binutils/bucomm.h binutils/bucomm.h *** /usr/src/contrib/binutils/binutils/bucomm.h Fri Jul 7 15:34:12 2000 --- binutils/bucomm.h Wed May 9 01:37:18 2001 *************** *** 167,173 **** void print_arelt_descr PARAMS ((FILE *file, bfd *abfd, boolean verbose)); ! char *make_tempname PARAMS ((char *)); bfd_vma parse_vma PARAMS ((const char *, const char *)); --- 167,173 ---- void print_arelt_descr PARAMS ((FILE *file, bfd *abfd, boolean verbose)); ! char *make_tempname PARAMS ((char *, int)); bfd_vma parse_vma PARAMS ((const char *, const char *)); diff -c /usr/src/contrib/binutils/binutils/dlltool.c binutils/dlltool.c *** /usr/src/contrib/binutils/binutils/dlltool.c Fri Jul 7 15:34:17 2000 --- binutils/dlltool.c Wed May 9 01:40:57 2001 *************** *** 1117,1123 **** --- 1117,1127 ---- int i; const char **argv; char *errmsg_fmt, *errmsg_arg; + #if defined (__MSDOS__) && !defined (__GO32__) char *temp_base = choose_temp_base (); + #else + char *temp_base = NULL; + #endif inform ("run: %s %s", what, args); diff -c /usr/src/contrib/binutils/binutils/dllwrap.c binutils/dllwrap.c *** /usr/src/contrib/binutils/binutils/dllwrap.c Fri Jul 7 07:33:30 2000 --- binutils/dllwrap.c Wed May 9 01:42:56 2001 *************** *** 392,398 **** int i; const char **argv; char *errmsg_fmt, *errmsg_arg; ! char *temp_base = choose_temp_base (); int in_quote; char sep; --- 392,402 ---- int i; const char **argv; char *errmsg_fmt, *errmsg_arg; ! #if defined (__MSDOS__) && !defined (__GO32__) ! char *temp_base = choose_temp_base (); ! #else ! char *temp_base = NULL; ! #endif int in_quote; char sep; *************** *** 834,845 **** if (! def_file_seen) { ! char *fileprefix = choose_temp_base (); ! def_file_name = (char *) xmalloc (strlen (fileprefix) + 5); ! sprintf (def_file_name, "%s.def", ! (dontdeltemps) ? mybasename (fileprefix) : fileprefix); ! delete_def_file = 1; ! free (fileprefix); delete_def_file = 1; warn (_("no export definition file provided")); warn (_("creating one, but that may not be what you want")); --- 838,846 ---- if (! def_file_seen) { ! def_file_name = make_temp_file (".def"); ! if (dontdeltemps) ! def_file_name = mybasename (def_file_name); delete_def_file = 1; warn (_("no export definition file provided")); warn (_("creating one, but that may not be what you want")); *************** *** 1022,1033 **** if (! base_file_name) { ! char *fileprefix = choose_temp_base (); ! base_file_name = (char *) xmalloc (strlen (fileprefix) + 6); ! sprintf (base_file_name, "%s.base", ! (dontdeltemps) ? mybasename (fileprefix) : fileprefix); delete_base_file = 1; - free (fileprefix); } { --- 1023,1032 ---- if (! base_file_name) { ! base_file_name = make_temp_file (".base"); ! if (dontdeltemps) ! base_file_name = mybasename (base_file_name); delete_base_file = 1; } { diff -c /usr/src/contrib/binutils/binutils/objcopy.c binutils/objcopy.c *** /usr/src/contrib/binutils/binutils/objcopy.c Sat Nov 25 14:01:33 2000 --- binutils/objcopy.c Wed May 9 01:39:14 2001 *************** *** 1071,1084 **** } *list, *l; bfd **ptr = &obfd->archive_head; bfd *this_element; ! char *dir = make_tempname (bfd_get_filename (obfd)); /* Make a temp directory to hold the contents. */ ! #if defined (_WIN32) && !defined (__CYGWIN32__) ! if (mkdir (dir) != 0) ! #else ! if (mkdir (dir, 0700) != 0) ! #endif { fatal (_("cannot mkdir %s for archive copying (error: %s)"), dir, strerror (errno)); --- 1071,1080 ---- } *list, *l; bfd **ptr = &obfd->archive_head; bfd *this_element; ! char *dir = make_tempname (bfd_get_filename (obfd), 1); /* Make a temp directory to hold the contents. */ ! if (dir == (char *) NULL) { fatal (_("cannot mkdir %s for archive copying (error: %s)"), dir, strerror (errno)); *************** *** 1761,1767 **** if (output_file != NULL) tmpname = output_file; else ! tmpname = make_tempname (argv[i]); status = 0; copy_file (argv[i], tmpname, input_target, output_target); --- 1757,1763 ---- if (output_file != NULL) tmpname = output_file; else ! tmpname = make_tempname (argv[i], 0); status = 0; copy_file (argv[i], tmpname, input_target, output_target); *************** *** 2166,2172 **** if (output_filename == (char *) NULL) { ! char *tmpname = make_tempname (input_filename); copy_file (input_filename, tmpname, input_target, output_target); if (status == 0) --- 2162,2168 ---- if (output_filename == (char *) NULL) { ! char *tmpname = make_tempname (input_filename, 0); copy_file (input_filename, tmpname, input_target, output_target); if (status == 0) diff -c /usr/src/contrib/binutils/binutils/objdump.c binutils/objdump.c *** /usr/src/contrib/binutils/binutils/objdump.c Sat Nov 25 14:01:33 2000 --- binutils/objdump.c Wed May 9 01:15:02 2001 *************** *** 2631,2637 **** char *dummy_name; int t; ! dummy_name = choose_temp_base (); for (t = 0; bfd_target_vector[t]; t++) { bfd_target *p = bfd_target_vector[t]; --- 2631,2637 ---- char *dummy_name; int t; ! dummy_name = make_temp_file (NULL); for (t = 0; bfd_target_vector[t]; t++) { bfd_target *p = bfd_target_vector[t]; *************** *** 2685,2691 **** printf ("%s ", bfd_target_vector[t]->name); putchar ('\n'); ! dummy_name = choose_temp_base (); for (a = (int) bfd_arch_obscure + 1; a < (int) bfd_arch_last; a++) if (strcmp (bfd_printable_arch_mach (a, 0), "UNKNOWN!") != 0) { --- 2685,2691 ---- printf ("%s ", bfd_target_vector[t]->name); putchar ('\n'); ! dummy_name = make_temp_file (NULL); for (a = (int) bfd_arch_obscure + 1; a < (int) bfd_arch_last; a++) if (strcmp (bfd_printable_arch_mach (a, 0), "UNKNOWN!") != 0) { Common subdirectories: /usr/src/contrib/binutils/binutils/po and binutils/po diff -c /usr/src/contrib/binutils/binutils/resrc.c binutils/resrc.c *** /usr/src/contrib/binutils/binutils/resrc.c Fri Jul 7 15:34:26 2000 --- binutils/resrc.c Wed May 9 01:44:39 2001 *************** *** 185,191 **** --- 185,195 ---- int i; const char **argv; char *errmsg_fmt, *errmsg_arg; + #if defined (__MSDOS__) && !defined (__GO32__) char *temp_base = choose_temp_base (); + #else + char *temp_base = NULL; + #endif int in_quote; char sep; int redir_handle = -1; *************** *** 297,308 **** { if (istream_type == ISTREAM_FILE) { ! char *fileprefix; ! ! fileprefix = choose_temp_base (); ! cpp_temp_file = (char *) xmalloc (strlen (fileprefix) + 5); ! sprintf (cpp_temp_file, "%s.irc", fileprefix); ! free (fileprefix); if (run_cmd (cmd, cpp_temp_file)) fatal (_("can't execute `%s': %s"), cmd, strerror (errno)); --- 301,307 ---- { if (istream_type == ISTREAM_FILE) { ! cpp_temp_file = make_temp_file (".irc"); if (run_cmd (cmd, cpp_temp_file)) fatal (_("can't execute `%s': %s"), cmd, strerror (errno)); --gBBFr7Ir9EOA20Yy-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Tue May 8 20:45:53 2001 Delivered-To: freebsd-audit@freebsd.org Received: from fledge.watson.org (fledge.watson.org [204.156.12.50]) by hub.freebsd.org (Postfix) with ESMTP id 57D6B37B422 for ; Tue, 8 May 2001 20:45:49 -0700 (PDT) (envelope-from arr@watson.org) Received: from localhost (arr@localhost) by fledge.watson.org (8.11.3/8.11.3) with SMTP id f493jkn79841 for ; Tue, 8 May 2001 23:45:46 -0400 (EDT) (envelope-from arr@watson.org) Date: Tue, 8 May 2001 23:45:45 -0400 (EDT) From: "Andrew R. Reiter" To: freebsd-audit@freebsd.org Subject: audit work: cmds.c from timedc Message-ID: MIME-Version: 1.0 Content-Type: MULTIPART/MIXED; BOUNDARY="0-575651080-989379945=:79826" Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG This message is in MIME format. The first part should be readable text, while the remaining parts are likely unreadable without MIME-aware tools. Send mail to mime@docserver.cac.washington.edu for more info. --0-575651080-989379945=:79826 Content-Type: TEXT/PLAIN; charset=US-ASCII Hey, The attached patch accounts for a few sync ups to openbsd... they are: - check the msg.tsp_type value prior to using it as an index into char *tsptype[] - use strlcpy's instead of strcpy's - & handle short packets properly. The patch can also be found at: http://www.watson.org/~arr/fbsd-audit/usr.sbin/timed/timedc/ comments appreciated Thanks, Andrew *-------------................................................. | Andrew R. Reiter | arr@fledge.watson.org | "It requires a very unusual mind | to undertake the analysis of the obvious" -- A.N. Whitehead --0-575651080-989379945=:79826 Content-Type: TEXT/PLAIN; charset=US-ASCII; name="cmds.c.05082001.diff" Content-Transfer-Encoding: BASE64 Content-ID: Content-Description: LS0tIGNtZHMuYy5vcmlnCVR1ZSBNYXkgIDggMTk6NTI6MzggMjAwMQ0KKysr IGNtZHMuYwlUdWUgTWF5ICA4IDIwOjQwOjQwIDIwMDENCkBAIC0yNzcsNyAr Mjc3LDcgQEANCiAJZmRfc2V0IHJlYWR5Ow0KIAlzdHJ1Y3Qgc29ja2FkZHJf aW4gZGVzdDsNCiAJaW50IGksIGxlbmd0aDsNCi0Jc3RydWN0IHNvY2thZGRy IGZyb207DQorCXN0cnVjdCBzb2NrYWRkcl9pbiBmcm9tOw0KIAlzdHJ1Y3Qg dGltZXZhbCB0b3V0Ow0KIAlzdHJ1Y3QgdHNwIG1zZzsNCiAJc3RydWN0IHNl cnZlbnQgKnNydnA7DQpAQCAtMzA4LDcgKzMwOCw3IEBADQogCQl9DQogCQli Y29weShocC0+aF9hZGRyLCAmZGVzdC5zaW5fYWRkci5zX2FkZHIsIGhwLT5o X2xlbmd0aCk7DQogDQotCQkodm9pZClzdHJjcHkobXNnLnRzcF9uYW1lLCBt eW5hbWUpOw0KKwkJKHZvaWQpc3RybGNweShtc2cudHNwX25hbWUsIG15bmFt ZSwgc2l6ZW9mKG1zZy50c3BfbmFtZSkpOw0KIAkJbXNnLnRzcF90eXBlID0g VFNQX01TSVRFOw0KIAkJbXNnLnRzcF92ZXJzID0gVFNQVkVSU0lPTjsNCiAJ CWJ5dGVuZXRvcmRlcigmbXNnKTsNCkBAIC0zMjUsMjAgKzMyNSwzMSBAQA0K IAkJRkRfU0VUKHNvY2ssICZyZWFkeSk7DQogCQlpZiAoc2VsZWN0KEZEX1NF VFNJWkUsICZyZWFkeSwgKGZkX3NldCAqKTAsIChmZF9zZXQgKikwLA0KIAkJ CSAgICZ0b3V0KSkgew0KLQkJCWxlbmd0aCA9IHNpemVvZihzdHJ1Y3Qgc29j a2FkZHIpOw0KKwkJCWxlbmd0aCA9IHNpemVvZihmcm9tKTsNCiAJCQljYyA9 IHJlY3Zmcm9tKHNvY2ssICZtc2csIHNpemVvZihzdHJ1Y3QgdHNwKSwgMCwN Ci0JCQkJICAgICAgJmZyb20sICZsZW5ndGgpOw0KKwkJCQkgICAgICAoc3Ry dWN0IHNvY2thZGRyICopJmZyb20sICZsZW5ndGgpOw0KIAkJCWlmIChjYyA8 IDApIHsNCiAJCQkJd2FybigicmVjdmZyb20iKTsNCiAJCQkJY29udGludWU7 DQogCQkJfQ0KKwkJCWlmIChjYyA8IHNpemVvZihzdHJ1Y3QgdHNwKSkgew0K KwkJCQlmcHJpbnRmKHN0ZGVyciwgDQorCQkJCSAgICJzaG9ydCBwYWNrZXQg KCV1LyV1IGJ5dGVzKSBmcm9tICVzXG4iLA0KKwkJCQkgICBjYywgc2l6ZW9m KHN0cnVjdCB0c3ApLA0KKwkJCQkgICBpbmV0X250b2EoZnJvbS5zaW5fYWRk cikpOw0KKwkJCQljb250aW51ZTsNCisJCQl9DQogCQkJYnl0ZWhvc3RvcmRl cigmbXNnKTsNCiAJCQlpZiAobXNnLnRzcF90eXBlID09IFRTUF9BQ0spIHsN CiAJCQkJcHJpbnRmKCJtYXN0ZXIgdGltZWRhZW1vbiBhdCAlcyBpcyAlc1xu IiwNCiAJCQkJICAgICAgIHRndG5hbWUsIG1zZy50c3BfbmFtZSk7DQogCQkJ fSBlbHNlIHsNCi0JCQkJcHJpbnRmKCJyZWNlaXZlZCB3cm9uZyBhY2s6ICVz XG4iLA0KLQkJCQkgICAgICAgdHNwdHlwZVttc2cudHNwX3R5cGVdKTsNCisJ CQkJaWYgKG1zZy50c3BfdHlwZSA+PSBUU1BUWVBFTlVNQkVSDQorCQkJCQlw cmludGYoInVua25vd24gYWNrIHJlY2VpdmVkOiAldVxuIiwNCisJCQkJCQlt c2cudHNwX3R5cGUpOw0KKwkJCQllbHNlCQ0KKwkJCQkJcHJpbnRmKCJ3cm9u ZyBhY2sgcmVjZWl2ZWQ6ICVzXG4iLA0KKwkJCQkgICAgICAgCQl0c3B0eXBl W21zZy50c3BfdHlwZV0pOw0KIAkJCX0NCiAJCX0gZWxzZSB7DQogCQkJcHJp bnRmKCJjb21tdW5pY2F0aW9uIGVycm9yIHdpdGggJXNcbiIsIHRndG5hbWUp Ow0KQEAgLTM5Nyw3ICs0MDgsNyBAQA0KIAkJbXNnLnRzcF92ZXJzID0gVFNQ VkVSU0lPTjsNCiAJCWlmIChnZXRob3N0bmFtZShteW5hbWUsIHNpemVvZiht eW5hbWUpIC0gMSkgPCAwKQ0KIAkJCWVycigxLCAiZ2V0aG9zdG5hbWUiKTsN Ci0JCSh2b2lkKXN0cmNweShtc2cudHNwX25hbWUsIG15bmFtZSk7DQorCQko dm9pZClzdHJsY3B5KG1zZy50c3BfbmFtZSwgbXluYW1lLCBzaXplb2YobXNn LnRzcF9uYW1lKSk7DQogCQlieXRlbmV0b3JkZXIoJm1zZyk7DQogCQlpZiAo c2VuZHRvKHNvY2ssICZtc2csIHNpemVvZihzdHJ1Y3QgdHNwKSwgMCwNCiAJ CQkgICAoc3RydWN0IHNvY2thZGRyKikmc2luLA0KQEAgLTQyMSw3ICs0MzIs NyBAQA0KIAlpbnQgY2M7DQogCWZkX3NldCByZWFkeTsNCiAJc3RydWN0IHNv Y2thZGRyX2luIGRlc3Q7DQotCXN0cnVjdCBzb2NrYWRkciBmcm9tOw0KKwlz dHJ1Y3Qgc29ja2FkZHJfaW4gZnJvbTsNCiAJc3RydWN0IHRpbWV2YWwgdG91 dDsNCiAJc3RydWN0IHRzcCBtc2c7DQogCXN0cnVjdCBzZXJ2ZW50ICpzcnZw Ow0KQEAgLTQ2NiwyMiArNDc3LDMyIEBADQogCUZEX1pFUk8oJnJlYWR5KTsN CiAJRkRfU0VUKHNvY2ssICZyZWFkeSk7DQogCWlmIChzZWxlY3QoRkRfU0VU U0laRSwgJnJlYWR5LCAoZmRfc2V0ICopMCwgKGZkX3NldCAqKTAsICZ0b3V0 KSkgew0KLQkJbGVuZ3RoID0gc2l6ZW9mKHN0cnVjdCBzb2NrYWRkcik7DQor CQlsZW5ndGggPSBzaXplb2YoZnJvbSk7DQogCQljYyA9IHJlY3Zmcm9tKHNv Y2ssICZtc2csIHNpemVvZihzdHJ1Y3QgdHNwKSwgMCwNCi0JCQkgICAgICAm ZnJvbSwgJmxlbmd0aCk7DQorCQkJICAgICAgKHN0cnVjdCBzb2NrYWRkciAq KSZmcm9tLCAmbGVuZ3RoKTsNCiAJCWlmIChjYyA8IDApIHsNCiAJCQl3YXJu KCJyZWN2ZnJvbSIpOw0KIAkJCXJldHVybjsNCiAJCX0NCisJCWlmIChjYyA8 IHNpemVvZihzdHJ1Y3QgdHNwKSkgew0KKwkJCWZwcmludGYoc3RkZXJyLCAi c2hvcnQgcGFjayAoJXUvJXUgYnl0ZXMpIGZyb20gJXNcbiIsDQorCQkJICAg Y2MsIHNpemVvZihzdHJ1Y3QgdHNwKSwgaW5ldF9udG9hKGZyb20uc2luX2Fk ZHIpKTsNCisJCQlyZXR1cm47DQorCQl9DQogCQlieXRlaG9zdG9yZGVyKCZt c2cpOw0KIAkJaWYgKG1zZy50c3BfdHlwZSA9PSBUU1BfQUNLKQ0KIAkJCWlm IChvbmZsYWcpDQogCQkJCXByaW50ZigidGltZWQgdHJhY2luZyBlbmFibGVk XG4iKTsNCiAJCQllbHNlDQogCQkJCXByaW50ZigidGltZWQgdHJhY2luZyBk aXNhYmxlZFxuIik7DQotCQllbHNlDQotCQkJcHJpbnRmKCJ3cm9uZyBhY2sg cmVjZWl2ZWQ6ICVzXG4iLA0KKwkJZWxzZSB7DQorCQkJaWYgKG1zZy50c3Bf dHlwZSA+PSBUU1BUWVBFTlVNQkVSKQ0KKwkJCQlwcmludGYoInVua25vd24g YWNrIHJlY2VpdmVkOiAldVxuIiwNCisJCQkJCW1zZy50c3BfdHlwZSk7DQor CQkJZWxzZQkNCisJCQkJcHJpbnRmKCJ3cm9uZyBhY2sgcmVjZWl2ZWQ6ICVz XG4iLA0KIAkJCQkJCXRzcHR5cGVbbXNnLnRzcF90eXBlXSk7DQorCQl9DQog CX0gZWxzZQ0KIAkJcHJpbnRmKCJjb21tdW5pY2F0aW9uIGVycm9yXG4iKTsN CiB9DQo= --0-575651080-989379945=:79826-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Wed May 9 1:30:27 2001 Delivered-To: freebsd-audit@freebsd.org Received: from obsecurity.dyndns.org (adsl-63-207-60-108.dsl.lsan03.pacbell.net [63.207.60.108]) by hub.freebsd.org (Postfix) with ESMTP id B791737B422; Wed, 9 May 2001 01:30:16 -0700 (PDT) (envelope-from kris@obsecurity.org) Received: by obsecurity.dyndns.org (Postfix, from userid 1000) id 552F4678BA; Wed, 9 May 2001 01:30:16 -0700 (PDT) Date: Wed, 9 May 2001 01:30:16 -0700 From: Kris Kennaway To: audit@FreeBSD.org, jkh@FreeBSD.org Subject: pkg_add patch Message-ID: <20010509013016.A29331@xor.obsecurity.org> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-md5; protocol="application/pgp-signature"; boundary="a8Wt8u1KmwUX3Y2C" Content-Disposition: inline User-Agent: Mutt/1.2.5i Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG --a8Wt8u1KmwUX3Y2C Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable This is part I of a patch to pkg_*. I started out doing this, then somehow got sidetracked into making all of pkg_install/* BDECFLAGS-clean (343 warnings!! I'm down to about 50, half of which are harmless/impossible to get rid of, the others I'm not immediately sure how to fix. I want to review the changes I've made before I send them out, so perhaps tomorrow). The rest of pkg_* needs a good cleaning up too, but I don't have the energy right now. This patch fixes the string buffer ops in pkg_add/main.c and tidies up the handling of the package version directory selection. Kris Index: add/main.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /mnt/ncvs/src/usr.sbin/pkg_install/add/main.c,v retrieving revision 1.35 diff -u -r1.35 main.c --- add/main.c 2001/04/26 06:48:59 1.35 +++ add/main.c 2001/05/09 08:18:37 @@ -49,6 +49,23 @@ char pkgnames[MAX_PKGS][MAXPATHLEN]; char *pkgs[MAX_PKGS]; =20 +struct { + int lowver; /* Lowest version number to match */ + int hiver; /* Highest version number to match */ + const char *directory; /* Directory it lives in */ +} releases[] =3D { + { 410000, 410000, "/packages-4.1-release" }, + { 420000, 420000, "/packages-4.2-release" }, + { 430000, 430000, "/packages-4.3-release" }, + { 440000, 440000, "/packages-4.4-release" }, + { 450000, 450000, "/packages-4.5-release" }, + { 300000, 399000, "/packages-3-stable" }, + { 400000, 499000, "/packages-4-stable" }, + { 510000, 599000, "/packages-5-stable" }, + { 0, 9999999, "/packages-current" }, + { 0, 0, NULL } +}; + static char *getpackagesite(void); int getosreldate(void); =20 @@ -57,11 +74,9 @@ int main(int argc, char **argv) { - int ch, err; + int ch, error; char **start; - char *cp; - - char *remotepkg =3D NULL, *ptr; + char *cp, *packagesite, *remotepkg =3D NULL, *ptr; static char temppackageroot[MAXPATHLEN]; =20 start =3D argv; @@ -97,7 +112,8 @@ break; =20 case 't': - strcpy(FirstPen, optarg); + if (s_strlcpy(FirstPen, optarg, sizeof(FirstPen))) + errx(1, "-t Argument too long."); break; =20 case 'S': @@ -119,8 +135,7 @@ argv +=3D optind; =20 if (argc > MAX_PKGS) { - warnx("too many packages (max %d)", MAX_PKGS); - return(1); + errx(1, "too many packages (max %d)", MAX_PKGS); } =20 if (AddMode !=3D SLAVE) { @@ -129,26 +144,42 @@ /* Get all the remaining package names, if any */ for (ch =3D 0; *argv; ch++, argv++) { if (Remote) { - strcpy(temppackageroot, getpackagesite()); - remotepkg =3D strcat(temppackageroot, *argv); + if ((packagesite =3D getpackagesite()) =3D=3D NULL) + errx(1, "package name too long"); + if (s_strlcpy(temppackageroot, packagesite, + sizeof(temppackageroot))) + errx(1, "package name too long"); + if (s_strlcat(temppackageroot, *argv, + sizeof(temppackageroot))) + errx(1, "package name too long"); + remotepkg =3D temppackageroot; if (!((ptr =3D strrchr(remotepkg, '.')) && ptr[1] =3D=3D 't' &&=20 ptr[2] =3D=3D 'g' && ptr[3] =3D=3D 'z' && !ptr[4])) - strcat(remotepkg, ".tgz"); + if (s_strlcat(remotepkg, ".tgz", sizeof(temppackageroot))) + errx(1, "package name too long"); } if (!strcmp(*argv, "-")) /* stdin? */ pkgs[ch] =3D "-"; - else if (isURL(*argv)) /* preserve URLs */ - pkgs[ch] =3D strcpy(pkgnames[ch], *argv); - else if ((Remote) && isURL(remotepkg)) - pkgs[ch] =3D strcpy(pkgnames[ch], remotepkg); - else { /* expand all pathnames to fullnames */ + else if (isURL(*argv)) { /* preserve URLs */ + if (s_strlcpy(pkgnames[ch], *argv, sizeof(pkgnames[ch]))) + errx(1, "package name too long"); + pkgs[ch] =3D pkgnames[ch]; + } + else if ((Remote) && isURL(remotepkg)) { + if (s_strlcpy(pkgnames[ch], remotepkg, sizeof(pkgnames[ch]))) + errx(1, "package name too long"); + pkgs[ch] =3D pkgnames[ch]; + } else { /* expand all pathnames to fullnames */ if (fexists(*argv)) /* refers to a file directly */ pkgs[ch] =3D realpath(*argv, pkgnames[ch]); else { /* look for the file in the expected places */ if (!(cp =3D fileFindByPath(NULL, *argv))) warnx("can't find package '%s'", *argv); - else - pkgs[ch] =3D strcpy(pkgnames[ch], cp); + else { + if (s_strlcpy(pkgnames[ch], cp, sizeof(pkgnames[ch]))) + errx(1, "package name too long"); + pkgs[ch] =3D pkgnames[ch]; + } } } } @@ -170,10 +201,10 @@ /* Set a reasonable umask */ umask(022); =20 - if ((err =3D pkg_perform(pkgs)) !=3D 0) { + if ((error =3D pkg_perform(pkgs)) !=3D 0) { if (Verbose) - warnx("%d package addition(s) failed", err); - return err; + warnx("%d package addition(s) failed", error); + return error; } else return 0; @@ -182,51 +213,43 @@ static char * getpackagesite(void) { - int reldate; + int reldate, i; static char sitepath[MAXPATHLEN]; struct utsname u; =20 if (getenv("PACKAGESITE")) { - strcpy(sitepath, getenv("PACKAGESITE")); + if (s_strlcpy(sitepath, getenv("PACKAGESITE"),=20 + sizeof(sitepath))) + return NULL; return sitepath; } - - if (getenv("PACKAGEMIRROR")) - strcpy(sitepath, getenv("PACKAGEMIRROR")); - else - strcpy(sitepath, "ftp://ftp.FreeBSD.org"); =20 - if (getenv("PACKAGEROOT")) - strcpy(sitepath, getenv("PACKAGEMIRRORROOT")); - else - strcat(sitepath, "/pub"); + if (getenv("PACKAGEROOT")) { + if (s_strlcpy(sitepath, getenv("PACKAGEROOT"), sizeof(sitepath))) + return NULL; + } else { + if (s_strlcat(sitepath, "ftp://ftp.freebsd.org", sizeof(sitepath))) + return NULL; + } =20 - strcat(sitepath, "/FreeBSD/ports/"); + if (s_strlcat(sitepath, "/pub/FreeBSD/ports/", sizeof(sitepath))) + return NULL; =20 uname(&u); - strcat(sitepath, u.machine); + if (s_strlcat(sitepath, u.machine, sizeof(sitepath))) + return NULL; =20 reldate =3D getosreldate(); - if (reldate =3D=3D 410000) - strcat(sitepath, "/packages-4.1-release"); - else if (reldate =3D=3D 420000) - strcat(sitepath, "/packages-4.2-release"); - else if (reldate =3D=3D 430000) - strcat(sitepath, "/packages-4.3-release"); - else if (reldate =3D=3D 440000) - strcat(sitepath, "/packages-4.4-release"); - else if (reldate =3D=3D 450000) - strcat(sitepath, "/packages-4.5-release"); - else if (300000 <=3D reldate && reldate <=3D 399000) - strcat(sitepath, "/packages-3-stable"); - else if (400000 <=3D reldate && reldate <=3D 499000) - strcat(sitepath, "/packages-4-stable"); - else if (510000 <=3D reldate && reldate <=3D 599000) /* get real value= s!! */ - strcat(sitepath, "/packages-5-stable"); - else - strcat(sitepath, "/packages-current"); + for(i =3D 0; releases[i].directory !=3D NULL; i++) { + if (reldate >=3D releases[i].lowver && reldate <=3D releases[i].hiver) { + if (s_strlcat(sitepath, releases[i].directory, sizeof(sitepath))) + return NULL; + continue; + } + } =20 - strcat(sitepath, "/Latest/"); + if (s_strlcat(sitepath, "/Latest/", sizeof(sitepath))) + return NULL; =20 return sitepath; =20 Index: lib/lib.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /mnt/ncvs/src/usr.sbin/pkg_install/lib/lib.h,v retrieving revision 1.34 diff -u -r1.34 lib.h --- lib/lib.h 2001/03/23 18:45:24 1.34 +++ lib/lib.h 2001/05/09 08:17:02 @@ -128,6 +128,8 @@ char *basename_of(char *); char *strconcat(char *, char *); char *get_string(char *, int, FILE *); +int s_strlcpy(char *, const char *, size_t); +int s_strlcat(char *, const char *, size_t); =20 /* File */ Boolean fexists(char *); Index: lib/str.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /mnt/ncvs/src/usr.sbin/pkg_install/lib/str.c,v retrieving revision 1.8 diff -u -r1.8 str.c --- lib/str.c 2001/03/23 18:45:24 1.8 +++ lib/str.c 2001/05/09 08:16:03 @@ -61,6 +61,20 @@ return *str; } =20 +/* Do a strlcpy and test for overflow */ +int +s_strlcpy(char *dst, const char *src, size_t size) +{ + return (strlcpy(dst, src, size) >=3D size); +} + +/* Do a strlcat and test for overflow */ +int +s_strlcat(char *dst, const char *src, size_t size) +{ + return (strlcat(dst, src, size) >=3D size); +} + /* Rather Obvious */ char * copy_string(char *str) --a8Wt8u1KmwUX3Y2C Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.5 (FreeBSD) Comment: For info see http://www.gnupg.org iD8DBQE6+QAXWry0BWjoQKURAn6pAKDcFxG90FconKIQEqJZmOZMZxzadACgj+x4 s3cKXMjwrNLuZ+BXkgLAJ4U= =V5Og -----END PGP SIGNATURE----- --a8Wt8u1KmwUX3Y2C-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Wed May 9 1:36:10 2001 Delivered-To: freebsd-audit@freebsd.org Received: from obsecurity.dyndns.org (adsl-63-207-60-108.dsl.lsan03.pacbell.net [63.207.60.108]) by hub.freebsd.org (Postfix) with ESMTP id 927E037B422 for ; Wed, 9 May 2001 01:36:08 -0700 (PDT) (envelope-from kris@obsecurity.org) Received: by obsecurity.dyndns.org (Postfix, from userid 1000) id 2FC70678BA; Wed, 9 May 2001 01:36:08 -0700 (PDT) Date: Wed, 9 May 2001 01:36:08 -0700 From: Kris Kennaway To: "Andrew R. Reiter" Cc: freebsd-audit@freebsd.org Subject: Re: audit work: cmds.c from timedc Message-ID: <20010509013608.A29442@xor.obsecurity.org> References: Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-md5; protocol="application/pgp-signature"; boundary="bg08WKrSYDhXBjb5" Content-Disposition: inline User-Agent: Mutt/1.2.5i In-Reply-To: ; from arr@watson.org on Tue, May 08, 2001 at 11:45:45PM -0400 Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG --bg08WKrSYDhXBjb5 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Tue, May 08, 2001 at 11:45:45PM -0400, Andrew R. Reiter wrote: > + if (msg.tsp_type >= TSPTYPENUMBER ) Well, apart from the fact that this didn't compile, it looks good :-) I've committed it - thanks. Kris --bg08WKrSYDhXBjb5 Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.5 (FreeBSD) Comment: For info see http://www.gnupg.org iD8DBQE6+QF3Wry0BWjoQKURAgt0AJ0RD2CvIWOxlj/RQjnQJSt35BhDdgCg+I0F C5nKwNcvEjdO5204CW25BJE= =iy75 -----END PGP SIGNATURE----- --bg08WKrSYDhXBjb5-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Wed May 9 4:15:59 2001 Delivered-To: freebsd-audit@freebsd.org Received: from nebula.cybercable.fr (d189.dhcp212-126.cybercable.fr [212.198.126.189]) by hub.freebsd.org (Postfix) with ESMTP id 65B3537B422 for ; Wed, 9 May 2001 04:15:54 -0700 (PDT) (envelope-from mux@qualys.com) Received: (from mux@localhost) by nebula.cybercable.fr (8.11.3/8.11.3) id f49BFpI01796 for audit@FreeBSD.org; Wed, 9 May 2001 13:15:51 +0200 (CEST) (envelope-from mux) Date: Wed, 9 May 2001 13:15:50 +0200 From: Maxime Henrion To: audit@FreeBSD.org Subject: chpass patch to disallow non-printable characters in the passwd file Message-ID: <20010509131550.A984@nebula.cybercable.fr> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="HcAYCG3uE/tztfnV" Content-Disposition: inline User-Agent: Mutt/1.2.5i Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG --HcAYCG3uE/tztfnV Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hi, Here is another patch from OpenBSD taken from Kris mailbox. It prevents users from putting non-printable characters in the passwd file. Maxime -- Don't be fooled by cheap finnish imitations ; BSD is the One True Code Key fingerprint = F9B6 1D5A 4963 331C 88FC CA6A AB50 1EF2 8CBE 99D6 Public Key : http://www.epita.fr/~henrio_m/ --HcAYCG3uE/tztfnV Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="edit.c.diff" *** /usr/src/usr.bin/chpass/edit.c Wed Sep 6 20:16:46 2000 --- edit.c Wed May 9 13:12:05 2001 *************** *** 184,193 **** struct passwd *pw; { ENTRY *ep; ! char *p; struct stat sb; FILE *fp; ! int len, line; static char buf[LINE_MAX]; if (!(fp = fopen(tempname, "r"))) --- 184,193 ---- struct passwd *pw; { ENTRY *ep; ! char *p, *q; struct stat sb; FILE *fp; ! unsigned int len, line; static char buf[LINE_MAX]; if (!(fp = fopen(tempname, "r"))) *************** *** 225,231 **** goto bad; } while (isspace(*++p)); ! if (ep->except && strpbrk(p, ep->except)) { warnx( "illegal character in the \"%s\" field", ep->prompt); --- 225,235 ---- goto bad; } while (isspace(*++p)); ! for (q = p; *q && isprint(*q); q++) { ! if (ep->except && strchr(ep->except, *q)) ! break; ! } ! if (*q) { warnx( "illegal character in the \"%s\" field", ep->prompt); --HcAYCG3uE/tztfnV-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Wed May 9 4:19:23 2001 Delivered-To: freebsd-audit@freebsd.org Received: from obsecurity.dyndns.org (adsl-63-207-60-108.dsl.lsan03.pacbell.net [63.207.60.108]) by hub.freebsd.org (Postfix) with ESMTP id 7F92737B423; Wed, 9 May 2001 04:19:15 -0700 (PDT) (envelope-from kris@obsecurity.org) Received: by obsecurity.dyndns.org (Postfix, from userid 1000) id 163AE678BA; Wed, 9 May 2001 04:19:15 -0700 (PDT) Date: Wed, 9 May 2001 04:19:14 -0700 From: Kris Kennaway To: Maxime Henrion Cc: audit@FreeBSD.ORG, freebsd-i18n@FreeBSD.org Subject: Re: chpass patch to disallow non-printable characters in the passwd file Message-ID: <20010509041914.A36212@xor.obsecurity.org> References: <20010509131550.A984@nebula.cybercable.fr> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-md5; protocol="application/pgp-signature"; boundary="45Z9DzgjV8m4Oswq" Content-Disposition: inline User-Agent: Mutt/1.2.5i In-Reply-To: <20010509131550.A984@nebula.cybercable.fr>; from mux@qualys.com on Wed, May 09, 2001 at 01:15:50PM +0200 Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG --45Z9DzgjV8m4Oswq Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Wed, May 09, 2001 at 01:15:50PM +0200, Maxime Henrion wrote: > Hi, >=20 > Here is another patch from OpenBSD taken from Kris mailbox. It prevents > users from putting non-printable characters in the passwd file. I'm not sure whether isprint() is the canonical way to check this in the face of different locales. Can someone confirm the correct way to do this? Kris >=20 > Maxime > --=20 > Don't be fooled by cheap finnish imitations ; BSD is the One True Code > Key fingerprint =3D F9B6 1D5A 4963 331C 88FC CA6A AB50 1EF2 8CBE 99D6 > Public Key : http://www.epita.fr/~henrio_m/ > *** /usr/src/usr.bin/chpass/edit.c Wed Sep 6 20:16:46 2000 > --- edit.c Wed May 9 13:12:05 2001 > *************** > *** 184,193 **** > struct passwd *pw; > { > ENTRY *ep; > ! char *p; > struct stat sb; > FILE *fp; > ! int len, line; > static char buf[LINE_MAX]; > =20 > if (!(fp =3D fopen(tempname, "r"))) > --- 184,193 ---- > struct passwd *pw; > { > ENTRY *ep; > ! char *p, *q; > struct stat sb; > FILE *fp; > ! unsigned int len, line; > static char buf[LINE_MAX]; > =20 > if (!(fp =3D fopen(tempname, "r"))) > *************** > *** 225,231 **** > goto bad; > } > while (isspace(*++p)); > ! if (ep->except && strpbrk(p, ep->except)) { > warnx( > "illegal character in the \"%s\" field", > ep->prompt); > --- 225,235 ---- > goto bad; > } > while (isspace(*++p)); > ! for (q =3D p; *q && isprint(*q); q++) { > ! if (ep->except && strchr(ep->except, *q)) > ! break; > ! } > ! if (*q) { > warnx( > "illegal character in the \"%s\" field", > ep->prompt); --45Z9DzgjV8m4Oswq Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.5 (FreeBSD) Comment: For info see http://www.gnupg.org iD8DBQE6+SeyWry0BWjoQKURAkMPAKDNwBU45ER+s3/ny8MoCYlSgDamJgCdHOJx OAIS5Sg10yG5G2ZaXoX8rOE= =BHX0 -----END PGP SIGNATURE----- --45Z9DzgjV8m4Oswq-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Wed May 9 6:47: 0 2001 Delivered-To: freebsd-audit@freebsd.org Received: from ringworld.nanolink.com (ringworld.nanolink.com [195.24.48.13]) by hub.freebsd.org (Postfix) with SMTP id 9A66837B42C for ; Wed, 9 May 2001 06:46:54 -0700 (PDT) (envelope-from roam@orbitel.bg) Received: (qmail 1059 invoked by uid 1000); 9 May 2001 13:46:22 -0000 Date: Wed, 9 May 2001 16:46:22 +0300 From: Peter Pentchev To: Kris Kennaway Cc: Maxime Henrion , audit@FreeBSD.ORG, freebsd-i18n@FreeBSD.org Subject: Re: chpass patch to disallow non-printable characters in the passwd file Message-ID: <20010509164622.C645@ringworld.oblivion.bg> Mail-Followup-To: Kris Kennaway , Maxime Henrion , audit@FreeBSD.ORG, freebsd-i18n@FreeBSD.org References: <20010509131550.A984@nebula.cybercable.fr> <20010509041914.A36212@xor.obsecurity.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5i In-Reply-To: <20010509041914.A36212@xor.obsecurity.org>; from kris@obsecurity.org on Wed, May 09, 2001 at 04:19:14AM -0700 Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG On Wed, May 09, 2001 at 04:19:14AM -0700, Kris Kennaway wrote: > On Wed, May 09, 2001 at 01:15:50PM +0200, Maxime Henrion wrote: > > Hi, > > > > Here is another patch from OpenBSD taken from Kris mailbox. It prevents > > users from putting non-printable characters in the passwd file. > > I'm not sure whether isprint() is the canonical way to check this in > the face of different locales. Can someone confirm the correct way to > do this? isprint() does honor locales, if setlocale() is called in advance. So this fix is proper, but not enough - there must be a call to setlocale(LC_ALL, ""), and a good place for it would be the start of main, even before the getopt() call, as done by a lot of other base system tools. G'luck, Peter -- If I were you, who would be reading this sentence? To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Wed May 9 7: 3:25 2001 Delivered-To: freebsd-audit@freebsd.org Received: from nebula.cybercable.fr (d189.dhcp212-126.cybercable.fr [212.198.126.189]) by hub.freebsd.org (Postfix) with ESMTP id 0808B37B423 for ; Wed, 9 May 2001 07:03:16 -0700 (PDT) (envelope-from mux@qualys.com) Received: (from mux@localhost) by nebula.cybercable.fr (8.11.3/8.11.3) id f49E3Cu10166; Wed, 9 May 2001 16:03:12 +0200 (CEST) (envelope-from mux) Date: Wed, 9 May 2001 16:03:11 +0200 From: Maxime Henrion To: audit@FreeBSD.org Cc: Peter Pentchev Subject: Re: chpass patch to disallow non-printable characters in the passwd file Message-ID: <20010509160311.C984@nebula.cybercable.fr> References: <20010509131550.A984@nebula.cybercable.fr> <20010509041914.A36212@xor.obsecurity.org> <20010509164622.C645@ringworld.oblivion.bg> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="98e8jtXdkpgskNou" Content-Disposition: inline User-Agent: Mutt/1.2.5i In-Reply-To: <20010509164622.C645@ringworld.oblivion.bg>; from roam@orbitel.bg on Wed, May 09, 2001 at 04:46:22PM +0300 Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG --98e8jtXdkpgskNou Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Peter Pentchev wrote: > On Wed, May 09, 2001 at 04:19:14AM -0700, Kris Kennaway wrote: > > On Wed, May 09, 2001 at 01:15:50PM +0200, Maxime Henrion wrote: > > > Hi, > > > > > > Here is another patch from OpenBSD taken from Kris mailbox. It prevents > > > users from putting non-printable characters in the passwd file. > > > > I'm not sure whether isprint() is the canonical way to check this in > > the face of different locales. Can someone confirm the correct way to > > do this? > > isprint() does honor locales, if setlocale() is called in advance. > So this fix is proper, but not enough - there must be a call to > setlocale(LC_ALL, ""), and a good place for it would be the start of main, > even before the getopt() call, as done by a lot of other base system tools. > > G'luck, > Peter OK, here is a new patch with the missing setlocale() call. I did a setlocale(LC_CTYPE, "") as it's only used for the ctype.h functions. Maxime -- Don't be fooled by cheap finnish imitations ; BSD is the One True Code Key fingerprint = F9B6 1D5A 4963 331C 88FC CA6A AB50 1EF2 8CBE 99D6 Public Key : http://www.epita.fr/~henrio_m/ --98e8jtXdkpgskNou Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="chpass.diff" diff -c /usr/src/usr.bin/chpass/chpass.c ./chpass.c *** /usr/src/usr.bin/chpass/chpass.c Sat Apr 28 01:14:31 2001 --- ./chpass.c Wed May 9 15:59:24 2001 *************** *** 53,58 **** --- 53,59 ---- #include #include #include + #include #include #include #include *************** *** 92,97 **** --- 93,99 ---- int force_yp = 0; #endif + setlocale(LC_CTYPE, ""); op = EDITENTRY; #ifdef YP while ((ch = getopt(argc, argv, "a:p:s:e:d:h:oly")) != -1) diff -c /usr/src/usr.bin/chpass/edit.c ./edit.c *** /usr/src/usr.bin/chpass/edit.c Wed Sep 6 20:16:46 2000 --- ./edit.c Wed May 9 13:12:05 2001 *************** *** 184,193 **** struct passwd *pw; { ENTRY *ep; ! char *p; struct stat sb; FILE *fp; ! int len, line; static char buf[LINE_MAX]; if (!(fp = fopen(tempname, "r"))) --- 184,193 ---- struct passwd *pw; { ENTRY *ep; ! char *p, *q; struct stat sb; FILE *fp; ! unsigned int len, line; static char buf[LINE_MAX]; if (!(fp = fopen(tempname, "r"))) *************** *** 225,231 **** goto bad; } while (isspace(*++p)); ! if (ep->except && strpbrk(p, ep->except)) { warnx( "illegal character in the \"%s\" field", ep->prompt); --- 225,235 ---- goto bad; } while (isspace(*++p)); ! for (q = p; *q && isprint(*q); q++) { ! if (ep->except && strchr(ep->except, *q)) ! break; ! } ! if (*q) { warnx( "illegal character in the \"%s\" field", ep->prompt); --98e8jtXdkpgskNou-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Wed May 9 10:32:43 2001 Delivered-To: freebsd-audit@freebsd.org Received: from fledge.watson.org (fledge.watson.org [204.156.12.50]) by hub.freebsd.org (Postfix) with ESMTP id 1BC8A37B423 for ; Wed, 9 May 2001 10:31:36 -0700 (PDT) (envelope-from robert@fledge.watson.org) Received: from fledge.watson.org (robert@fledge.pr.watson.org [192.0.2.3]) by fledge.watson.org (8.11.3/8.11.3) with SMTP id f49HVWf90437 for ; Wed, 9 May 2001 13:31:32 -0400 (EDT) (envelope-from robert@fledge.watson.org) Date: Wed, 9 May 2001 13:31:32 -0400 (EDT) From: Robert Watson X-Sender: robert@fledge.watson.org To: audit@FreeBSD.org Subject: RE: Patch to eliminate struct pcred (fwd) Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG Attached, please find pcred.3.diff, a patch which merges the ucred and pcred structures in 5.0-CURRENT. Also, please find my comments on initially posting the patch on the topic of the changes and rationale for those changes, made to freebsd-arch a couple of days ago. I'd like to commit this in the next day or two; any comments would be appreciated. The basic gist of this change is that it combines the two existing process credential structures, allowing the ucred to be used for almost all access control decisions without use of struct proc directly; it also simplifies the caching of credential information in sigio structures (and related kinds of places), as well as locking for access control decisions. From: Robert Watson To: arch@FreeBSD.org Subject: Patch to eliminate struct pcred Below, please find patches to eliminate struct pcred, as previously discussed on this list. Detailed description of the changes is below, but the quick of it is: pcred and ucred were independent, these patches merge both into ucred, simplifying a number of cached credential cases (such as in sigio), and making the ucred the central structure required for almost all subject-based authorization events. While I did this, I took the opportunity to clean up a number of related issues, including changing the uid/gid helper functions substantially. If you prefer patches via the web, they are at: http://www.watson.org/~robert/pcred.diff Any reviews welcome. An important observation is that, in practice, almost all pcred write operations involve a ucred copy-on-write, so this shouldn't increase the number of ucred's in use; it does slightly expand ucred, but also removes an indirection from the use of ucred in most environments. The performance impact is probably a wash. Detailed description: o Merge contents of struct pcred into struct ucred. Specifically, add the real uid, saved uid, real gid, and saved gid to ucred, as well as the pcred->pc_uidinfo, which was associated with the real uid, only rename it to cr_ruidinfo so as not to conflict with cr_uidinfo, which corresponds to the effective uid. o Remove p_cred from struct proc; add p_ucred to struct proc, replacing original macro that pointed. p->p_ucred to p->p_cred->pc_ucred. o Universally update code so that it makes use of ucred instead of pcred, p->p_ucred instead of p->p_pcred, cr_ruidinfo instead of p_uidinfo, cr_{r,sv}{u,g}id instead of p_*, etc. o Remove pcred0 and its initialization from init_main.c; initialize cr_ruidinfo there. o Restruction many credential modification chunks to always crdup while we figure out locking and optimizations; generally speaking, this means moving to a structure like this: newcred = crdup(oldcred); ... p->p_ucred = newcred; crfree(oldcred); It's not race-free, but better than nothing. There are also races in sys_process.c, all inter-process authorization, fork, exec, and exit. o Remove sigio->sio_ruid since sigio->sio_ucred now contains the ruid; remove comments indicating that the old arrangement was a problem. o Restructure exec1() a little to use newcred/oldcred arrangement, and use improved uid management primitives. o Clean up exit1() so as to do less work in credential cleanup due to pcred removal. o Clean up fork1() so as to do less work in credential cleanup and allocation. o Clean up ktrcanset() to take into account changes, and move to using suser_xxx() instead of performing a direct uid==0 comparision. o Improve commenting in various kern_prot.c credential modification calls to better document current behavior. In a couple of places, current behavior is a little questionable and we need to check POSIX.1 to make sure it's "right". More commenting work still remains to be done. o Update credential management calls, such as crfree(), to take into account new ruidinfo reference. o Modify or add the following uid and gid helper routines: change_euid() change_egid() change_ruid() change_rgid() change_svuid() change_svgid() In each case, the call now acts on a credential not a process, and as such no longer requires more complicated process locking/etc. They now assume the caller will do any necessary allocation of an exclusive credential reference. Each is commented to document its reference requirements. o CANSIGIO() is simplified to require only credentials, not processes and pcreds. o Remove lots of (p_pcred==NULL) checks. o Add an XXX to authorization code in nfs_lock.c, since it's questionable, and needs to be considered carefully. o Simplify posix4 authorization code to require only credentials, not processes and pcreds. Note that this authorization, as well as CANSIGIO(), needs to be updated to use the p_cansignal() and p_cansched() centralized authorization routines, as they currently do not take into account some desirable restrictions that are handled by the centralized routines, as well as being inconsistent with other similar authorization instances. Robert N M Watson FreeBSD Core Team, TrustedBSD Project robert@fledge.watson.org NAI Labs, Safeport Network Services ? compile/GENERIC ? compile/LINT ? i386/conf/LINT Index: compat/linprocfs/linprocfs_misc.c =================================================================== RCS file: /home/ncvs/src/sys/compat/linprocfs/linprocfs_misc.c,v retrieving revision 1.24 diff -u -r1.24 linprocfs_misc.c --- compat/linprocfs/linprocfs_misc.c 2001/05/01 08:11:51 1.24 +++ compat/linprocfs/linprocfs_misc.c 2001/05/09 17:22:37 @@ -444,14 +444,14 @@ PROC_LOCK(p); sbuf_printf(&sb, "PPid:\t%d\n", p->p_pptr ? p->p_pptr->p_pid : 0); - sbuf_printf(&sb, "Uid:\t%d %d %d %d\n", p->p_cred->p_ruid, + sbuf_printf(&sb, "Uid:\t%d %d %d %d\n", p->p_ucred->cr_ruid, p->p_ucred->cr_uid, - p->p_cred->p_svuid, + p->p_ucred->cr_svuid, /* FreeBSD doesn't have fsuid */ p->p_ucred->cr_uid); - sbuf_printf(&sb, "Gid:\t%d %d %d %d\n", p->p_cred->p_rgid, + sbuf_printf(&sb, "Gid:\t%d %d %d %d\n", p->p_ucred->cr_rgid, p->p_ucred->cr_gid, - p->p_cred->p_svgid, + p->p_ucred->cr_svgid, /* FreeBSD doesn't have fsgid */ p->p_ucred->cr_gid); sbuf_cat(&sb, "Groups:\t"); @@ -543,7 +543,7 @@ char *freepath = NULL; p = PFIND(pfs->pfs_pid); - if (p == NULL || p->p_cred == NULL || p->p_ucred == NULL) { + if (p == NULL || p->p_ucred == NULL) { if (p != NULL) PROC_UNLOCK(p); printf("doexelink: pid %d disappeared\n", pfs->pfs_pid); Index: compat/linprocfs/linprocfs_vnops.c =================================================================== RCS file: /home/ncvs/src/sys/compat/linprocfs/linprocfs_vnops.c,v retrieving revision 1.23 diff -u -r1.23 linprocfs_vnops.c --- compat/linprocfs/linprocfs_vnops.c 2001/05/04 05:19:22 1.23 +++ compat/linprocfs/linprocfs_vnops.c 2001/05/09 17:22:37 @@ -432,7 +432,7 @@ procp = PFIND(pfs->pfs_pid); if (procp == NULL) return (ENOENT); - if (procp->p_cred == NULL || procp->p_ucred == NULL) { + if (procp->p_ucred == NULL) { PROC_UNLOCK(procp); return (ENOENT); } Index: compat/linux/linux_misc.c =================================================================== RCS file: /home/ncvs/src/sys/compat/linux/linux_misc.c,v retrieving revision 1.101 diff -u -r1.101 linux_misc.c --- compat/linux/linux_misc.c 2001/05/01 08:11:51 1.101 +++ compat/linux/linux_misc.c 2001/05/09 17:22:38 @@ -958,12 +958,11 @@ struct proc *p; struct linux_setgroups_args *uap; { - struct pcred *pc; + struct ucred *newcred, *oldcred = p->p_ucred; linux_gid_t linux_gidset[NGROUPS]; gid_t *bsd_gidset; int ngrp, error; - pc = p->p_cred; ngrp = uap->gidsetsize; /* @@ -972,22 +971,22 @@ * Keep cr_groups[0] unchanged to prevent that. */ - if ((error = suser_xxx(NULL, p, PRISON_ROOT)) != 0) + if ((error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) return (error); if (ngrp >= NGROUPS) return (EINVAL); - pc->pc_ucred = crcopy(pc->pc_ucred); + newcred = crdup(oldcred); if (ngrp > 0) { error = copyin((caddr_t)uap->gidset, (caddr_t)linux_gidset, ngrp * sizeof(linux_gid_t)); if (error) return (error); - pc->pc_ucred->cr_ngroups = ngrp + 1; + newcred->cr_ngroups = ngrp + 1; - bsd_gidset = pc->pc_ucred->cr_groups; + bsd_gidset = newcred->cr_groups; ngrp--; while (ngrp >= 0) { bsd_gidset[ngrp + 1] = linux_gidset[ngrp]; @@ -995,9 +994,13 @@ } } else - pc->pc_ucred->cr_ngroups = 1; + newcred->cr_ngroups = 1; setsugid(p); + + p->p_ucred = newcred; + crfree(oldcred); + return (0); } @@ -1006,14 +1009,14 @@ struct proc *p; struct linux_getgroups_args *uap; { - struct pcred *pc; + struct ucred *cred; linux_gid_t linux_gidset[NGROUPS]; gid_t *bsd_gidset; int bsd_gidsetsz, ngrp, error; - pc = p->p_cred; - bsd_gidset = pc->pc_ucred->cr_groups; - bsd_gidsetsz = pc->pc_ucred->cr_ngroups - 1; + cred = p->p_ucred; + bsd_gidset = cred->cr_groups; + bsd_gidsetsz = cred->cr_ngroups - 1; /* * cr_groups[0] holds egid. Returning the whole set Index: compat/svr4/svr4_misc.c =================================================================== RCS file: /home/ncvs/src/sys/compat/svr4/svr4_misc.c,v retrieving revision 1.30 diff -u -r1.30 svr4_misc.c --- compat/svr4/svr4_misc.c 2001/05/01 08:11:52 1.30 +++ compat/svr4/svr4_misc.c 2001/05/09 17:22:40 @@ -1283,7 +1283,7 @@ /* * Decrement the count of procs running with this uid. */ - (void)chgproccnt(q->p_cred->p_uidinfo, -1, 0); + (void)chgproccnt(q->p_ucred->cr_ruidinfo, -1, 0); /* * Release reference to text vnode. @@ -1294,13 +1294,8 @@ /* * Free up credentials. */ - PROC_LOCK(q); - if (--q->p_cred->p_refcnt == 0) { - crfree(q->p_ucred); - uifree(q->p_cred->p_uidinfo); - FREE(q->p_cred, M_SUBPROC); - q->p_cred = NULL; - } + crfree(q->p_ucred); + q->p_ucred = NULL; /* * Remove unused arguments Index: compat/svr4/svr4_sysvec.c =================================================================== RCS file: /home/ncvs/src/sys/compat/svr4/svr4_sysvec.c,v retrieving revision 1.20 diff -u -r1.20 svr4_sysvec.c --- compat/svr4/svr4_sysvec.c 2001/02/24 22:20:02 1.20 +++ compat/svr4/svr4_sysvec.c 2001/05/09 17:22:41 @@ -213,10 +213,10 @@ AUXARGS_ENTRY(pos, AT_FLAGS, args->flags); AUXARGS_ENTRY(pos, AT_ENTRY, args->entry); AUXARGS_ENTRY(pos, AT_BASE, args->base); - AUXARGS_ENTRY(pos, AT_UID, imgp->proc->p_cred->p_ruid); - AUXARGS_ENTRY(pos, AT_EUID, imgp->proc->p_cred->p_svuid); - AUXARGS_ENTRY(pos, AT_GID, imgp->proc->p_cred->p_rgid); - AUXARGS_ENTRY(pos, AT_EGID, imgp->proc->p_cred->p_svgid); + AUXARGS_ENTRY(pos, AT_UID, imgp->proc->p_ucred->cr_ruid); + AUXARGS_ENTRY(pos, AT_EUID, imgp->proc->p_ucred->cr_svuid); + AUXARGS_ENTRY(pos, AT_GID, imgp->proc->p_ucred->cr_rgid); + AUXARGS_ENTRY(pos, AT_EGID, imgp->proc->p_ucred->cr_svgid); AUXARGS_ENTRY(pos, AT_NULL, 0); free(imgp->auxargs, M_TEMP); Index: ddb/db_ps.c =================================================================== RCS file: /home/ncvs/src/sys/ddb/db_ps.c,v retrieving revision 1.22 diff -u -r1.22 db_ps.c --- ddb/db_ps.c 2001/03/28 09:17:49 1.22 +++ ddb/db_ps.c 2001/05/09 17:22:42 @@ -95,7 +95,7 @@ db_printf("%5d %8p %8p %4d %5d %5d %06x %d", p->p_pid, (volatile void *)p, (void *)p->p_addr, - p->p_cred ? p->p_cred->p_ruid : 0, pp->p_pid, + p->p_ucred ? p->p_ucred->cr_ruid : 0, pp->p_pid, p->p_pgrp ? p->p_pgrp->pg_id : 0, p->p_flag, p->p_stat); if (p->p_wchan) { db_printf(" %6s %8p", p->p_wmesg, (void *)p->p_wchan); Index: i386/linux/linux_sysvec.c =================================================================== RCS file: /home/ncvs/src/sys/i386/linux/linux_sysvec.c,v retrieving revision 1.78 diff -u -r1.78 linux_sysvec.c --- i386/linux/linux_sysvec.c 2001/05/01 08:12:52 1.78 +++ i386/linux/linux_sysvec.c 2001/05/09 17:22:51 @@ -186,10 +186,10 @@ AUXARGS_ENTRY(pos, AT_ENTRY, args->entry); AUXARGS_ENTRY(pos, AT_BASE, args->base); PROC_LOCK(imgp->proc); - AUXARGS_ENTRY(pos, AT_UID, imgp->proc->p_cred->p_ruid); - AUXARGS_ENTRY(pos, AT_EUID, imgp->proc->p_cred->p_svuid); - AUXARGS_ENTRY(pos, AT_GID, imgp->proc->p_cred->p_rgid); - AUXARGS_ENTRY(pos, AT_EGID, imgp->proc->p_cred->p_svgid); + AUXARGS_ENTRY(pos, AT_UID, imgp->proc->p_ucred->cr_ruid); + AUXARGS_ENTRY(pos, AT_EUID, imgp->proc->p_ucred->cr_svuid); + AUXARGS_ENTRY(pos, AT_GID, imgp->proc->p_ucred->cr_rgid); + AUXARGS_ENTRY(pos, AT_EGID, imgp->proc->p_ucred->cr_svgid); PROC_UNLOCK(imgp->proc); AUXARGS_ENTRY(pos, AT_NULL, 0); Index: kern/init_main.c =================================================================== RCS file: /home/ncvs/src/sys/kern/init_main.c,v retrieving revision 1.168 diff -u -r1.168 init_main.c --- kern/init_main.c 2001/04/29 02:44:48 1.168 +++ kern/init_main.c 2001/05/09 17:22:52 @@ -85,7 +85,6 @@ static struct session session0; static struct pgrp pgrp0; struct proc proc0; -static struct pcred cred0; static struct procsig procsig0; static struct filedesc0 filedesc0; static struct plimit limit0; @@ -321,12 +320,10 @@ callout_init(&p->p_slpcallout, 1); /* Create credentials. */ - cred0.p_refcnt = 1; - cred0.p_uidinfo = uifind(0); - p->p_cred = &cred0; p->p_ucred = crget(); p->p_ucred->cr_ngroups = 1; /* group 0 */ p->p_ucred->cr_uidinfo = uifind(0); + p->p_ucred->cr_ruidinfo = uifind(0); p->p_ucred->cr_prison = NULL; /* Don't jail it. */ /* Create procsig. */ @@ -380,7 +377,7 @@ /* * Charge root for one process. */ - (void)chgproccnt(cred0.p_uidinfo, 1, 0); + (void)chgproccnt(p->p_ucred->cr_ruidinfo, 1, 0); } SYSINIT(p0init, SI_SUB_INTRINSIC, SI_ORDER_FIRST, proc0_init, NULL) Index: kern/kern_acct.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_acct.c,v retrieving revision 1.33 diff -u -r1.33 kern_acct.c --- kern/kern_acct.c 2001/05/01 08:12:55 1.33 +++ kern/kern_acct.c 2001/05/09 17:22:52 @@ -222,8 +222,8 @@ acct.ac_io = encode_comp_t(r->ru_inblock + r->ru_oublock, 0); /* (6) The UID and GID of the process */ - acct.ac_uid = p->p_cred->p_ruid; - acct.ac_gid = p->p_cred->p_rgid; + acct.ac_uid = p->p_ucred->cr_ruid; + acct.ac_gid = p->p_ucred->cr_rgid; /* (7) The terminal from which the process was started */ if ((p->p_flag & P_CONTROLT) && p->p_pgrp->pg_session->s_ttyp) Index: kern/kern_descrip.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_descrip.c,v retrieving revision 1.100 diff -u -r1.100 kern_descrip.c --- kern/kern_descrip.c 2001/05/01 08:12:55 1.100 +++ kern/kern_descrip.c 2001/05/09 17:22:53 @@ -525,8 +525,6 @@ sigio->sio_pgid = pgid; crhold(curproc->p_ucred); sigio->sio_ucred = curproc->p_ucred; - /* It would be convenient if p_ruid was in ucred. */ - sigio->sio_ruid = curproc->p_cred->p_ruid; sigio->sio_myref = sigiop; s = splhigh(); *sigiop = sigio; Index: kern/kern_exec.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_exec.c,v retrieving revision 1.126 diff -u -r1.126 kern_exec.c --- kern/kern_exec.c 2001/05/01 08:12:56 1.126 +++ kern/kern_exec.c 2001/05/09 17:22:54 @@ -104,6 +104,7 @@ register struct execve_args *uap; { struct nameidata nd, *ndp; + struct ucred *oldcred = p->p_ucred, *newcred; register_t *stack_base; int error, len, i; struct image_params image_params, *imgp; @@ -274,13 +275,23 @@ } /* + * XXX: Note, the whole execve() is incredibly racey right now + * with regards to debugging and privilege/credential management. + * In particular, it's possible to race during exec() to attach + * debugging to a process that will gain privilege. + * + * This MUST be fixed prior to any release. + */ + + /* * Implement image setuid/setgid. * * Don't honor setuid/setgid if the filesystem prohibits it or if * the process is being traced. */ - if ((((attr.va_mode & VSUID) && p->p_ucred->cr_uid != attr.va_uid) || - ((attr.va_mode & VSGID) && p->p_ucred->cr_gid != attr.va_gid)) && + newcred = NULL; + if ((((attr.va_mode & VSUID) && oldcred->cr_uid != attr.va_uid) || + ((attr.va_mode & VSGID) && oldcred->cr_gid != attr.va_gid)) && (imgp->vp->v_mount->mnt_flag & MNT_NOSUID) == 0 && (p->p_flag & P_TRACED) == 0) { PROC_UNLOCK(p); @@ -288,7 +299,7 @@ * Turn off syscall tracing for set-id programs, except for * root. */ - if (p->p_tracep && suser(p)) { + if (p->p_tracep && suser_xxx(oldcred, NULL, PRISON_ROOT)) { p->p_traceflag = 0; vrele(p->p_tracep); p->p_tracep = NULL; @@ -296,25 +307,50 @@ /* * Set the new credentials. */ - p->p_ucred = crcopy(p->p_ucred); + newcred = crdup(p->p_ucred); if (attr.va_mode & VSUID) - change_euid(p, attr.va_uid); + change_euid(newcred, attr.va_uid); if (attr.va_mode & VSGID) - p->p_ucred->cr_gid = attr.va_gid; + change_egid(newcred, attr.va_gid); setsugid(p); setugidsafety(p); } else { - if (p->p_ucred->cr_uid == p->p_cred->p_ruid && - p->p_ucred->cr_gid == p->p_cred->p_rgid) + if (oldcred->cr_uid == oldcred->cr_ruid && + oldcred->cr_gid == oldcred->cr_rgid) p->p_flag &= ~P_SUGID; PROC_UNLOCK(p); } /* * Implement correct POSIX saved-id behavior. + * + * XXX: determine whether tests and sets should occur on old or + * new credentials. */ - p->p_cred->p_svuid = p->p_ucred->cr_uid; - p->p_cred->p_svgid = p->p_ucred->cr_gid; + if (newcred->cr_svuid != newcred->cr_uid || + newcred->cr_svgid != newcred->cr_gid) { + if (newcred != NULL) + newcred = crdup(p->p_ucred); + + change_svuid(newcred, newcred->cr_uid); + change_svgid(newcred, newcred->cr_gid); + } + + if (newcred != NULL) { + /* + * If the credential was updated, replace it with the + * new credential. + * + * XXX: should setsugid() be called here? + */ + struct ucred *oldcred; + + oldcred = p->p_ucred; + PROC_LOCK(p); + p->p_ucred = newcred; + PROC_UNLOCK(p); + crfree(oldcred); + } /* * Store the vp for use in procfs Index: kern/kern_exit.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_exit.c,v retrieving revision 1.126 diff -u -r1.126 kern_exit.c --- kern/kern_exit.c 2001/05/04 16:13:28 1.126 +++ kern/kern_exit.c 2001/05/09 17:22:54 @@ -514,7 +514,7 @@ /* * Decrement the count of procs running with this uid. */ - (void)chgproccnt(p->p_cred->p_uidinfo, -1, 0); + (void)chgproccnt(p->p_ucred->cr_ruidinfo, -1, 0); /* * Release reference to text vnode @@ -539,12 +539,8 @@ /* * Free up credentials. */ - if (--p->p_cred->p_refcnt == 0) { - crfree(p->p_ucred); - uifree(p->p_cred->p_uidinfo); - FREE(p->p_cred, M_SUBPROC); - p->p_cred = NULL; - } + crfree(p->p_ucred); + p->p_ucred = NULL; /* * Remove unused arguments Index: kern/kern_fork.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_fork.c,v retrieving revision 1.111 diff -u -r1.111 kern_fork.c --- kern/kern_fork.c 2001/05/07 18:07:29 1.111 +++ kern/kern_fork.c 2001/05/09 17:22:55 @@ -257,7 +257,7 @@ * exceed the limit. The variable nprocs is the current number of * processes, maxproc is the limit. */ - uid = p1->p_cred->p_ruid; + uid = p1->p_ucred->cr_ruid; if ((nprocs >= maxproc - 1 && uid != 0) || nprocs >= maxproc) { tablefull("proc"); return (EAGAIN); @@ -272,7 +272,7 @@ * Increment the count of procs running with this uid. Don't allow * a nonprivileged user to exceed their current limit. */ - ok = chgproccnt(p1->p_cred->p_uidinfo, 1, + ok = chgproccnt(p1->p_ucred->cr_ruidinfo, 1, (uid != 0) ? p1->p_rlimit[RLIMIT_NPROC].rlim_cur : 0); if (!ok) { /* @@ -408,15 +408,9 @@ * We start off holding one spinlock after fork: sched_lock. */ p2->p_spinlocks = 1; - PROC_UNLOCK(p2); - MALLOC(p2->p_cred, struct pcred *, sizeof(struct pcred), - M_SUBPROC, M_WAITOK); - PROC_LOCK(p2); PROC_LOCK(p1); - bcopy(p1->p_cred, p2->p_cred, sizeof(*p2->p_cred)); - p2->p_cred->p_refcnt = 1; crhold(p1->p_ucred); - uihold(p1->p_cred->p_uidinfo); + p2->p_ucred = p1->p_ucred; if (p2->p_args) p2->p_args->ar_ref++; Index: kern/kern_ktrace.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_ktrace.c,v retrieving revision 1.52 diff -u -r1.52 kern_ktrace.c --- kern/kern_ktrace.c 2001/05/01 08:12:56 1.52 +++ kern/kern_ktrace.c 2001/05/09 17:22:56 @@ -531,17 +531,17 @@ ktrcanset(callp, targetp) struct proc *callp, *targetp; { - register struct pcred *caller = callp->p_cred; - register struct pcred *target = targetp->p_cred; + struct ucred *callcr = callp->p_ucred; + struct ucred *targetcr = targetp->p_ucred; - if (prison_check(callp->p_ucred, targetp->p_ucred)) + if (prison_check(callcr, targetcr)) return (0); - if ((caller->pc_ucred->cr_uid == target->p_ruid && - target->p_ruid == target->p_svuid && - caller->p_rgid == target->p_rgid && /* XXX */ - target->p_rgid == target->p_svgid && + if ((callcr->cr_uid == targetcr->cr_ruid && + targetcr->cr_ruid == targetcr->cr_svuid && + callcr->cr_rgid == targetcr->cr_rgid && /* XXX */ + targetcr->cr_rgid == targetcr->cr_svgid && (targetp->p_traceflag & KTRFAC_ROOT) == 0) || - caller->pc_ucred->cr_uid == 0) + !suser_xxx(callcr, NULL, PRISON_ROOT)) return (1); return (0); Index: kern/kern_proc.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_proc.c,v retrieving revision 1.93 diff -u -r1.93 kern_proc.c --- kern/kern_proc.c 2001/05/01 08:12:57 1.93 +++ kern/kern_proc.c 2001/05/09 17:22:56 @@ -424,15 +424,15 @@ kp->ki_textvp = p->p_textvp; kp->ki_fd = p->p_fd; kp->ki_vmspace = p->p_vmspace; - if (p->p_cred) { - kp->ki_uid = p->p_cred->pc_ucred->cr_uid; - kp->ki_ruid = p->p_cred->p_ruid; - kp->ki_svuid = p->p_cred->p_svuid; - kp->ki_ngroups = p->p_cred->pc_ucred->cr_ngroups; - bcopy(p->p_cred->pc_ucred->cr_groups, kp->ki_groups, + if (p->p_ucred) { + kp->ki_uid = p->p_ucred->cr_uid; + kp->ki_ruid = p->p_ucred->cr_ruid; + kp->ki_svuid = p->p_ucred->cr_svuid; + kp->ki_ngroups = p->p_ucred->cr_ngroups; + bcopy(p->p_ucred->cr_groups, kp->ki_groups, NGROUPS * sizeof(gid_t)); - kp->ki_rgid = p->p_cred->p_rgid; - kp->ki_svgid = p->p_cred->p_svgid; + kp->ki_rgid = p->p_ucred->cr_rgid; + kp->ki_svgid = p->p_ucred->cr_svgid; } if (p->p_procsig) { kp->ki_sigignore = p->p_procsig->ps_sigignore; @@ -653,7 +653,7 @@ case KERN_PROC_RUID: if (p->p_ucred == NULL || - p->p_cred->p_ruid != (uid_t)name[0]) + p->p_ucred->cr_ruid != (uid_t)name[0]) continue; break; } Index: kern/kern_prot.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_prot.c,v retrieving revision 1.89 diff -u -r1.89 kern_prot.c --- kern/kern_prot.c 2001/05/01 08:12:57 1.89 +++ kern/kern_prot.c 2001/05/09 17:22:57 @@ -210,7 +210,7 @@ struct getuid_args *uap; { - p->p_retval[0] = p->p_cred->p_ruid; + p->p_retval[0] = p->p_ucred->cr_ruid; #if defined(COMPAT_43) || defined(COMPAT_SUNOS) p->p_retval[1] = p->p_ucred->cr_uid; #endif @@ -253,7 +253,7 @@ struct getgid_args *uap; { - p->p_retval[0] = p->p_cred->p_rgid; + p->p_retval[0] = p->p_ucred->cr_rgid; #if defined(COMPAT_43) || defined(COMPAT_SUNOS) p->p_retval[1] = p->p_ucred->cr_groups[0]; #endif @@ -293,18 +293,18 @@ struct proc *p; register struct getgroups_args *uap; { - register struct pcred *pc = p->p_cred; + register struct ucred *cred = p->p_ucred; register u_int ngrp; int error; if ((ngrp = uap->gidsetsize) == 0) { - p->p_retval[0] = pc->pc_ucred->cr_ngroups; + p->p_retval[0] = cred->cr_ngroups; return (0); } - if (ngrp < pc->pc_ucred->cr_ngroups) + if (ngrp < cred->cr_ngroups) return (EINVAL); - ngrp = pc->pc_ucred->cr_ngroups; - if ((error = copyout((caddr_t)pc->pc_ucred->cr_groups, + ngrp = cred->cr_ngroups; + if ((error = copyout((caddr_t)cred->cr_groups, (caddr_t)uap->gidset, ngrp * sizeof(gid_t)))) return (error); p->p_retval[0] = ngrp; @@ -427,7 +427,7 @@ struct proc *p; struct setuid_args *uap; { - register struct pcred *pc = p->p_cred; + struct ucred *oldcred = p->p_ucred, *newcred; register uid_t uid; int error; @@ -449,16 +449,17 @@ * 3: Change euid last. (after tests in #2 for "appropriate privs") */ uid = uap->uid; - if (uid != pc->p_ruid && /* allow setuid(getuid()) */ + if (uid != oldcred->cr_ruid && /* allow setuid(getuid()) */ #ifdef _POSIX_SAVED_IDS - uid != pc->p_svuid && /* allow setuid(saved gid) */ + uid != oldcred->cr_svuid && /* allow setuid(saved gid) */ #endif #ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */ - uid != pc->pc_ucred->cr_uid && /* allow setuid(geteuid()) */ + uid != oldcred->cr_uid && /* allow setuid(geteuid()) */ #endif - (error = suser_xxx(0, p, PRISON_ROOT))) + (error = suser_xxx(oldcred, NULL, PRISON_ROOT))) return (error); + newcred = crdup(oldcred); #ifdef _POSIX_SAVED_IDS /* * Do we have "appropriate privileges" (are we root or uid == euid) @@ -466,16 +467,16 @@ */ if ( #ifdef POSIX_APPENDIX_B_4_2_2 /* Use the clause from B.4.2.2 */ - uid == pc->pc_ucred->cr_uid || + uid == oldcred->cr_uid || #endif - suser_xxx(0, p, PRISON_ROOT) == 0) /* we are using privs */ + suser_xxx(oldcred, NULL, PRISON_ROOT) == 0) /* we are using privs */ #endif { /* * Set the real uid and transfer proc count to new user. */ - if (uid != pc->p_ruid) { - change_ruid(p, uid); + if (uid != oldcred->cr_ruid) { + change_ruid(newcred, uid); setsugid(p); } /* @@ -485,8 +486,8 @@ * the security of seteuid() depends on it. B.4.2.2 says it * is important that we should do this. */ - if (pc->p_svuid != uid) { - pc->p_svuid = uid; + if (uid != oldcred->cr_svuid) { + change_svuid(newcred, uid); setsugid(p); } } @@ -495,10 +496,12 @@ * In all permitted cases, we are changing the euid. * Copy credentials so other references do not see our changes. */ - if (pc->pc_ucred->cr_uid != uid) { - change_euid(p, uid); + if (uid != oldcred->cr_uid) { + change_euid(newcred, uid); setsugid(p); } + p->p_ucred = newcred; + crfree(oldcred); return (0); } @@ -513,23 +516,31 @@ struct proc *p; struct seteuid_args *uap; { - register struct pcred *pc = p->p_cred; + register struct ucred *oldcred = p->p_ucred, *newcred; register uid_t euid; int error; euid = uap->euid; - if (euid != pc->p_ruid && /* allow seteuid(getuid()) */ - euid != pc->p_svuid && /* allow seteuid(saved uid) */ - (error = suser_xxx(0, p, PRISON_ROOT))) + /* + * The new effective uid must equal the current real or saved + * uid. Appropriate privilege may override this restriction. + */ + if (euid != oldcred->cr_ruid && /* allow seteuid(getuid()) */ + euid != oldcred->cr_svuid && /* allow seteuid(saved uid) */ + (error = suser_xxx(oldcred, NULL, PRISON_ROOT))) return (error); + /* * Everything's okay, do it. Copy credentials so other references do * not see our changes. */ - if (pc->pc_ucred->cr_uid != euid) { - change_euid(p, euid); + newcred = crdup(oldcred); + if (oldcred->cr_uid != euid) { + change_euid(newcred, euid); setsugid(p); } + p->p_ucred = newcred; + crfree(oldcred); return (0); } @@ -544,7 +555,7 @@ struct proc *p; struct setgid_args *uap; { - register struct pcred *pc = p->p_cred; + register struct ucred *oldcred = p->p_ucred, *newcred; register gid_t gid; int error; @@ -560,16 +571,17 @@ * For notes on the logic here, see setuid() above. */ gid = uap->gid; - if (gid != pc->p_rgid && /* allow setgid(getgid()) */ + if (gid != oldcred->cr_rgid && /* allow setgid(getgid()) */ #ifdef _POSIX_SAVED_IDS - gid != pc->p_svgid && /* allow setgid(saved gid) */ + gid != oldcred->cr_svgid && /* allow setgid(saved gid) */ #endif #ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */ - gid != pc->pc_ucred->cr_groups[0] && /* allow setgid(getegid()) */ + gid != oldcred->cr_groups[0] && /* allow setgid(getegid()) */ #endif - (error = suser_xxx(0, p, PRISON_ROOT))) + (error = suser_xxx(oldcred, NULL, PRISON_ROOT))) return (error); + newcred = crdup(oldcred); #ifdef _POSIX_SAVED_IDS /* * Do we have "appropriate privileges" (are we root or gid == egid) @@ -577,16 +589,16 @@ */ if ( #ifdef POSIX_APPENDIX_B_4_2_2 /* use the clause from B.4.2.2 */ - gid == pc->pc_ucred->cr_groups[0] || + gid == oldcred->cr_groups[0] || #endif - suser_xxx(0, p, PRISON_ROOT) == 0) /* we are using privs */ + suser_xxx(oldcred, NULL, PRISON_ROOT) == 0) /* we are using privs */ #endif { /* * Set real gid */ - if (pc->p_rgid != gid) { - pc->p_rgid = gid; + if (oldcred->cr_rgid != gid) { + change_rgid(newcred, gid); setsugid(p); } /* @@ -596,8 +608,8 @@ * the security of setegid() depends on it. B.4.2.2 says it * is important that we should do this. */ - if (pc->p_svgid != gid) { - pc->p_svgid = gid; + if (oldcred->cr_svgid != gid) { + change_svgid(newcred, gid); setsugid(p); } } @@ -605,11 +617,12 @@ * In all cases permitted cases, we are changing the egid. * Copy credentials so other references do not see our changes. */ - if (pc->pc_ucred->cr_groups[0] != gid) { - pc->pc_ucred = crcopy(pc->pc_ucred); - pc->pc_ucred->cr_groups[0] = gid; + if (oldcred->cr_groups[0] != gid) { + change_egid(newcred, gid); setsugid(p); } + p->p_ucred = newcred; + crfree(oldcred); return (0); } @@ -624,20 +637,27 @@ struct proc *p; struct setegid_args *uap; { - register struct pcred *pc = p->p_cred; + register struct ucred *oldcred = p->p_ucred, *newcred; register gid_t egid; int error; egid = uap->egid; - if (egid != pc->p_rgid && /* allow setegid(getgid()) */ - egid != pc->p_svgid && /* allow setegid(saved gid) */ - (error = suser_xxx(0, p, PRISON_ROOT))) + /* + * The new effective gid must be equal to either the current real or + * saved gid. Appropriate privilege may override this restriction. + */ + if (egid != oldcred->cr_rgid && /* allow setegid(getgid()) */ + egid != oldcred->cr_svgid && /* allow setegid(saved gid) */ + (error = suser_xxx(oldcred, NULL, PRISON_ROOT))) return (error); - if (pc->pc_ucred->cr_groups[0] != egid) { - pc->pc_ucred = crcopy(pc->pc_ucred); - pc->pc_ucred->cr_groups[0] = egid; + + newcred = crdup(oldcred); + if (oldcred->cr_groups[0] != egid) { + change_egid(newcred, egid); setsugid(p); } + p->p_ucred = newcred; + crfree(oldcred); return (0); } @@ -653,11 +673,11 @@ struct proc *p; struct setgroups_args *uap; { - register struct pcred *pc = p->p_cred; + register struct ucred *oldcred = p->p_ucred, *newcred; register u_int ngrp; int error; - if ((error = suser_xxx(0, p, PRISON_ROOT))) + if ((error = suser_xxx(oldcred, NULL, PRISON_ROOT))) return (error); ngrp = uap->gidsetsize; if (ngrp > NGROUPS) @@ -666,7 +686,7 @@ * XXX A little bit lazy here. We could test if anything has * changed before crcopy() and setting P_SUGID. */ - pc->pc_ucred = crcopy(pc->pc_ucred); + newcred = crdup(oldcred); if (ngrp < 1) { /* * setgroups(0, NULL) is a legitimate way of clearing the @@ -674,14 +694,18 @@ * have the egid in the groups[0]). We risk security holes * when running non-BSD software if we do not do the same. */ - pc->pc_ucred->cr_ngroups = 1; + newcred->cr_ngroups = 1; } else { if ((error = copyin((caddr_t)uap->gidset, - (caddr_t)pc->pc_ucred->cr_groups, ngrp * sizeof(gid_t)))) + (caddr_t)newcred->cr_groups, ngrp * sizeof(gid_t)))) { + crfree(newcred); return (error); - pc->pc_ucred->cr_ngroups = ngrp; + } + newcred->cr_ngroups = ngrp; } setsugid(p); + p->p_ucred = newcred; + crfree(oldcred); return (0); } @@ -697,31 +721,52 @@ register struct proc *p; struct setreuid_args *uap; { - register struct pcred *pc = p->p_cred; + register struct ucred *oldcred = p->p_ucred, *newcred; register uid_t ruid, euid; int error; ruid = uap->ruid; euid = uap->euid; - if (((ruid != (uid_t)-1 && ruid != pc->p_ruid && ruid != pc->p_svuid) || - (euid != (uid_t)-1 && euid != pc->pc_ucred->cr_uid && - euid != pc->p_ruid && euid != pc->p_svuid)) && - (error = suser_xxx(0, p, PRISON_ROOT)) != 0) + /* + * If an real uid update is requested, the requested real uid must + * be equal to the current real or saved uid. If an effective uid + * update is requested, the requested euid must be equal to the + * current effective uid, real uid, or saved uid. Appropriate + * privilege may override these restrictions. + */ + if (((ruid != (uid_t)-1 && ruid != oldcred->cr_ruid && + ruid != oldcred->cr_svuid) || + (euid != (uid_t)-1 && euid != oldcred->cr_uid && + euid != oldcred->cr_ruid && euid != oldcred->cr_svuid)) && + (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) return (error); - if (euid != (uid_t)-1 && pc->pc_ucred->cr_uid != euid) { - change_euid(p, euid); + newcred = crdup(oldcred); + if (euid != (uid_t)-1 && oldcred->cr_uid != euid) { + change_euid(newcred, euid); setsugid(p); } - if (ruid != (uid_t)-1 && pc->p_ruid != ruid) { - change_ruid(p, ruid); + if (ruid != (uid_t)-1 && oldcred->cr_ruid != ruid) { + change_ruid(newcred, ruid); setsugid(p); } - if ((ruid != (uid_t)-1 || pc->pc_ucred->cr_uid != pc->p_ruid) && - pc->p_svuid != pc->pc_ucred->cr_uid) { - pc->p_svuid = pc->pc_ucred->cr_uid; + /* + * XXX: What is this intended to accomplish? In which cases should + * it be looking at the old values, and in which, the new values? + * + * Note current behavior is: + * If the ruid update is requested (even if the ruid is not changed) + * or the euid is not equal to the value of the ruid, a difference + * in the svuid and the euid will result in the svuid being + * updated to the new value of the euid. + */ + if ((ruid != (uid_t)-1 || newcred->cr_uid != newcred->cr_ruid) && + newcred->cr_svuid != newcred->cr_uid) { + change_svuid(newcred, newcred->cr_uid); setsugid(p); } + p->p_ucred = newcred; + crfree(oldcred); return (0); } @@ -737,30 +782,49 @@ register struct proc *p; struct setregid_args *uap; { - register struct pcred *pc = p->p_cred; + register struct ucred *oldcred = p->p_ucred, *newcred; register gid_t rgid, egid; int error; rgid = uap->rgid; egid = uap->egid; - if (((rgid != (gid_t)-1 && rgid != pc->p_rgid && rgid != pc->p_svgid) || - (egid != (gid_t)-1 && egid != pc->pc_ucred->cr_groups[0] && - egid != pc->p_rgid && egid != pc->p_svgid)) && - (error = suser_xxx(0, p, PRISON_ROOT)) != 0) + /* + * If a real gid update is requested, the requested real gid must + * be equal to the current real or saved gid. If an effective gid + * update is requested, the requested effective gid must be equal + * to the current effective gid, the current real gid, or the + * current saved gid. Apropriate privilege may override this + * restriction. + */ + if (((rgid != (gid_t)-1 && rgid != oldcred->cr_rgid && + rgid != oldcred->cr_svgid) || + (egid != (gid_t)-1 && egid != oldcred->cr_groups[0] && + egid != oldcred->cr_rgid && egid != oldcred->cr_svgid)) && + (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) return (error); - if (egid != (gid_t)-1 && pc->pc_ucred->cr_groups[0] != egid) { - pc->pc_ucred = crcopy(pc->pc_ucred); - pc->pc_ucred->cr_groups[0] = egid; + newcred = crdup(oldcred); + if (egid != (gid_t)-1 && oldcred->cr_groups[0] != egid) { + change_egid(newcred, egid); setsugid(p); } - if (rgid != (gid_t)-1 && pc->p_rgid != rgid) { - pc->p_rgid = rgid; + if (rgid != (gid_t)-1 && oldcred->cr_rgid != rgid) { + change_rgid(newcred, rgid); setsugid(p); } - if ((rgid != (gid_t)-1 || pc->pc_ucred->cr_groups[0] != pc->p_rgid) && - pc->p_svgid != pc->pc_ucred->cr_groups[0]) { - pc->p_svgid = pc->pc_ucred->cr_groups[0]; + /* + * XXX: What is this intended to accomplish? In which cases should + * it be looking at the old values, and in which, the new values? + * + * Note current behavior is: + * If the rgid update is requested (even if the rgid is not changed) + * or the egid is not equal to the value of the rgid, a difference + * in the svgid and the egid will result in the svuid being + * updated to the new value of the euid. + */ + if ((rgid != (gid_t)-1 || newcred->cr_groups[0] != newcred->cr_rgid) && + newcred->cr_svgid != newcred->cr_groups[0]) { + change_svgid(newcred, newcred->cr_groups[0]); setsugid(p); } return (0); @@ -784,33 +848,40 @@ register struct proc *p; struct setresuid_args *uap; { - register struct pcred *pc = p->p_cred; + register struct ucred *oldcred = p->p_ucred, *newcred; register uid_t ruid, euid, suid; int error; ruid = uap->ruid; euid = uap->euid; suid = uap->suid; - if (((ruid != (uid_t)-1 && ruid != pc->p_ruid && ruid != pc->p_svuid && - ruid != pc->pc_ucred->cr_uid) || - (euid != (uid_t)-1 && euid != pc->p_ruid && euid != pc->p_svuid && - euid != pc->pc_ucred->cr_uid) || - (suid != (uid_t)-1 && suid != pc->p_ruid && suid != pc->p_svuid && - suid != pc->pc_ucred->cr_uid)) && - (error = suser_xxx(0, p, PRISON_ROOT)) != 0) + if (((ruid != (uid_t)-1 && ruid != oldcred->cr_ruid && + ruid != oldcred->cr_svuid && + ruid != oldcred->cr_uid) || + (euid != (uid_t)-1 && euid != oldcred->cr_ruid && + euid != oldcred->cr_svuid && + euid != oldcred->cr_uid) || + (suid != (uid_t)-1 && suid != oldcred->cr_ruid && + suid != oldcred->cr_svuid && + suid != oldcred->cr_uid)) && + (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) return (error); - if (euid != (uid_t)-1 && pc->pc_ucred->cr_uid != euid) { - change_euid(p, euid); + + newcred = crdup(oldcred); + if (euid != (uid_t)-1 && oldcred->cr_uid != euid) { + change_euid(newcred, euid); setsugid(p); } - if (ruid != (uid_t)-1 && pc->p_ruid != ruid) { - change_ruid(p, ruid); + if (ruid != (uid_t)-1 && oldcred->cr_ruid != ruid) { + change_ruid(newcred, ruid); setsugid(p); } - if (suid != (uid_t)-1 && pc->p_svuid != suid) { - pc->p_svuid = suid; + if (suid != (uid_t)-1 && oldcred->cr_svuid != suid) { + change_svuid(newcred, suid); setsugid(p); } + p->p_ucred = newcred; + crfree(oldcred); return (0); } @@ -832,35 +903,40 @@ register struct proc *p; struct setresgid_args *uap; { - register struct pcred *pc = p->p_cred; + register struct ucred *oldcred = p->p_ucred, *newcred; register gid_t rgid, egid, sgid; int error; rgid = uap->rgid; egid = uap->egid; sgid = uap->sgid; - if (((rgid != (gid_t)-1 && rgid != pc->p_rgid && rgid != pc->p_svgid && - rgid != pc->pc_ucred->cr_groups[0]) || - (egid != (gid_t)-1 && egid != pc->p_rgid && egid != pc->p_svgid && - egid != pc->pc_ucred->cr_groups[0]) || - (sgid != (gid_t)-1 && sgid != pc->p_rgid && sgid != pc->p_svgid && - sgid != pc->pc_ucred->cr_groups[0])) && - (error = suser_xxx(0, p, PRISON_ROOT)) != 0) + if (((rgid != (gid_t)-1 && rgid != oldcred->cr_rgid && + rgid != oldcred->cr_svgid && + rgid != oldcred->cr_groups[0]) || + (egid != (gid_t)-1 && egid != oldcred->cr_rgid && + egid != oldcred->cr_svgid && + egid != oldcred->cr_groups[0]) || + (sgid != (gid_t)-1 && sgid != oldcred->cr_rgid && + sgid != oldcred->cr_svgid && + sgid != oldcred->cr_groups[0])) && + (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) return (error); - if (egid != (gid_t)-1 && pc->pc_ucred->cr_groups[0] != egid) { - pc->pc_ucred = crcopy(pc->pc_ucred); - pc->pc_ucred->cr_groups[0] = egid; + newcred = crdup(oldcred); + if (egid != (gid_t)-1 && oldcred->cr_groups[0] != egid) { + change_egid(newcred, egid); setsugid(p); } - if (rgid != (gid_t)-1 && pc->p_rgid != rgid) { - pc->p_rgid = rgid; + if (rgid != (gid_t)-1 && oldcred->cr_rgid != rgid) { + change_rgid(newcred, rgid); setsugid(p); } - if (sgid != (gid_t)-1 && pc->p_svgid != sgid) { - pc->p_svgid = sgid; + if (sgid != (gid_t)-1 && oldcred->cr_svgid != sgid) { + change_svgid(newcred, sgid); setsugid(p); } + p->p_ucred = newcred; + crfree(oldcred); return (0); } @@ -877,18 +953,18 @@ register struct proc *p; struct getresuid_args *uap; { - struct pcred *pc = p->p_cred; + struct ucred *cred = p->p_ucred; int error1 = 0, error2 = 0, error3 = 0; if (uap->ruid) - error1 = copyout((caddr_t)&pc->p_ruid, - (caddr_t)uap->ruid, sizeof(pc->p_ruid)); + error1 = copyout((caddr_t)&cred->cr_ruid, + (caddr_t)uap->ruid, sizeof(cred->cr_ruid)); if (uap->euid) - error2 = copyout((caddr_t)&pc->pc_ucred->cr_uid, - (caddr_t)uap->euid, sizeof(pc->pc_ucred->cr_uid)); + error2 = copyout((caddr_t)&cred->cr_uid, + (caddr_t)uap->euid, sizeof(cred->cr_uid)); if (uap->suid) - error3 = copyout((caddr_t)&pc->p_svuid, - (caddr_t)uap->suid, sizeof(pc->p_svuid)); + error3 = copyout((caddr_t)&cred->cr_svuid, + (caddr_t)uap->suid, sizeof(cred->cr_svuid)); return error1 ? error1 : (error2 ? error2 : error3); } @@ -905,18 +981,18 @@ register struct proc *p; struct getresgid_args *uap; { - struct pcred *pc = p->p_cred; + struct ucred *cred = p->p_ucred; int error1 = 0, error2 = 0, error3 = 0; if (uap->rgid) - error1 = copyout((caddr_t)&pc->p_rgid, - (caddr_t)uap->rgid, sizeof(pc->p_rgid)); + error1 = copyout((caddr_t)&cred->cr_rgid, + (caddr_t)uap->rgid, sizeof(cred->cr_rgid)); if (uap->egid) - error2 = copyout((caddr_t)&pc->pc_ucred->cr_groups[0], - (caddr_t)uap->egid, sizeof(pc->pc_ucred->cr_groups[0])); + error2 = copyout((caddr_t)&cred->cr_groups[0], + (caddr_t)uap->egid, sizeof(cred->cr_groups[0])); if (uap->sgid) - error3 = copyout((caddr_t)&pc->p_svgid, - (caddr_t)uap->sgid, sizeof(pc->p_svgid)); + error3 = copyout((caddr_t)&cred->cr_svgid, + (caddr_t)uap->sgid, sizeof(cred->cr_svgid)); return error1 ? error1 : (error2 ? error2 : error3); } @@ -1113,10 +1189,10 @@ * Generally, the object credential's ruid or svuid must match the * subject credential's ruid or euid. */ - if (p1->p_cred->p_ruid != p2->p_cred->p_ruid && - p1->p_cred->p_ruid != p2->p_cred->p_svuid && - p1->p_ucred->cr_uid != p2->p_cred->p_ruid && - p1->p_ucred->cr_uid != p2->p_cred->p_svuid) { + if (p1->p_ucred->cr_ruid != p2->p_ucred->cr_ruid && + p1->p_ucred->cr_ruid != p2->p_ucred->cr_svuid && + p1->p_ucred->cr_uid != p2->p_ucred->cr_ruid && + p1->p_ucred->cr_uid != p2->p_ucred->cr_svuid) { /* Not permitted, try privilege. */ error = suser_xxx(NULL, p1, PRISON_ROOT); if (error) @@ -1140,9 +1216,9 @@ if ((error = prison_check(p1->p_ucred, p2->p_ucred))) return (error); - if (p1->p_cred->p_ruid == p2->p_cred->p_ruid) + if (p1->p_ucred->cr_ruid == p2->p_ucred->cr_ruid) return (0); - if (p1->p_ucred->cr_uid == p2->p_cred->p_ruid) + if (p1->p_ucred->cr_uid == p2->p_ucred->cr_ruid) return (0); if (!suser_xxx(0, p1, PRISON_ROOT)) { @@ -1178,9 +1254,9 @@ /* not owned by you, has done setuid (unless you're root) */ /* add a CAP_SYS_PTRACE here? */ - if (p1->p_cred->pc_ucred->cr_uid != p2->p_cred->p_ruid || - p1->p_cred->p_ruid != p2->p_cred->p_ruid || - p1->p_cred->p_svuid != p2->p_cred->p_ruid || + if (p1->p_ucred->cr_uid != p2->p_ucred->cr_ruid || + p1->p_ucred->cr_ruid != p2->p_ucred->cr_ruid || + p1->p_ucred->cr_svuid != p2->p_ucred->cr_ruid || p2->p_flag & P_SUGID) { if ((error = suser_xxx(0, p1, PRISON_ROOT))) return (error); @@ -1308,6 +1384,7 @@ *newcr = *cr; mtx_init(&newcr->cr_mtx, "ucred", MTX_DEF); uihold(newcr->cr_uidinfo); + uihold(newcr->cr_ruidinfo); if (jailed(newcr)) prison_hold(newcr->cr_prison); newcr->cr_ref = 1; @@ -1375,48 +1452,123 @@ } /* - * Helper function to change the effective uid of a process + * change_euid(): Change a process's effective uid. + * Arguments: struct ucred *newcred, uid_t euid + * Returns: none + * Locks: none + * Side effects: newcred->cr_uid and newcred->cr_uidinfo will be modified. + * References: newcred must be an exclusive credential reference for the + * duration of the call. + * Notes: none */ void -change_euid(p, euid) - struct proc *p; - uid_t euid; +change_euid(newcred, euid) + struct ucred *newcred; + uid_t euid; { - struct pcred *pc; - struct uidinfo *uip; - pc = p->p_cred; - /* - * crcopy is essentially a NOP if ucred has a reference count - * of 1, which is true if it has already been copied. - */ - pc->pc_ucred = crcopy(pc->pc_ucred); - uip = pc->pc_ucred->cr_uidinfo; - pc->pc_ucred->cr_uid = euid; - pc->pc_ucred->cr_uidinfo = uifind(euid); - uifree(uip); + newcred->cr_uid = euid; + uifree(newcred->cr_uidinfo); + newcred->cr_uidinfo = uifind(euid); } /* - * Helper function to change the real uid of a process - * - * The per-uid process count for this process is transfered from - * the old uid to the new uid. + * change_egid(): Change a process's effective gid. + * Arguments: struct ucred *newcred, gid_t egid + * Returns: none + * Locks: none + * Side effects: newcred->cr_gid will be modified. + * References: newcred must be an exclusive credential reference for the + * duration of the call. + * Notes: none */ void -change_ruid(p, ruid) - struct proc *p; - uid_t ruid; +change_egid(newcred, egid) + struct ucred *newcred; + gid_t egid; +{ + + newcred->cr_groups[0] = egid; +} + +/* + * change_ruid(): Change a process's real uid. + * Arguments: struct ucred *newcred, uid_t ruid + * Returns: none + * Locks: none + * Side effects: newcred->cr_ruid will be updated, newcred->cr_ruidinfo + * will be updated, and the old and new cr_ruidinfo proc + * counts will be updated. + * References: newcred must be an exclusive credential reference for the + * duration of the call. + * Notes: none + */ +void +change_ruid(newcred, ruid) + struct ucred *newcred; + uid_t ruid; +{ + + (void)chgproccnt(newcred->cr_ruidinfo, -1, 0); + newcred->cr_ruid = ruid; + uifree(newcred->cr_ruidinfo); + newcred->cr_ruidinfo = uifind(ruid); + (void)chgproccnt(newcred->cr_ruidinfo, 1, 0); +} + +/* + * change_rgid(): Change a process's real gid. + * Arguments: struct ucred *newcred, gid_t rgid + * Returns: none + * Locks: none + * Side effects: newcred->cr_rgid will be updated. + * References: newcred must be an exclusive credential reference for the + * duration of the call. + * Notes: none + */ +void +change_rgid(newcred, rgid) + struct ucred *newcred; + gid_t rgid; +{ + + newcred->cr_rgid = rgid; +} + +/* + * change_svuid(): Change a process's saved uid. + * Arguments: struct ucred *newcred, uid_t svuid + * Returns: none + * Locks: none + * Side effects: newcred->cr_svuid will be updated. + * References: newcred must be an exclusive credential reference for the + * duration of the call. + * Notes: none + */ +void +change_svuid(newcred, svuid) + struct ucred *newcred; + uid_t svuid; +{ + + newcred->cr_svuid = svuid; +} + +/* + * change_svgid(): Change a process's saved gid. + * Arguments: struct ucred *newcred, gid_t svgid + * Returns: none + * Locks: none + * Side effects: newcred->cr_svgid will be updated. + * References: newcred must be an exclusive credential reference for the + * duration of the call. + * Notes: none + */ +void +change_svgid(newcred, svgid) + struct ucred *newcred; + gid_t svgid; { - struct pcred *pc; - struct uidinfo *uip; - pc = p->p_cred; - (void)chgproccnt(pc->p_uidinfo, -1, 0); - uip = pc->p_uidinfo; - /* It is assumed that pcred is not shared between processes */ - pc->p_ruid = ruid; - pc->p_uidinfo = uifind(ruid); - (void)chgproccnt(pc->p_uidinfo, 1, 0); - uifree(uip); + newcred->cr_svgid = svgid; } Index: kern/kern_sig.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_sig.c,v retrieving revision 1.118 diff -u -r1.118 kern_sig.c --- kern/kern_sig.c 2001/05/07 18:07:29 1.118 +++ kern/kern_sig.c 2001/05/09 17:22:58 @@ -98,14 +98,14 @@ "Log processes quitting on abnormal signals to syslog(3)"); /* - * Policy -- Can real uid ruid with ucred uc send a signal to process q? + * Policy -- Can ucred cr1 send SIGIO to process cr2? */ -#define CANSIGIO(ruid, uc, q) \ - ((uc)->cr_uid == 0 || \ - (ruid) == (q)->p_cred->p_ruid || \ - (uc)->cr_uid == (q)->p_cred->p_ruid || \ - (ruid) == (q)->p_ucred->cr_uid || \ - (uc)->cr_uid == (q)->p_ucred->cr_uid) +#define CANSIGIO(cr1, cr2) \ + ((cr1)->cr_uid == 0 || \ + (cr2)->cr_ruid == (cr2)->cr_ruid || \ + (cr2)->cr_uid == (cr2)->cr_ruid || \ + (cr2)->cr_ruid == (cr2)->cr_uid || \ + (cr2)->cr_uid == (cr2)->cr_uid) int sugid_coredump; SYSCTL_INT(_kern, OID_AUTO, sugid_coredump, CTLFLAG_RW, @@ -1610,8 +1610,8 @@ { CTR3(KTR_PROC, "killproc: proc %p (pid %d, %s)", p, p->p_pid, p->p_comm); - log(LOG_ERR, "pid %d (%s), uid %d, was killed: %s\n", p->p_pid, p->p_comm, - p->p_cred && p->p_ucred ? p->p_ucred->cr_uid : -1, why); + log(LOG_ERR, "pid %d (%s), uid %d, was killed: %s\n", p->p_pid, + p->p_comm, p->p_ucred ? p->p_ucred->cr_uid : -1, why); PROC_LOCK(p); psignal(p, SIGKILL); PROC_UNLOCK(p); @@ -1650,7 +1650,7 @@ log(LOG_INFO, "pid %d (%s), uid %d: exited on signal %d%s\n", p->p_pid, p->p_comm, - p->p_cred && p->p_ucred ? p->p_ucred->cr_uid : -1, + p->p_ucred ? p->p_ucred->cr_uid : -1, sig &~ WCOREFLAG, sig & WCOREFLAG ? " (core dumped)" : ""); } else { @@ -1870,8 +1870,7 @@ if (sigio->sio_pgid > 0) { PROC_LOCK(sigio->sio_proc); - if (CANSIGIO(sigio->sio_ruid, sigio->sio_ucred, - sigio->sio_proc)) + if (CANSIGIO(sigio->sio_ucred, sigio->sio_proc->p_ucred)) psignal(sigio->sio_proc, sig); PROC_UNLOCK(sigio->sio_proc); } else if (sigio->sio_pgid < 0) { @@ -1879,7 +1878,7 @@ LIST_FOREACH(p, &sigio->sio_pgrp->pg_members, p_pglist) { PROC_LOCK(p); - if (CANSIGIO(sigio->sio_ruid, sigio->sio_ucred, p) && + if (CANSIGIO(sigio->sio_ucred, p->p_ucred) && (checkctty == 0 || (p->p_flag & P_CONTROLT))) psignal(p, sig); PROC_UNLOCK(p); Index: kern/uipc_usrreq.c =================================================================== RCS file: /home/ncvs/src/sys/kern/uipc_usrreq.c,v retrieving revision 1.65 diff -u -r1.65 uipc_usrreq.c --- kern/uipc_usrreq.c 2001/05/01 08:12:59 1.65 +++ kern/uipc_usrreq.c 2001/05/09 17:22:59 @@ -988,8 +988,8 @@ if (cm->cmsg_type == SCM_CREDS) { cmcred = (struct cmsgcred *)(cm + 1); cmcred->cmcred_pid = p->p_pid; - cmcred->cmcred_uid = p->p_cred->p_ruid; - cmcred->cmcred_gid = p->p_cred->p_rgid; + cmcred->cmcred_uid = p->p_ucred->cr_ruid; + cmcred->cmcred_gid = p->p_ucred->cr_rgid; cmcred->cmcred_euid = p->p_ucred->cr_uid; cmcred->cmcred_ngroups = MIN(p->p_ucred->cr_ngroups, CMGROUP_MAX); Index: kern/vfs_syscalls.c =================================================================== RCS file: /home/ncvs/src/sys/kern/vfs_syscalls.c,v retrieving revision 1.189 diff -u -r1.189 vfs_syscalls.c --- kern/vfs_syscalls.c 2001/04/29 02:44:49 1.189 +++ kern/vfs_syscalls.c 2001/05/09 17:23:02 @@ -1711,8 +1711,8 @@ * rather than to modify the potentially shared process structure. */ tmpcred = crdup(cred); - tmpcred->cr_uid = p->p_cred->p_ruid; - tmpcred->cr_groups[0] = p->p_cred->p_rgid; + tmpcred->cr_uid = cred->cr_ruid; + tmpcred->cr_groups[0] = cred->cr_rgid; p->p_ucred = tmpcred; NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, SCARG(uap, path), p); @@ -3799,7 +3799,7 @@ } cnt = auio.uio_resid; error = VOP_SETEXTATTR(vp, attrnamespace, attrname, &auio, - p->p_cred->pc_ucred, p); + p->p_ucred, p); cnt -= auio.uio_resid; p->p_retval[0] = cnt; done: @@ -3912,7 +3912,7 @@ } cnt = auio.uio_resid; error = VOP_GETEXTATTR(vp, attrnamespace, attrname, &auio, - p->p_cred->pc_ucred, p); + p->p_ucred, p); cnt -= auio.uio_resid; p->p_retval[0] = cnt; done: @@ -3995,7 +3995,7 @@ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); error = VOP_SETEXTATTR(vp, attrnamespace, attrname, NULL, - p->p_cred->pc_ucred, p); + p->p_ucred, p); VOP_UNLOCK(vp, 0, p); vn_finished_write(mp); Index: miscfs/procfs/procfs_status.c =================================================================== RCS file: /home/ncvs/src/sys/miscfs/procfs/procfs_status.c,v retrieving revision 1.29 diff -u -r1.29 procfs_status.c --- miscfs/procfs/procfs_status.c 2001/05/01 08:13:09 1.29 +++ miscfs/procfs/procfs_status.c 2001/05/09 17:23:02 @@ -153,11 +153,11 @@ ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, " %lu %lu %lu", (u_long)cr->cr_uid, - (u_long)p->p_cred->p_ruid, - (u_long)p->p_cred->p_rgid); + (u_long)cr->cr_ruid, + (u_long)cr->cr_rgid); DOCHECK(); - /* egid (p->p_cred->p_svgid) is equal to cr_ngroups[0] + /* egid (cr->cr_svgid) is equal to cr_ngroups[0] see also getegid(2) in /sys/kern/kern_prot.c */ for (i = 0; i < cr->cr_ngroups; i++) { Index: miscfs/procfs/procfs_vnops.c =================================================================== RCS file: /home/ncvs/src/sys/miscfs/procfs/procfs_vnops.c,v retrieving revision 1.95 diff -u -r1.95 procfs_vnops.c --- miscfs/procfs/procfs_vnops.c 2001/05/01 08:13:09 1.95 +++ miscfs/procfs/procfs_vnops.c 2001/05/09 17:23:04 @@ -404,7 +404,7 @@ procp = PFIND(pfs->pfs_pid); if (procp == NULL) return (ENOENT); - if (procp->p_cred == NULL || procp->p_ucred == NULL) { + if (procp->p_ucred == NULL) { PROC_UNLOCK(procp); return (ENOENT); } @@ -942,8 +942,7 @@ */ case Pfile: procp = PFIND(pfs->pfs_pid); - if (procp == NULL || procp->p_cred == NULL || - procp->p_ucred == NULL) { + if (procp == NULL || procp->p_ucred == NULL) { if (procp != NULL) PROC_UNLOCK(procp); printf("procfs_readlink: pid %d disappeared\n", Index: nfs/nfs_lock.c =================================================================== RCS file: /home/ncvs/src/sys/nfs/nfs_lock.c,v retrieving revision 1.4 diff -u -r1.4 nfs_lock.c --- nfs/nfs_lock.c 2001/05/01 08:13:14 1.4 +++ nfs/nfs_lock.c 2001/05/09 17:23:21 @@ -236,9 +236,11 @@ /* Let root, or someone who once was root (lockd generally * switches to the daemon uid once it is done setting up) make - * this call + * this call. + * + * XXX */ - if ((error = suser(p)) != 0 && p->p_cred->p_svuid != 0) + if ((error = suser(p)) != 0 && p->p_ucred->cr_svuid != 0) return (error); /* the version should match, or we're out of sync */ Index: posix4/p1003_1b.c =================================================================== RCS file: /home/ncvs/src/sys/posix4/p1003_1b.c,v retrieving revision 1.9 diff -u -r1.9 p1003_1b.c --- posix4/p1003_1b.c 2001/05/06 16:15:42 1.9 +++ posix4/p1003_1b.c 2001/05/09 17:23:21 @@ -68,16 +68,17 @@ /* * This is stolen from CANSIGNAL in kern_sig: * - * Can process p, with pcred pc, do "write flavor" operations to process q? + * Can process with credential cr1 do "write flavor" operations to credential + * cr2. This check needs to use generalized checks. */ -#define CAN_AFFECT(p, q) \ - (!suser_xxx(NULL, p, PRISON_ROOT) || \ - (p)->p_cred->pc_ruid == (q)->p_cred->p_ruid || \ - (p)->p_ucred->cr_uid == (q)->p_cred->p_ruid || \ - (p)->p_cred->pc_ruid == (q)->p_ucred->cr_uid || \ - (p)->p_ucred->cr_uid == (q)->p_ucred->cr_uid) +#define CAN_AFFECT(cr1, cr2) \ + (!suser_xxx(cr1, NULL, PRISON_ROOT) || \ + (c1)->cr_ruid == (cr2)->cr_ruid || \ + (c1)->cr_uid == (cr2)->cr_ruid || \ + (c1)->cr_ruid == (cr2)->cr_uid || \ + (c1)->cr_uid == (cr2)->cr_uid) #else -#define CAN_AFFECT(p, q) (!suser_xxx(NULL, p, PRISON_ROOT)) +#define CAN_AFFECT(cr1, cr2) (!suser_xxx(cr1, NULL, PRISON_ROOT)) #endif /* @@ -99,7 +100,7 @@ { /* Enforce permission policy. */ - if (CAN_AFFECT(p, other_proc)) + if (CAN_AFFECT(p->p_ucred, other_proc->p_ucred)) *pp = other_proc; else ret = EPERM; Index: sys/filedesc.h =================================================================== RCS file: /home/ncvs/src/sys/sys/filedesc.h,v retrieving revision 1.26 diff -u -r1.26 filedesc.h --- sys/filedesc.h 2000/11/18 21:01:04 1.26 +++ sys/filedesc.h 2001/05/09 17:23:22 @@ -117,7 +117,6 @@ struct sigio **sio_myref; /* location of the pointer that holds * the reference to this structure */ struct ucred *sio_ucred; /* current credentials */ - uid_t sio_ruid; /* real user id */ pid_t sio_pgid; /* pgid for signals */ }; #define sio_proc sio_u.siu_proc Index: sys/proc.h =================================================================== RCS file: /home/ncvs/src/sys/sys/proc.h,v retrieving revision 1.161 diff -u -r1.161 proc.h --- sys/proc.h 2001/04/27 19:28:25 1.161 +++ sys/proc.h 2001/05/09 17:23:22 @@ -156,7 +156,7 @@ LIST_ENTRY(proc) p_list; /* (d) List of all processes. */ /* substructures: */ - struct pcred *p_cred; /* (c + k) Process owner's identity. */ + struct ucred *p_ucred; /* (c + k) Process owner's identity. */ struct filedesc *p_fd; /* (b) Ptr to open files structure. */ struct pstats *p_stats; /* (b) Accounting/statistics (CPU). */ struct plimit *p_limit; /* (m) Process limits. */ @@ -166,7 +166,6 @@ #define p_sigignore p_procsig->ps_sigignore #define p_sigcatch p_procsig->ps_sigcatch -#define p_ucred p_cred->pc_ucred #define p_rlimit p_limit->pl_rlimit int p_flag; /* (c) P_* flags. */ @@ -336,23 +335,6 @@ #define P_CAN_SEE 1 #define P_CAN_SCHED 3 #define P_CAN_DEBUG 4 - -/* - * MOVE TO ucred.h? - * - * Shareable process credentials (always resident). This includes a reference - * to the current user credentials as well as real and saved ids that may be - * used to change ids. - */ -struct pcred { - struct ucred *pc_ucred; /* Current credentials. */ - uid_t p_ruid; /* Real user id. */ - uid_t p_svuid; /* Saved effective user id. */ - gid_t p_rgid; /* Real group id. */ - gid_t p_svgid; /* Saved effective group id. */ - int p_refcnt; /* Number of references. */ - struct uidinfo *p_uidinfo; /* Per uid resource consumption. */ -}; #ifdef _KERNEL Index: sys/ucred.h =================================================================== RCS file: /home/ncvs/src/sys/sys/ucred.h,v retrieving revision 1.23 diff -u -r1.23 ucred.h --- sys/ucred.h 2001/05/01 08:13:18 1.23 +++ sys/ucred.h 2001/05/09 17:23:23 @@ -50,9 +50,14 @@ struct ucred { u_int cr_ref; /* reference count */ uid_t cr_uid; /* effective user id */ + uid_t cr_ruid; /* real user id */ + uid_t cr_svuid; /* saved user id */ short cr_ngroups; /* number of groups */ gid_t cr_groups[NGROUPS]; /* groups */ - struct uidinfo *cr_uidinfo; /* per uid resource consumption */ + gid_t cr_rgid; /* real group id */ + gid_t cr_svgid; /* saved user id */ + struct uidinfo *cr_uidinfo; /* per euid resource consumption */ + struct uidinfo *cr_ruidinfo; /* per ruid resource consumption */ struct prison *cr_prison; /* jail(4) */ struct mtx cr_mtx; /* protect refcount */ }; @@ -77,8 +82,12 @@ struct proc; -void change_euid __P((struct proc *p, uid_t euid)); -void change_ruid __P((struct proc *p, uid_t ruid)); +void change_euid __P((struct ucred *newcred, uid_t euid)); +void change_egid __P((struct ucred *newcred, gid_t egid)); +void change_ruid __P((struct ucred *newcred, uid_t ruid)); +void change_rgid __P((struct ucred *newcred, uid_t rgid)); +void change_svuid __P((struct ucred *newcred, uid_t svuid)); +void change_svgid __P((struct ucred *newcred, gid_t svgid)); struct ucred *crcopy __P((struct ucred *cr)); struct ucred *crdup __P((struct ucred *cr)); void crfree __P((struct ucred *cr)); Index: ufs/ufs/ufs_extattr.c =================================================================== RCS file: /home/ncvs/src/sys/ufs/ufs/ufs_extattr.c,v retrieving revision 1.31 diff -u -r1.31 ufs_extattr.c --- ufs/ufs/ufs_extattr.c 2001/04/29 02:45:28 1.31 +++ ufs/ufs/ufs_extattr.c 2001/05/09 17:23:23 @@ -621,7 +621,7 @@ auio.uio_rw = UIO_READ; auio.uio_procp = (struct proc *) p; - VOP_LEASE(backing_vnode, p, p->p_cred->pc_ucred, LEASE_WRITE); + VOP_LEASE(backing_vnode, p, p->p_ucred, LEASE_WRITE); vn_lock(backing_vnode, LK_SHARED | LK_NOPAUSE | LK_RETRY, p); error = VOP_READ(backing_vnode, &auio, IO_NODELOCKED, ump->um_extattr.uepm_ucred); @@ -702,7 +702,7 @@ * Processes with privilege, but in jail, are not allowed to * configure extended attributes. */ - if ((error = suser_xxx(p->p_cred->pc_ucred, p, 0))) { + if ((error = suser_xxx(p->p_ucred, p, 0))) { if (filename_vp != NULL) VOP_UNLOCK(filename_vp, 0, p); return (error); Index: ufs/ufs/ufs_vfsops.c =================================================================== RCS file: /home/ncvs/src/sys/ufs/ufs/ufs_vfsops.c,v retrieving revision 1.24 diff -u -r1.24 ufs_vfsops.c --- ufs/ufs/ufs_vfsops.c 2001/05/01 08:13:19 1.24 +++ ufs/ufs/ufs_vfsops.c 2001/05/09 17:23:24 @@ -108,14 +108,14 @@ int cmd, type, error; if (uid == -1) - uid = p->p_cred->p_ruid; + uid = p->p_ucred->cr_ruid; cmd = cmds >> SUBCMDSHIFT; switch (cmd) { case Q_SYNC: break; case Q_GETQUOTA: - if (uid == p->p_cred->p_ruid) + if (uid == p->p_ucred->cr_ruid) break; /* fall through */ default: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Wed May 9 14: 4:45 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 9F40237B422 for ; Wed, 9 May 2001 14:04:33 -0700 (PDT) (envelope-from dima@unixfreak.org) Received: from hornet.unixfreak.org (hornet [63.198.170.140]) by bazooka.unixfreak.org (Postfix) with ESMTP id 1BDA13E28 for ; Wed, 9 May 2001 14:04:33 -0700 (PDT) To: audit@freebsd.org Subject: jot(1) patch Date: Wed, 09 May 2001 14:04:32 -0700 From: Dima Dorfman Message-Id: <20010509210433.1BDA13E28@bazooka.unixfreak.org> Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG The attached patch fixes some overflows in jot(1) and syncs up to OpenBSD a little. Significant changes include: - use getopt - de-register - fix overflows in -b and -w options; old behavior: dima@hornet% jot -b `perl -e 'print "A" x 2000'` 5 Segmentation fault (core dumped) dima@hornet% jot -w `perl -e 'print "A" x 2000'` 5 Segmentation fault (core dumped) (this is my primary motivation for the patch) - use strlcpy and snprintf - check return values of the above - fix other gratuituos diffs to OpenBSD; not a complete sync, but better than nothing Please review. Thanks, Dima Dorfman dima@unixfreak.org Index: jot.c =================================================================== RCS file: /st/src/FreeBSD/src/usr.bin/jot/jot.c,v retrieving revision 1.14 diff -u -r1.14 jot.c --- jot.c 2000/07/10 05:57:29 1.14 +++ jot.c 2001/05/09 20:58:25 @@ -51,8 +51,8 @@ * Author: John Kunze, Office of Comp. Affairs, UCB */ -#include #include +#include #include #include #include @@ -65,7 +65,7 @@ #define ENDER_DEF 100 #define STEP_DEF 1 -#define isdefault(s) (strcmp((s), "-") == 0) +#define is_default(s) (strcmp((s), "-") == 0) double begin; double ender; @@ -83,11 +83,10 @@ char *sepstring = "\n"; char format[BUFSIZ]; -void getargs __P((int, char *[])); -void getformat __P((void)); +void getformat __P((void)); int getprec __P((char *)); -int putdata __P((double, long)); -static void usage __P((void)); +int putdata __P((double, long)); +static void usage __P((void)); int main(argc, argv) @@ -96,37 +95,15 @@ { double xd, yd; long id; - register double *x = &xd; - register double *y = &yd; - register long *i = &id; - - getargs(argc, argv); - if (randomize) { - *x = (ender - begin) * (ender > begin ? 1 : -1); - for (*i = 1; *i <= reps || infinity; (*i)++) { - *y = (double) arc4random() / ULONG_MAX; - if (putdata(*y * *x + begin, reps - *i)) - errx(1, "range error in conversion"); - } - } else - for (*i = 1, *x = begin; *i <= reps || infinity; (*i)++, *x += s) - if (putdata(*x, reps - *i)) - errx(1, "range error in conversion"); - if (!nofinalnl) - putchar('\n'); - exit(0); -} - -void -getargs(ac, av) - int ac; - char *av[]; -{ - register unsigned int mask = 0; - register int n = 0; + double *x = &xd; + double *y = &yd; + long *i = &id; + unsigned int mask = 0; + int n = 0; + int ch; - while (--ac && **++av == '-' && !isdefault(*av)) - switch ((*av)[1]) { + while ((ch = getopt(argc, argv, "rb:w:cs:np:")) != -1) + switch ((char)ch) { case 'r': randomize = 1; break; @@ -138,72 +115,63 @@ break; case 'b': boring = 1; + /* FALLTHROUGH */ case 'w': - if ((*av)[2]) - strcpy(format, *av + 2); - else if (!--ac) - errx(1, "need context word after -w or -b"); - else - strcpy(format, *++av); + if (strlcpy(format, optarg, sizeof(format)) >= + sizeof(format)) + errx(1, "-%c word too long", ch); break; case 's': - if ((*av)[2]) - sepstring = *av + 2; - else if (!--ac) - errx(1, "need string after -s"); - else - sepstring = *++av; + sepstring = optarg; break; case 'p': - if ((*av)[2]) - prec = atoi(*av + 2); - else if (!--ac) - errx(1, "need number after -p"); - else - prec = atoi(*++av); + prec = atoi(optarg); if (prec <= 0) errx(1, "bad precision value"); break; default: usage(); } + argc -= optind; + argv += optind; - switch (ac) { /* examine args right to left, falling thru cases */ + switch (argc) { /* examine args right to left, falling thru cases */ case 4: - if (!isdefault(av[3])) { - if (!sscanf(av[3], "%lf", &s)) - errx(1, "bad s value: %s", av[3]); + if (!is_default(argv[3])) { + if (!sscanf(argv[3], "%lf", &s)) + errx(1, "bad s value: %s", argv[3]); mask |= 01; } case 3: - if (!isdefault(av[2])) { - if (!sscanf(av[2], "%lf", &ender)) - ender = av[2][strlen(av[2])-1]; + if (!is_default(argv[2])) { + if (!sscanf(argv[2], "%lf", &ender)) + ender = argv[2][strlen(argv[2])-1]; mask |= 02; if (!prec) - n = getprec(av[2]); + n = getprec(argv[2]); } case 2: - if (!isdefault(av[1])) { - if (!sscanf(av[1], "%lf", &begin)) - begin = av[1][strlen(av[1])-1]; + if (!is_default(argv[1])) { + if (!sscanf(argv[1], "%lf", &begin)) + begin = argv[1][strlen(argv[1])-1]; mask |= 04; if (!prec) - prec = getprec(av[1]); + prec = getprec(argv[1]); if (n > prec) /* maximum precision */ prec = n; } case 1: - if (!isdefault(av[0])) { - if (!sscanf(av[0], "%ld", &reps)) - errx(1, "bad reps value: %s", av[0]); + if (!is_default(argv[0])) { + if (!sscanf(argv[0], "%ld", &reps)) + errx(1, "bad reps value: %s", argv[0]); mask |= 010; } break; case 0: usage(); default: - errx(1, "too many arguments. What do you mean by %s?", av[4]); + errx(1, "too many arguments. What do you mean by %s?", + argv[4]); } getformat(); while (mask) /* 4 bit mask has 1's where last 4 args were given */ @@ -257,7 +225,7 @@ mask = 015; break; case 012: - s = (randomize ? -1.0 : STEP_DEF); + s = (randomize ? time(NULL) : STEP_DEF); mask = 013; break; case 013: @@ -265,8 +233,7 @@ begin = BEGIN_DEF; else if (reps == 0) errx(1, "must specify begin if reps == 0"); - else - begin = ender - reps * s + s; + begin = ender - reps * s + s; mask = 0; break; case 014: @@ -306,6 +273,20 @@ } if (reps == 0) infinity = 1; + if (randomize) { + *x = (ender - begin) * (ender > begin ? 1 : -1); + for (*i = 1; *i <= reps || infinity; (*i)++) { + *y = (double) arc4random() / ULONG_MAX; + if (putdata(*y * *x + begin, reps - *i)) + errx(1, "range error in conversion"); + } + } else + for (*i = 1, *x = begin; *i <= reps || infinity; (*i)++, *x += s) + if (putdata(*x, reps - *i)) + errx(1, "range error in conversion"); + if (!nofinalnl) + putchar('\n'); + exit(0); } int @@ -346,7 +327,7 @@ } static void -usage() +usage(void) { fprintf(stderr, "%s\n%s\n", "usage: jot [-cnr] [-b word] [-w word] [-s string] [-p precision]", @@ -358,8 +339,8 @@ getprec(s) char *s; { - register char *p; - register char *q; + char *p; + char *q; for (p = s; *p; p++) if (*p == '.') @@ -375,8 +356,9 @@ void getformat() { - register char *p; + char *p; int dot, hash, space, sign, numbers = 0; + size_t sz; char *s; if (boring) /* no need to bother */ @@ -384,14 +366,19 @@ for (p = format; *p; p++) /* look for '%' */ if (*p == '%' && *(p+1) != '%') /* leave %% alone */ break; - if (!*p && !chardata) - sprintf(p, "%%.%df", prec); - else if (!*p && chardata) { - strcpy(p, "%c"); + sz = sizeof(format) - strlen(format) - 1; + if (!*p && !chardata) { + if (snprintf(p, sz, "%%.%df", prec) >= (int)sz) + errx(1, "-w word too long"); + } else if (!*p && chardata) { + if (strlcpy(p, "%c", sz) >= sz) + errx(1, "-w word too long"); intdata = 1; - } else if (!*(p+1)) + } else if (!*(p+1)) { + if (sz <= 0) + errx(1, "-w word too long"); strcat(format, "%"); /* cannot end in single '%' */ - else { + } else { /* * Allow conversion format specifiers of the form * %[#][ ][{+,-}][0-9]*[.[0-9]*]? where ? must be one of To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Wed May 9 14:27:18 2001 Delivered-To: freebsd-audit@freebsd.org Received: from harmony.village.org (rover.bsdimp.com [204.144.255.66]) by hub.freebsd.org (Postfix) with ESMTP id 5C3EE37B422 for ; Wed, 9 May 2001 14:27:15 -0700 (PDT) (envelope-from imp@harmony.village.org) Received: from harmony.village.org (localhost.village.org [127.0.0.1]) by harmony.village.org (8.11.3/8.11.1) with ESMTP id f49LR7b40095; Wed, 9 May 2001 15:27:12 -0600 (MDT) (envelope-from imp@harmony.village.org) Message-Id: <200105092127.f49LR7b40095@harmony.village.org> To: Dima Dorfman Subject: Re: jot(1) patch Cc: audit@FreeBSD.ORG In-reply-to: Your message of "Wed, 09 May 2001 14:04:32 PDT." <20010509210433.1BDA13E28@bazooka.unixfreak.org> References: <20010509210433.1BDA13E28@bazooka.unixfreak.org> Date: Wed, 09 May 2001 15:27:07 -0600 From: Warner Losh Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG In message <20010509210433.1BDA13E28@bazooka.unixfreak.org> Dima Dorfman writes: : - use getopt : - de-register You should de __P() as well. The changes add a prototype : -usage() : +usage(void) which breaks K&R compatibility. So do one or the other. The one thing worse than old K&R code in the tree is broken K&R code in the tree. Warner To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Wed May 9 14:33:35 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 07B3137B424 for ; Wed, 9 May 2001 14:33:25 -0700 (PDT) (envelope-from dima@unixfreak.org) Received: from hornet.unixfreak.org (hornet [63.198.170.140]) by bazooka.unixfreak.org (Postfix) with ESMTP id 599E53E0B; Wed, 9 May 2001 14:33:24 -0700 (PDT) To: Warner Losh Cc: audit@FreeBSD.ORG Subject: Re: jot(1) patch In-Reply-To: <200105092127.f49LR7b40095@harmony.village.org>; from imp@harmony.village.org on "Wed, 09 May 2001 15:27:07 -0600" Date: Wed, 09 May 2001 14:33:24 -0700 From: Dima Dorfman Message-Id: <20010509213324.599E53E0B@bazooka.unixfreak.org> Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG Warner Losh writes: > In message <20010509210433.1BDA13E28@bazooka.unixfreak.org> Dima Dorfman writ > es: > : - use getopt > : - de-register > > You should de __P() as well. The changes add a prototype > > : -usage() > : +usage(void) > > which breaks K&R compatibility. So do one or the other. The one > thing worse than old K&R code in the tree is broken K&R code in the > tree. Oops. De-__P()-ified patch attached. Thanks! Dima Dorfman dima@unixfreak.org Index: jot.c =================================================================== RCS file: /st/src/FreeBSD/src/usr.bin/jot/jot.c,v retrieving revision 1.14 diff -u -r1.14 jot.c --- jot.c 2000/07/10 05:57:29 1.14 +++ jot.c 2001/05/09 21:31:29 @@ -51,8 +51,8 @@ * Author: John Kunze, Office of Comp. Affairs, UCB */ -#include #include +#include #include #include #include @@ -65,7 +65,7 @@ #define ENDER_DEF 100 #define STEP_DEF 1 -#define isdefault(s) (strcmp((s), "-") == 0) +#define is_default(s) (strcmp((s), "-") == 0) double begin; double ender; @@ -83,50 +83,25 @@ char *sepstring = "\n"; char format[BUFSIZ]; -void getargs __P((int, char *[])); -void getformat __P((void)); -int getprec __P((char *)); -int putdata __P((double, long)); -static void usage __P((void)); +void getformat(void); +int getprec(char *); +int putdata(double, long); +static void usage(void); int -main(argc, argv) - int argc; - char *argv[]; +main(int argc, char **argv) { double xd, yd; long id; - register double *x = &xd; - register double *y = &yd; - register long *i = &id; - - getargs(argc, argv); - if (randomize) { - *x = (ender - begin) * (ender > begin ? 1 : -1); - for (*i = 1; *i <= reps || infinity; (*i)++) { - *y = (double) arc4random() / ULONG_MAX; - if (putdata(*y * *x + begin, reps - *i)) - errx(1, "range error in conversion"); - } - } else - for (*i = 1, *x = begin; *i <= reps || infinity; (*i)++, *x += s) - if (putdata(*x, reps - *i)) - errx(1, "range error in conversion"); - if (!nofinalnl) - putchar('\n'); - exit(0); -} - -void -getargs(ac, av) - int ac; - char *av[]; -{ - register unsigned int mask = 0; - register int n = 0; + double *x = &xd; + double *y = &yd; + long *i = &id; + unsigned int mask = 0; + int n = 0; + int ch; - while (--ac && **++av == '-' && !isdefault(*av)) - switch ((*av)[1]) { + while ((ch = getopt(argc, argv, "rb:w:cs:np:")) != -1) + switch ((char)ch) { case 'r': randomize = 1; break; @@ -138,72 +113,63 @@ break; case 'b': boring = 1; + /* FALLTHROUGH */ case 'w': - if ((*av)[2]) - strcpy(format, *av + 2); - else if (!--ac) - errx(1, "need context word after -w or -b"); - else - strcpy(format, *++av); + if (strlcpy(format, optarg, sizeof(format)) >= + sizeof(format)) + errx(1, "-%c word too long", ch); break; case 's': - if ((*av)[2]) - sepstring = *av + 2; - else if (!--ac) - errx(1, "need string after -s"); - else - sepstring = *++av; + sepstring = optarg; break; case 'p': - if ((*av)[2]) - prec = atoi(*av + 2); - else if (!--ac) - errx(1, "need number after -p"); - else - prec = atoi(*++av); + prec = atoi(optarg); if (prec <= 0) errx(1, "bad precision value"); break; default: usage(); } + argc -= optind; + argv += optind; - switch (ac) { /* examine args right to left, falling thru cases */ + switch (argc) { /* examine args right to left, falling thru cases */ case 4: - if (!isdefault(av[3])) { - if (!sscanf(av[3], "%lf", &s)) - errx(1, "bad s value: %s", av[3]); + if (!is_default(argv[3])) { + if (!sscanf(argv[3], "%lf", &s)) + errx(1, "bad s value: %s", argv[3]); mask |= 01; } case 3: - if (!isdefault(av[2])) { - if (!sscanf(av[2], "%lf", &ender)) - ender = av[2][strlen(av[2])-1]; + if (!is_default(argv[2])) { + if (!sscanf(argv[2], "%lf", &ender)) + ender = argv[2][strlen(argv[2])-1]; mask |= 02; if (!prec) - n = getprec(av[2]); + n = getprec(argv[2]); } case 2: - if (!isdefault(av[1])) { - if (!sscanf(av[1], "%lf", &begin)) - begin = av[1][strlen(av[1])-1]; + if (!is_default(argv[1])) { + if (!sscanf(argv[1], "%lf", &begin)) + begin = argv[1][strlen(argv[1])-1]; mask |= 04; if (!prec) - prec = getprec(av[1]); + prec = getprec(argv[1]); if (n > prec) /* maximum precision */ prec = n; } case 1: - if (!isdefault(av[0])) { - if (!sscanf(av[0], "%ld", &reps)) - errx(1, "bad reps value: %s", av[0]); + if (!is_default(argv[0])) { + if (!sscanf(argv[0], "%ld", &reps)) + errx(1, "bad reps value: %s", argv[0]); mask |= 010; } break; case 0: usage(); default: - errx(1, "too many arguments. What do you mean by %s?", av[4]); + errx(1, "too many arguments. What do you mean by %s?", + argv[4]); } getformat(); while (mask) /* 4 bit mask has 1's where last 4 args were given */ @@ -257,7 +223,7 @@ mask = 015; break; case 012: - s = (randomize ? -1.0 : STEP_DEF); + s = (randomize ? time(NULL) : STEP_DEF); mask = 013; break; case 013: @@ -265,8 +231,7 @@ begin = BEGIN_DEF; else if (reps == 0) errx(1, "must specify begin if reps == 0"); - else - begin = ender - reps * s + s; + begin = ender - reps * s + s; mask = 0; break; case 014: @@ -306,12 +271,24 @@ } if (reps == 0) infinity = 1; + if (randomize) { + *x = (ender - begin) * (ender > begin ? 1 : -1); + for (*i = 1; *i <= reps || infinity; (*i)++) { + *y = (double) arc4random() / ULONG_MAX; + if (putdata(*y * *x + begin, reps - *i)) + errx(1, "range error in conversion"); + } + } else + for (*i = 1, *x = begin; *i <= reps || infinity; (*i)++, *x += s) + if (putdata(*x, reps - *i)) + errx(1, "range error in conversion"); + if (!nofinalnl) + putchar('\n'); + exit(0); } int -putdata(x, notlast) - double x; - long notlast; +putdata(double x, long notlast) { if (boring) @@ -346,7 +323,7 @@ } static void -usage() +usage(void) { fprintf(stderr, "%s\n%s\n", "usage: jot [-cnr] [-b word] [-w word] [-s string] [-p precision]", @@ -355,11 +332,10 @@ } int -getprec(s) - char *s; +getprec(char *s) { - register char *p; - register char *q; + char *p; + char *q; for (p = s; *p; p++) if (*p == '.') @@ -375,8 +351,9 @@ void getformat() { - register char *p; + char *p; int dot, hash, space, sign, numbers = 0; + size_t sz; char *s; if (boring) /* no need to bother */ @@ -384,14 +361,19 @@ for (p = format; *p; p++) /* look for '%' */ if (*p == '%' && *(p+1) != '%') /* leave %% alone */ break; - if (!*p && !chardata) - sprintf(p, "%%.%df", prec); - else if (!*p && chardata) { - strcpy(p, "%c"); + sz = sizeof(format) - strlen(format) - 1; + if (!*p && !chardata) { + if (snprintf(p, sz, "%%.%df", prec) >= (int)sz) + errx(1, "-w word too long"); + } else if (!*p && chardata) { + if (strlcpy(p, "%c", sz) >= sz) + errx(1, "-w word too long"); intdata = 1; - } else if (!*(p+1)) + } else if (!*(p+1)) { + if (sz <= 0) + errx(1, "-w word too long"); strcat(format, "%"); /* cannot end in single '%' */ - else { + } else { /* * Allow conversion format specifiers of the form * %[#][ ][{+,-}][0-9]*[.[0-9]*]? where ? must be one of To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Wed May 9 20:37:44 2001 Delivered-To: freebsd-audit@freebsd.org Received: from obsecurity.dyndns.org (adsl-63-207-60-108.dsl.lsan03.pacbell.net [63.207.60.108]) by hub.freebsd.org (Postfix) with ESMTP id 46F1537B422; Wed, 9 May 2001 20:37:42 -0700 (PDT) (envelope-from kris@obsecurity.org) Received: by obsecurity.dyndns.org (Postfix, from userid 1000) id DA65B678BA; Wed, 9 May 2001 20:37:40 -0700 (PDT) Date: Wed, 9 May 2001 20:37:40 -0700 From: Kris Kennaway To: Bruce Evans Cc: Ruslan Ermilov , Kris Kennaway , audit@FreeBSD.ORG Subject: Re: ping6 fixes Message-ID: <20010509203740.A49874@xor.obsecurity.org> References: <20010508152816.A58026@sunbay.com> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-md5; protocol="application/pgp-signature"; boundary="liOOAslEiF7prFVr" Content-Disposition: inline User-Agent: Mutt/1.2.5i In-Reply-To: ; from bde@zeta.org.au on Wed, May 09, 2001 at 04:20:44AM +1000 Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG --liOOAslEiF7prFVr Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Wed, May 09, 2001 at 04:20:44AM +1000, Bruce Evans wrote: > I think I now understand the purpose of seteuid() before seteuid(). Me too. Thanks, all. Kris --liOOAslEiF7prFVr Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.5 (FreeBSD) Comment: For info see http://www.gnupg.org iD8DBQE6+g0EWry0BWjoQKURAk4xAJ9sfsS4NSTWaV+htIUKYnceyoyxigCcCCOG n37TjGxDgKO33GkfmWUBr8o= =ajV/ -----END PGP SIGNATURE----- --liOOAslEiF7prFVr-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Thu May 10 2: 6:33 2001 Delivered-To: freebsd-audit@freebsd.org Received: from mailman.zeta.org.au (mailman.zeta.org.au [203.26.10.16]) by hub.freebsd.org (Postfix) with ESMTP id 0E9D337B423 for ; Thu, 10 May 2001 02:06:30 -0700 (PDT) (envelope-from bde@zeta.org.au) Received: from bde.zeta.org.au (bde.zeta.org.au [203.2.228.102]) by mailman.zeta.org.au (8.9.3/8.8.7) with ESMTP id TAA23633; Thu, 10 May 2001 19:06:16 +1000 Date: Thu, 10 May 2001 19:04:45 +1000 (EST) From: Bruce Evans X-Sender: bde@besplex.bde.org To: Warner Losh Cc: Dima Dorfman , audit@FreeBSD.ORG Subject: Re: jot(1) patch In-Reply-To: <200105092127.f49LR7b40095@harmony.village.org> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG On Wed, 9 May 2001, Warner Losh wrote: > In message <20010509210433.1BDA13E28@bazooka.unixfreak.org> Dima Dorfman writes: > : - use getopt > : - de-register > > You should de __P() as well. The changes add a prototype > > : -usage() > : +usage(void) > > which breaks K&R compatibility. So do one or the other. The one > thing worse than old K&R code in the tree is broken K&R code in the > tree. You should just not gratuitously break usage(). usage() is already declared to take a void in its forward declaration using __P(()), so using "void" in its definition just breaks K&R support. Bruce To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Thu May 10 2:46:49 2001 Delivered-To: freebsd-audit@freebsd.org Received: from whale.sunbay.crimea.ua (whale.sunbay.crimea.ua [212.110.138.65]) by hub.freebsd.org (Postfix) with ESMTP id 4061A37B423 for ; Thu, 10 May 2001 02:46:36 -0700 (PDT) (envelope-from ru@whale.sunbay.crimea.ua) Received: (from ru@localhost) by whale.sunbay.crimea.ua (8.11.2/8.11.2) id f4A9jTf29972; Thu, 10 May 2001 12:45:29 +0300 (EEST) (envelope-from ru) Date: Thu, 10 May 2001 12:45:29 +0300 From: Ruslan Ermilov To: Bruce Evans Cc: Kris Kennaway , audit@FreeBSD.ORG Subject: Re: ping6 fixes Message-ID: <20010510124529.C19855@sunbay.com> References: <20010508152816.A58026@sunbay.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="fUYQa+Pmc3FrFX/N" Content-Disposition: inline User-Agent: Mutt/1.2.5i In-Reply-To: ; from bde@zeta.org.au on Wed, May 09, 2001 at 04:20:44AM +1000 Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG --fUYQa+Pmc3FrFX/N Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Wed, May 09, 2001 at 04:20:44AM +1000, Bruce Evans wrote: > On Tue, 8 May 2001, Ruslan Ermilov wrote: > > > On Tue, May 08, 2001 at 04:03:48AM -0700, Kris Kennaway wrote: > > [...] > > > + > > > + /* revoke root privilege */ > > > + seteuid(getuid()); > > > + setuid(getuid()); > > > > > > /* > > > optval = 1; > > > > I still think seteuid() here is superfluous, but see below. > > > > I've just checked that OpenBSD's setuid() behaves differently, > > as mandated by recent POSIX specs. The differences are as > > follows: > > This doesn't seem to be anything recent. I'll check again tomorrow > when I'm awake. Does POSIX now mandate _BROKEN^W_POSIX_SAVED_IDS? > : * In this issue, _POSIX_SAVED_IDS is mandated, thus the effective : user ID and effective group ID of the new process image shall be : saved (as the saved set-user-ID and the saved set-group-ID) for : use by the setuid() function. Why you call it "broken"? > > ... > > > > Under OpenBSD, the attached program succeeds: > > None was attached :-). > Sorry, attached now. > > seteuid() to the fake (12345) UID > > setuid() to the real (1010) UID > > seteuid() back to the saved (0) UID > > > > Under FreeBSD, it fails with: > > > > seteuid() to the fake (12345) UID > > setuid() to the real (1001) UID > > seteuid() back to the saved (0) UID > > setuid: seteuid: Operation not permitted > > I think I now understand the purpose of seteuid() before seteuid(). > It is to set the euid to a value such that the process has "appropriate > privilege" for setuid() to set all the ids. "Appropriate privilege" > is implementation-defined and context-dependent. > In Unixware, this means "the calling process has the P_SETUID privilege". > FreeBSD defines it such that everyone has it for the context of setuid() > to their real uid, so setuid(getuid()) always works "right". > I don't have pre-2000 POSIX.1 specs, but POSIX-200x reads: : If the process has appropriate privileges, setuid() shall set the real : user ID, effective user ID, and the saved set-user-ID of the calling : process to uid. : : If the process does not have appropriate privileges, but uid is equal : to the real user ID or the saved set-user-ID, setuid() shall set the : effective user ID to uid; the real user ID and saved set-user-ID shall : remain unchanged. So, from the POSIX.1-200x point of view, FreeBSD currently defines "appropriate privilege" as "if the specified ID is equal to the real user ID or the effective user ID of the process, or if the effective user ID is that of the super user", while OpenBSD extracts from this list "if the specified ID is equal to the real user ID". In any case, the "euid root" is considered "appropriate privilege", and behavior of both FreeBSD and OpenBSD is the same in this case, i.e., set all three IDs (real, effective, and saved) to the specified value. The only case where the seteuid() call would be required before setuid() would be: 1) FreeBSD doesn't consider "the specified ID is equal to the real user ID" the "appropriate privilege" - and - 2) the process in question doesn't have "appropriate privilege", IOW, it's *NOT* set-uid root, which is not the case here, obviously. > IIRC, this > is mainly so that setuid(getuid()) can work at all (when ruid != euid) in > the !_POSIX_SAVE_IDS case. > Hmm, don't the setuid(ruid) was always allowed? > When it works, it works "right" -- it must > set the euid, and it should set any (non-POSIX) saved ids so that it > works the same as on systems without any saved ids. I think this is > all POSIX.1-199[0-6] conformant. BSD4.4-style saved ids can be viewed > as things that control "appropriate privilege". > It's hard to say without having an old, 1003.1-199x text :-) Cheers, -- Ruslan Ermilov Oracle Developer/DBA, ru@sunbay.com Sunbay Software AG, ru@FreeBSD.org FreeBSD committer, +380.652.512.251 Simferopol, Ukraine http://www.FreeBSD.org The Power To Serve http://www.oracle.com Enabling The Information Age --fUYQa+Pmc3FrFX/N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="setuid.c" #include #include #include int main(void) { uid_t ruid, suid; ruid = getuid(); suid = geteuid(); printf("seteuid() to the fake (%d) UID\n", 12345); if (seteuid((uid_t)12345) == -1) err(1, "seteuid"); printf("setuid() to the real (%d) UID\n", ruid); if (setuid(ruid) == -1) err(1, "setuid"); printf("seteuid() back to the saved (%d) UID\n", suid); if (seteuid(suid) == -1) err(1, "seteuid"); return 0; } --fUYQa+Pmc3FrFX/N-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Thu May 10 2:49:24 2001 Delivered-To: freebsd-audit@freebsd.org Received: from whale.sunbay.crimea.ua (whale.sunbay.crimea.ua [212.110.138.65]) by hub.freebsd.org (Postfix) with ESMTP id DB12737B422 for ; Thu, 10 May 2001 02:49:20 -0700 (PDT) (envelope-from ru@whale.sunbay.crimea.ua) Received: (from ru@localhost) by whale.sunbay.crimea.ua (8.11.2/8.11.2) id f4A9mxO30242; Thu, 10 May 2001 12:48:59 +0300 (EEST) (envelope-from ru) Date: Thu, 10 May 2001 12:48:58 +0300 From: Ruslan Ermilov To: Kris Kennaway Cc: Bruce Evans , audit@FreeBSD.ORG Subject: Re: ping6 fixes Message-ID: <20010510124858.D19855@sunbay.com> References: <20010508152816.A58026@sunbay.com> <20010509203740.A49874@xor.obsecurity.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5i In-Reply-To: <20010509203740.A49874@xor.obsecurity.org>; from kris@obsecurity.org on Wed, May 09, 2001 at 08:37:40PM -0700 Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG On Wed, May 09, 2001 at 08:37:40PM -0700, Kris Kennaway wrote: > On Wed, May 09, 2001 at 04:20:44AM +1000, Bruce Evans wrote: > > > I think I now understand the purpose of seteuid() before seteuid(). > > Me too. Thanks, all. > /me still doesn't. As I said, this would only be meaningful if: 1) we follow POSIX.1-200x - and - 2) the process doesn't have "appropriate privilege" initially, i.e., it's not setuid root (not the case here). Cheers, -- Ruslan Ermilov Oracle Developer/DBA, ru@sunbay.com Sunbay Software AG, ru@FreeBSD.org FreeBSD committer, +380.652.512.251 Simferopol, Ukraine http://www.FreeBSD.org The Power To Serve http://www.oracle.com Enabling The Information Age To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Thu May 10 3:54:31 2001 Delivered-To: freebsd-audit@freebsd.org Received: from mailman.zeta.org.au (mailman.zeta.org.au [203.26.10.16]) by hub.freebsd.org (Postfix) with ESMTP id 95B5337B422; Thu, 10 May 2001 03:54:27 -0700 (PDT) (envelope-from bde@zeta.org.au) Received: from bde.zeta.org.au (bde.zeta.org.au [203.2.228.102]) by mailman.zeta.org.au (8.9.3/8.8.7) with ESMTP id UAA31793; Thu, 10 May 2001 20:54:21 +1000 Date: Thu, 10 May 2001 20:52:50 +1000 (EST) From: Bruce Evans X-Sender: bde@besplex.bde.org To: Ruslan Ermilov Cc: Kris Kennaway , audit@FreeBSD.ORG Subject: Re: ping6 fixes In-Reply-To: <20010510124858.D19855@sunbay.com> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG On Thu, 10 May 2001, Ruslan Ermilov wrote: > On Wed, May 09, 2001 at 08:37:40PM -0700, Kris Kennaway wrote: > > On Wed, May 09, 2001 at 04:20:44AM +1000, Bruce Evans wrote: > > > > > I think I now understand the purpose of seteuid() before seteuid(). > > > > Me too. Thanks, all. > > > /me still doesn't. > > As I said, this would only be meaningful if: > > 1) we follow POSIX.1-200x I'm stll not sure about this (haven't seen POSIX.any-200x...). > - and - > > 2) the process doesn't have "appropriate privilege" initially, > i.e., it's not setuid root (not the case here). It saves you from having to know much about the current ids. (Not a good reason, since you really should understand the current ids in set*id programs. And you really should check that set*id() succeeded...) Bruce To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Thu May 10 5:13: 8 2001 Delivered-To: freebsd-audit@freebsd.org Received: from whale.sunbay.crimea.ua (whale.sunbay.crimea.ua [212.110.138.65]) by hub.freebsd.org (Postfix) with ESMTP id 4C7BD37B422 for ; Thu, 10 May 2001 05:13:03 -0700 (PDT) (envelope-from ru@whale.sunbay.crimea.ua) Received: (from ru@localhost) by whale.sunbay.crimea.ua (8.11.2/8.11.2) id f4ACCgY44568; Thu, 10 May 2001 15:12:42 +0300 (EEST) (envelope-from ru) Date: Thu, 10 May 2001 15:12:41 +0300 From: Ruslan Ermilov To: Bruce Evans Cc: Kris Kennaway , audit@FreeBSD.ORG Subject: Re: ping6 fixes Message-ID: <20010510151241.A44027@sunbay.com> References: <20010510124858.D19855@sunbay.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5i In-Reply-To: ; from bde@zeta.org.au on Thu, May 10, 2001 at 08:52:50PM +1000 Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG On Thu, May 10, 2001 at 08:52:50PM +1000, Bruce Evans wrote: > On Thu, 10 May 2001, Ruslan Ermilov wrote: > > > On Wed, May 09, 2001 at 08:37:40PM -0700, Kris Kennaway wrote: > > > On Wed, May 09, 2001 at 04:20:44AM +1000, Bruce Evans wrote: > > > > > > > I think I now understand the purpose of seteuid() before seteuid(). > > > > > > Me too. Thanks, all. > > > > > /me still doesn't. > > > > As I said, this would only be meaningful if: > > > > 1) we follow POSIX.1-200x > > I'm stll not sure about this (haven't seen POSIX.any-200x...). > Don't you know that the drafts are available on www.opengroup.com/austin-l ? > > - and - > > > > 2) the process doesn't have "appropriate privilege" initially, > > i.e., it's not setuid root (not the case here). > > It saves you from having to know much about the current ids. (Not a > good reason, since you really should understand the current ids in > set*id programs. And you really should check that set*id() succeeded...) > But the comment in the code assumes that the current IDs are that of root. Cheers, -- Ruslan Ermilov Oracle Developer/DBA, ru@sunbay.com Sunbay Software AG, ru@FreeBSD.org FreeBSD committer, +380.652.512.251 Simferopol, Ukraine http://www.FreeBSD.org The Power To Serve http://www.oracle.com Enabling The Information Age To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Thu May 10 20:26: 1 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 DFBE237B422 for ; Thu, 10 May 2001 20:25:51 -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 7720D3E0B; Thu, 10 May 2001 20:25:51 -0700 (PDT) To: Bruce Evans Cc: Warner Losh , audit@FreeBSD.ORG Subject: Re: jot(1) patch In-Reply-To: ; from bde@zeta.org.au on "Thu, 10 May 2001 19:04:45 +1000 (EST)" Date: Thu, 10 May 2001 20:25:51 -0700 From: Dima Dorfman Message-Id: <20010511032551.7720D3E0B@bazooka.unixfreak.org> Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG Bruce Evans writes: > On Wed, 9 May 2001, Warner Losh wrote: > > > In message <20010509210433.1BDA13E28@bazooka.unixfreak.org> Dima Dorfman wr > ites: > > : - use getopt > > : - de-register > > > > You should de __P() as well. The changes add a prototype > > > > : -usage() > > : +usage(void) > > > > which breaks K&R compatibility. So do one or the other. The one > > thing worse than old K&R code in the tree is broken K&R code in the > > tree. > > You should just not gratuitously break usage(). usage() is already > declared to take a void in its forward declaration using __P(()), > so using "void" in its definition just breaks K&R support. Fair enough. The attached patch is like the first one I sent, but doesn't include the change to break K&R support. If there's nothing wrong with this could someone please commit it? Thanks, Dima Dorfman dima@unixfreak.org Index: jot.c =================================================================== RCS file: /st/src/FreeBSD/src/usr.bin/jot/jot.c,v retrieving revision 1.14 diff -u -r1.14 jot.c --- jot.c 2000/07/10 05:57:29 1.14 +++ jot.c 2001/05/11 03:23:48 @@ -51,8 +51,8 @@ * Author: John Kunze, Office of Comp. Affairs, UCB */ -#include #include +#include #include #include #include @@ -65,7 +65,7 @@ #define ENDER_DEF 100 #define STEP_DEF 1 -#define isdefault(s) (strcmp((s), "-") == 0) +#define is_default(s) (strcmp((s), "-") == 0) double begin; double ender; @@ -83,11 +83,10 @@ char *sepstring = "\n"; char format[BUFSIZ]; -void getargs __P((int, char *[])); -void getformat __P((void)); +void getformat __P((void)); int getprec __P((char *)); -int putdata __P((double, long)); -static void usage __P((void)); +int putdata __P((double, long)); +static void usage __P((void)); int main(argc, argv) @@ -96,37 +95,15 @@ { double xd, yd; long id; - register double *x = &xd; - register double *y = &yd; - register long *i = &id; - - getargs(argc, argv); - if (randomize) { - *x = (ender - begin) * (ender > begin ? 1 : -1); - for (*i = 1; *i <= reps || infinity; (*i)++) { - *y = (double) arc4random() / ULONG_MAX; - if (putdata(*y * *x + begin, reps - *i)) - errx(1, "range error in conversion"); - } - } else - for (*i = 1, *x = begin; *i <= reps || infinity; (*i)++, *x += s) - if (putdata(*x, reps - *i)) - errx(1, "range error in conversion"); - if (!nofinalnl) - putchar('\n'); - exit(0); -} - -void -getargs(ac, av) - int ac; - char *av[]; -{ - register unsigned int mask = 0; - register int n = 0; + double *x = &xd; + double *y = &yd; + long *i = &id; + unsigned int mask = 0; + int n = 0; + int ch; - while (--ac && **++av == '-' && !isdefault(*av)) - switch ((*av)[1]) { + while ((ch = getopt(argc, argv, "rb:w:cs:np:")) != -1) + switch ((char)ch) { case 'r': randomize = 1; break; @@ -138,72 +115,63 @@ break; case 'b': boring = 1; + /* FALLTHROUGH */ case 'w': - if ((*av)[2]) - strcpy(format, *av + 2); - else if (!--ac) - errx(1, "need context word after -w or -b"); - else - strcpy(format, *++av); + if (strlcpy(format, optarg, sizeof(format)) >= + sizeof(format)) + errx(1, "-%c word too long", ch); break; case 's': - if ((*av)[2]) - sepstring = *av + 2; - else if (!--ac) - errx(1, "need string after -s"); - else - sepstring = *++av; + sepstring = optarg; break; case 'p': - if ((*av)[2]) - prec = atoi(*av + 2); - else if (!--ac) - errx(1, "need number after -p"); - else - prec = atoi(*++av); + prec = atoi(optarg); if (prec <= 0) errx(1, "bad precision value"); break; default: usage(); } + argc -= optind; + argv += optind; - switch (ac) { /* examine args right to left, falling thru cases */ + switch (argc) { /* examine args right to left, falling thru cases */ case 4: - if (!isdefault(av[3])) { - if (!sscanf(av[3], "%lf", &s)) - errx(1, "bad s value: %s", av[3]); + if (!is_default(argv[3])) { + if (!sscanf(argv[3], "%lf", &s)) + errx(1, "bad s value: %s", argv[3]); mask |= 01; } case 3: - if (!isdefault(av[2])) { - if (!sscanf(av[2], "%lf", &ender)) - ender = av[2][strlen(av[2])-1]; + if (!is_default(argv[2])) { + if (!sscanf(argv[2], "%lf", &ender)) + ender = argv[2][strlen(argv[2])-1]; mask |= 02; if (!prec) - n = getprec(av[2]); + n = getprec(argv[2]); } case 2: - if (!isdefault(av[1])) { - if (!sscanf(av[1], "%lf", &begin)) - begin = av[1][strlen(av[1])-1]; + if (!is_default(argv[1])) { + if (!sscanf(argv[1], "%lf", &begin)) + begin = argv[1][strlen(argv[1])-1]; mask |= 04; if (!prec) - prec = getprec(av[1]); + prec = getprec(argv[1]); if (n > prec) /* maximum precision */ prec = n; } case 1: - if (!isdefault(av[0])) { - if (!sscanf(av[0], "%ld", &reps)) - errx(1, "bad reps value: %s", av[0]); + if (!is_default(argv[0])) { + if (!sscanf(argv[0], "%ld", &reps)) + errx(1, "bad reps value: %s", argv[0]); mask |= 010; } break; case 0: usage(); default: - errx(1, "too many arguments. What do you mean by %s?", av[4]); + errx(1, "too many arguments. What do you mean by %s?", + argv[4]); } getformat(); while (mask) /* 4 bit mask has 1's where last 4 args were given */ @@ -257,7 +225,7 @@ mask = 015; break; case 012: - s = (randomize ? -1.0 : STEP_DEF); + s = (randomize ? time(NULL) : STEP_DEF); mask = 013; break; case 013: @@ -265,8 +233,7 @@ begin = BEGIN_DEF; else if (reps == 0) errx(1, "must specify begin if reps == 0"); - else - begin = ender - reps * s + s; + begin = ender - reps * s + s; mask = 0; break; case 014: @@ -306,6 +273,20 @@ } if (reps == 0) infinity = 1; + if (randomize) { + *x = (ender - begin) * (ender > begin ? 1 : -1); + for (*i = 1; *i <= reps || infinity; (*i)++) { + *y = (double) arc4random() / ULONG_MAX; + if (putdata(*y * *x + begin, reps - *i)) + errx(1, "range error in conversion"); + } + } else + for (*i = 1, *x = begin; *i <= reps || infinity; (*i)++, *x += s) + if (putdata(*x, reps - *i)) + errx(1, "range error in conversion"); + if (!nofinalnl) + putchar('\n'); + exit(0); } int @@ -358,8 +339,8 @@ getprec(s) char *s; { - register char *p; - register char *q; + char *p; + char *q; for (p = s; *p; p++) if (*p == '.') @@ -375,8 +356,9 @@ void getformat() { - register char *p; + char *p; int dot, hash, space, sign, numbers = 0; + size_t sz; char *s; if (boring) /* no need to bother */ @@ -384,14 +366,19 @@ for (p = format; *p; p++) /* look for '%' */ if (*p == '%' && *(p+1) != '%') /* leave %% alone */ break; - if (!*p && !chardata) - sprintf(p, "%%.%df", prec); - else if (!*p && chardata) { - strcpy(p, "%c"); + sz = sizeof(format) - strlen(format) - 1; + if (!*p && !chardata) { + if (snprintf(p, sz, "%%.%df", prec) >= (int)sz) + errx(1, "-w word too long"); + } else if (!*p && chardata) { + if (strlcpy(p, "%c", sz) >= sz) + errx(1, "-w word too long"); intdata = 1; - } else if (!*(p+1)) + } else if (!*(p+1)) { + if (sz <= 0) + errx(1, "-w word too long"); strcat(format, "%"); /* cannot end in single '%' */ - else { + } else { /* * Allow conversion format specifiers of the form * %[#][ ][{+,-}][0-9]*[.[0-9]*]? where ? must be one of To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Fri May 11 4:41:46 2001 Delivered-To: freebsd-audit@freebsd.org Received: from whale.sunbay.crimea.ua (whale.sunbay.crimea.ua [212.110.138.65]) by hub.freebsd.org (Postfix) with ESMTP id 605B737B422 for ; Fri, 11 May 2001 04:39:12 -0700 (PDT) (envelope-from ru@whale.sunbay.crimea.ua) Received: (from ru@localhost) by whale.sunbay.crimea.ua (8.11.2/8.11.2) id f4BBd5q58998; Fri, 11 May 2001 14:39:05 +0300 (EEST) (envelope-from ru) Date: Fri, 11 May 2001 14:39:05 +0300 From: Ruslan Ermilov To: audit@FreeBSD.org, freebsd-standards@bostonradio.org Subject: Please review: new implementation of hsearch(3) Message-ID: <20010511143904.A58159@sunbay.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="h31gzZEtNLTqOjlF" Content-Disposition: inline User-Agent: Mutt/1.2.5i Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG --h31gzZEtNLTqOjlF Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hi! Our current hsearch(3) implementation is buggy in many ways. The most limiting factor is that it can only handle char * item.data despite the type was recently changed to void *. (See example in the manpage.) The attached patch merely merges NetBSD re-implementation of the hsearch(3), which is POSIX.1-200x conformant. Cheers, -- Ruslan Ermilov Oracle Developer/DBA, ru@sunbay.com Sunbay Software AG, ru@FreeBSD.org FreeBSD committer, +380.652.512.251 Simferopol, Ukraine http://www.FreeBSD.org The Power To Serve http://www.oracle.com Enabling The Information Age --h31gzZEtNLTqOjlF Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="libc_hsearch.patch" Index: db/hash/Makefile.inc =================================================================== RCS file: /home/ncvs/src/lib/libc/db/hash/Makefile.inc,v retrieving revision 1.3 diff -u -p -r1.3 Makefile.inc --- db/hash/Makefile.inc 1999/08/27 23:58:18 1.3 +++ db/hash/Makefile.inc 2001/05/11 10:59:18 @@ -4,4 +4,4 @@ .PATH: ${.CURDIR}/../libc/db/hash SRCS+= hash.c hash_bigkey.c hash_buf.c hash_func.c hash_log2.c \ - hash_page.c hsearch.c ndbm.c + hash_page.c ndbm.c Index: db/hash/hsearch.c =================================================================== RCS file: hsearch.c diff -N hsearch.c --- /home/ru/tmp/cvskuzjM35216 Fri May 11 13:59:18 2001 +++ /dev/null Fri May 11 10:43:20 2001 @@ -1,109 +0,0 @@ -/*- - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Margo Seltzer. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD: src/lib/libc/db/hash/hsearch.c,v 1.3 2000/07/06 20:04:34 alfred Exp $ - */ - -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)hsearch.c 8.4 (Berkeley) 7/21/94"; -#endif /* LIBC_SCCS and not lint */ - -#include - -#include -#include - -#include -#include - -static DB *dbp = NULL; -static ENTRY retval; - -extern int -hcreate(nel) - size_t nel; -{ - HASHINFO info; - - info.nelem = nel; - info.bsize = 256; - info.ffactor = 8; - info.cachesize = 0; - info.hash = NULL; - info.lorder = 0; - dbp = (DB *)__hash_open(NULL, O_CREAT | O_RDWR, 0600, &info, 0); - return (dbp != NULL); -} - -extern ENTRY * -hsearch(item, action) - ENTRY item; - ACTION action; -{ - DBT key, val; - int status; - - if (!dbp) - return (NULL); - key.data = (u_char *)item.key; - key.size = strlen(item.key) + 1; - - if (action == ENTER) { - val.data = (u_char *)item.data; - val.size = strlen(item.data) + 1; - status = (dbp->put)(dbp, &key, &val, R_NOOVERWRITE); - if (status) - return (NULL); - } else { - /* FIND */ - status = (dbp->get)(dbp, &key, &val, 0); - if (status) - return (NULL); - else - item.data = (char *)val.data; - } - retval.key = item.key; - retval.data = item.data; - return (&retval); -} - -extern void -hdestroy() -{ - if (dbp) { - (void)(dbp->close)(dbp); - dbp = NULL; - } -} Index: stdlib/Makefile.inc =================================================================== RCS file: /home/ncvs/src/lib/libc/stdlib/Makefile.inc,v retrieving revision 1.26 diff -u -p -r1.26 Makefile.inc --- stdlib/Makefile.inc 2001/04/23 11:11:00 1.26 +++ stdlib/Makefile.inc 2001/05/11 10:59:18 @@ -5,8 +5,8 @@ .PATH: ${.CURDIR}/../libc/${MACHINE_ARCH}/stdlib ${.CURDIR}/../libc/stdlib MISRCS+=abort.c abs.c atexit.c atof.c atoi.c atol.c bsearch.c calloc.c div.c \ - exit.c getenv.c getopt.c getsubopt.c heapsort.c labs.c ldiv.c \ - malloc.c merge.c putenv.c qsort.c radixsort.c rand.c random.c \ + exit.c getenv.c getopt.c getsubopt.c hcreate.c heapsort.c labs.c \ + ldiv.c malloc.c merge.c putenv.c qsort.c radixsort.c rand.c random.c \ reallocf.c realpath.c setenv.c strhash.c strtol.c strtoll.c strtoq.c \ strtoul.c strtoull.c strtouq.c system.c tdelete.c tfind.c tsearch.c \ twalk.c @@ -25,11 +25,12 @@ SRCS+= strtod.c .if ${LIB} == "c" MAN+= abort.3 abs.3 alloca.3 atexit.3 atof.3 atoi.3 atol.3 bsearch.3 \ - div.3 exit.3 getenv.3 getopt.3 getsubopt.3 labs.3 \ + div.3 exit.3 getenv.3 getopt.3 getsubopt.3 hcreate.3 labs.3 \ ldiv.3 malloc.3 memory.3 qsort.3 radixsort.3 rand.3 random.3 \ realpath.3 strtod.3 strtol.3 strtoul.3 system.3 tsearch.3 MLINKS+=getenv.3 putenv.3 getenv.3 setenv.3 getenv.3 unsetenv.3 +MLINKS+=hcreate.3 hdestroy.3 hcreate.3 hsearch.3 MLINKS+=qsort.3 heapsort.3 qsort.3 mergesort.3 MLINKS+=rand.3 rand_r.3 rand.3 srand.3 rand.3 sranddev.3 MLINKS+=random.3 initstate.3 random.3 setstate.3 random.3 srandom.3 \ Index: stdlib/hcreate.3 =================================================================== RCS file: hcreate.3 diff -N hcreate.3 --- /dev/null Fri May 11 10:43:20 2001 +++ hcreate.3 Fri May 11 13:59:18 2001 @@ -0,0 +1,206 @@ +.\" $FreeBSD$ +.\" +.Dd May 8, 2001 +.Os +.Dt HCREATE 3 +.Sh NAME +.Nm hcreate , hdestroy , hsearch +.Nd manage hash search table +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In search.h +.Ft int +.Fn hcreate "size_t nel" +.Ft void +.Fn hdestroy void +.Ft ENTRY * +.Fn hsearch "ENTRY item" "ACTION action" +.Sh DESCRIPTION +The +.Fn hcreate , +.Fn hdestroy , +and +.Fn hsearch +functions manage hash search tables. +.Pp +The +.Fn hcreate +function allocates sufficient space for the table, and the application should +ensure it is called before +.Fn hsearch +is used. +The +.Fa nel +argument is an estimate of the maximum +number of entries that the table should contain. +This number may be adjusted upward by the +algorithm in order to obtain certain mathematically favorable circumstances. +.Pp +The +.Fn hdestroy +function disposes of the search table, and may be followed by another call to +.Fn hcreate . +After the call to +.Fn hdestroy , +the data can no longer be considered accessible. +.Pp +The +.Fn hsearch +function is a hash-table search routine. +It returns a pointer into a hash table +indicating the location at which an entry can be found. +The +.Fa item +argument is a structure of type +.Vt ENTRY +(defined in the +.Aq Pa search.h +header) containing two pointers: +.Fa item.key +points to the comparison key (a +.Vt "char *" ) , +and +.Fa item.data +(a +.Vt "void *" ) +points to any other data to be associated with +that key. +The comparison function used by +.Fn hsearch +is +.Xr strcmp 3 . +The +.Fa action +argument is a +member of an enumeration type +.Vt ACTION +indicating the disposition of the entry if it cannot be +found in the table. +.Dv ENTER +indicates that the +.Fa item +should be inserted in the table at an +appropriate point. +.Dv FIND +indicates that no entry should be made. +Unsuccessful resolution is +indicated by the return of a +.Dv NULL +pointer. +.Sh RETURN VALUES +The +.Fn hcreate +function returns 0 if it cannot allocate sufficient space for the table; +otherwise, it returns non-zero. +.Pp +The +.Fn hdestroy +function does not return a value. +.Pp +The +.Fn hsearch +function returns a +.Dv NULL +pointer if either the +.Fa action +is +.Dv FIND +and the +.Fa item +could not be found or the +.Fa action +is +.Dv ENTER +and the table is full. +.Sh ERRORS +The +.Fn hcreate +and +.Fn hsearch +functions may fail if: +.Bl -tag -width Er +.It Bq Er ENOMEM +Insufficient storage space is available. +.El +.Sh EXAMPLES +The following example reads in strings followed by two numbers +and stores them in a hash table, discarding duplicates. +It then reads in strings and finds the matching entry in the hash +table and prints it out. +.Bd -literal +#include +#include +#include + +struct info { /* This is the info stored in the table */ + int age, room; /* other than the key. */ +}; + +#define NUM_EMPL 5000 /* # of elements in search table. */ + +int +main(void) +{ + char string_space[NUM_EMPL*20]; /* Space to store strings. */ + struct info info_space[NUM_EMPL]; /* Space to store employee info. */ + char *str_ptr = string_space; /* Next space in string_space. */ + struct info *info_ptr = info_space; /* Next space in info_space. */ + ENTRY item; + ENTRY *found_item; /* Name to look for in table. */ + char name_to_find[30]; + int i = 0; + + /* Create table; no error checking is performed. */ + (void) hcreate(NUM_EMPL); + + while (scanf("%s%d%d", str_ptr, &info_ptr->age, + &info_ptr->room) != EOF && i++ < NUM_EMPL) { + /* Put information in structure, and structure in item. */ + item.key = str_ptr; + item.data = info_ptr; + str_ptr += strlen(str_ptr) + 1; + info_ptr++; + /* Put item into table. */ + (void) hsearch(item, ENTER); + } + + /* Access table. */ + item.key = name_to_find; + while (scanf("%s", item.key) != EOF) { + if ((found_item = hsearch(item, FIND)) != NULL) { + /* If item is in the table. */ + (void)printf("found %s, age = %d, room = %d\n", + found_item->key, + ((struct info *)found_item->data)->age, + ((struct info *)found_item->data)->room); + } else + (void)printf("no such employee %s\n", name_to_find); + } + return 0; +} +.Ed +.Sh SEE ALSO +.Xr bsearch 3 , +.Xr lsearch 3 , +.Xr malloc 3 , +.Xr strcmp 3 , +.Xr tsearch 3 +.Sh STANDARDS +The +.Fn hcreate , +.Fn hdestroy , +and +.Fn hsearch +functions conform to +.St -xpg4.2 . +.Sh HISTORY +The +.Fn hcreate , +.Fn hdestroy , +and +.Fn hsearch +functions first appeared in +.At V . +.Sh BUGS +The interface permits the use of only one hash table at a time. Index: stdlib/hcreate.c =================================================================== RCS file: hcreate.c diff -N hcreate.c --- /dev/null Fri May 11 10:43:20 2001 +++ hcreate.c Fri May 11 13:59:18 2001 @@ -0,0 +1,184 @@ +/* $NetBSD: hcreate.c,v 1.2 2001/02/19 21:26:04 ross Exp $ */ +/* $FreeBSD$ */ + +/* + * Copyright (c) 2001 Christopher G. Demetriou + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed for the + * NetBSD Project. See http://www.netbsd.org/ for + * information about NetBSD. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * <> + */ + +/* + * hcreate() / hsearch() / hdestroy() + * + * SysV/XPG4 hash table functions. + * + * Implementation done based on NetBSD manual page and Solaris manual page, + * plus my own personal experience about how they're supposed to work. + * + * I tried to look at Knuth (as cited by the Solaris manual page), but + * nobody had a copy in the office, so... + */ + +#include +#if defined(LIBC_SCCS) && !defined(lint) +__RCSID("$NetBSD: hcreate.c,v 1.2 2001/02/19 21:26:04 ross Exp $"); +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include "namespace.h" + +/* + * DO NOT MAKE THIS STRUCTURE LARGER THAN 32 BYTES (4 ptrs on 64-bit + * ptr machine) without adjusting MAX_BUCKETS_LG2 below. + */ +struct internal_entry { + SLIST_ENTRY(internal_entry) link; + ENTRY ent; +}; +SLIST_HEAD(internal_head, internal_entry); + +#define MIN_BUCKETS_LG2 4 +#define MIN_BUCKETS (1 << MIN_BUCKETS_LG2) + +/* + * max * sizeof internal_entry must fit into size_t. + * assumes internal_entry is <= 32 (2^5) bytes. + */ +#define MAX_BUCKETS_LG2 (sizeof (size_t) * 8 - 1 - 5) +#define MAX_BUCKETS ((size_t)1 << MAX_BUCKETS_LG2) + +/* Default hash function, from db/hash/hash_func.c */ +extern u_int32_t (*__default_hash)(const void *, size_t); + +static struct internal_head *htable; +static size_t htablesize; + +int +hcreate(size_t nel) +{ + size_t idx; + unsigned int p2; + + /* Make sure this this isn't called when a table already exists. */ + if (htable != NULL) { + errno = EINVAL; + return 0; + } + + /* If nel is too small, make it min sized. */ + if (nel < MIN_BUCKETS) + nel = MIN_BUCKETS; + + /* If it's too large, cap it. */ + if (nel > MAX_BUCKETS) + nel = MAX_BUCKETS; + + /* If it's is not a power of two in size, round up. */ + if ((nel & (nel - 1)) != 0) { + for (p2 = 0; nel != 0; p2++) + nel >>= 1; + nel = 1 << p2; + } + + /* Allocate the table. */ + htablesize = nel; + htable = malloc(htablesize * sizeof htable[0]); + if (htable == NULL) { + errno = ENOMEM; + return 0; + } + + /* Initialize it. */ + for (idx = 0; idx < htablesize; idx++) + SLIST_INIT(&htable[idx]); + + return 1; +} + +void +hdestroy(void) +{ + struct internal_entry *ie; + size_t idx; + + if (htable == NULL) + return; + + for (idx = 0; idx < htablesize; idx++) { + while (!SLIST_EMPTY(&htable[idx])) { + ie = SLIST_FIRST(&htable[idx]); + SLIST_REMOVE_HEAD(&htable[idx], link); + free(ie->ent.key); + free(ie); + } + } + free(htable); + htable = NULL; +} + +ENTRY * +hsearch(ENTRY item, ACTION action) +{ + struct internal_head *head; + struct internal_entry *ie; + uint32_t hashval; + size_t len; + + len = strlen(item.key); + hashval = (*__default_hash)(item.key, len); + + head = &htable[hashval & (htablesize - 1)]; + ie = SLIST_FIRST(head); + while (ie != NULL) { + if (strcmp(ie->ent.key, item.key) == 0) + break; + ie = SLIST_NEXT(ie, link); + } + + if (ie != NULL) + return &ie->ent; + else if (action == FIND) + return NULL; + + ie = malloc(sizeof *ie); + if (ie == NULL) + return NULL; + ie->ent.key = item.key; + ie->ent.data = item.data; + + SLIST_INSERT_HEAD(head, ie, link); + return &ie->ent; +} --h31gzZEtNLTqOjlF-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Sat May 12 0: 6: 2 2001 Delivered-To: freebsd-audit@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 885) id A5AEC37B423; Sat, 12 May 2001 00:05:59 -0700 (PDT) Date: Sat, 12 May 2001 00:05:59 -0700 From: Eric Melville To: freebsd-audit@freebsd.org Subject: login(1) patch Message-ID: <20010512000559.B12766@FreeBSD.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5i Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG Check for account expiration and password expiration in the proper order. Obtained from OpenBSD. Any objections or comments? Index: login.c =================================================================== RCS file: /home/ncvs/src/usr.bin/login/login.c,v retrieving revision 1.57 diff -u -r1.57 login.c --- login.c 2001/03/27 19:40:50 1.57 +++ login.c 2001/05/12 02:19:31 @@ -415,6 +415,19 @@ #define DEFAULT_WARN (2L * 7L * 86400L) /* Two weeks */ + + warntime = login_getcaptime(lc, "warnexpire", + DEFAULT_WARN, DEFAULT_WARN); + + if (pwd->pw_expire) { + if (tp.tv_sec >= pwd->pw_expire) { + refused("Sorry -- your account has expired", + "EXPIRED", 1); + } else if (pwd->pw_expire - tp.tv_sec < warntime && !quietlog) + (void)printf("Warning: your account expires on %s", + ctime(&pwd->pw_expire)); + } + warntime = login_getcaptime(lc, "warnpassword", DEFAULT_WARN, DEFAULT_WARN); @@ -429,18 +442,6 @@ } else if (pwd->pw_change - tp.tv_sec < warntime && !quietlog) (void)printf("Warning: your password expires on %s", ctime(&pwd->pw_change)); - } - - warntime = login_getcaptime(lc, "warnexpire", - DEFAULT_WARN, DEFAULT_WARN); - - if (pwd->pw_expire) { - if (tp.tv_sec >= pwd->pw_expire) { - refused("Sorry -- your account has expired", - "EXPIRED", 1); - } else if (pwd->pw_expire - tp.tv_sec < warntime && !quietlog) - (void)printf("Warning: your account expires on %s", - ctime(&pwd->pw_expire)); } if (lc != NULL) { To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Sat May 12 11: 9:11 2001 Delivered-To: freebsd-audit@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 885) id 72CAC37B424; Sat, 12 May 2001 11:09:10 -0700 (PDT) Date: Sat, 12 May 2001 11:09:10 -0700 From: Eric Melville To: freebsd-audit@freebsd.org Subject: MFC for last window(1) patch Message-ID: <20010512110910.A51717@FreeBSD.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5i Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG I probably ought to MFC this to kill another mktemp(3) from the tree. It's the same thing that I committed a couple weeks back aside from the line numbers. Also, I frequently see "foo.h" instead of for including system wide headers in the older source. Is this something that should be changed, or does the fact that it works fine mean it should stay the same? Index: scanner.c =================================================================== RCS file: /home/ncvs/src/usr.bin/window/scanner.c,v retrieving revision 1.2 diff -r1.2 scanner.c 45a46 > #include "mystring.h" Index: wwterminfo.c =================================================================== RCS file: /home/ncvs/src/usr.bin/window/wwterminfo.c,v retrieving revision 1.3 diff -r1.3 wwterminfo.c 66,67c66 < mktemp(wwterminfopath); < if (mkdir(wwterminfopath, 0755) < 0 || --- > if (mkdtemp(wwterminfopath) < 0 || To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Sat May 12 20:42:52 2001 Delivered-To: freebsd-audit@freebsd.org Received: from fledge.watson.org (fledge.watson.org [204.156.12.50]) by hub.freebsd.org (Postfix) with ESMTP id A362B37B423 for ; Sat, 12 May 2001 20:41:55 -0700 (PDT) (envelope-from robert@fledge.watson.org) Received: from fledge.watson.org (robert@fledge.pr.watson.org [192.0.2.3]) by fledge.watson.org (8.11.3/8.11.3) with SMTP id f4D3fpf49857 for ; Sat, 12 May 2001 23:41:51 -0400 (EDT) (envelope-from robert@fledge.watson.org) Date: Sat, 12 May 2001 23:41:51 -0400 (EDT) From: Robert Watson X-Sender: robert@fledge.watson.org To: audit@FreeBSD.org Subject: RE: Patch to eliminate struct pcred (fwd) In-Reply-To: Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG Attached, please find revision 4 of the pcred merge into ucred patch. Differences from pcred.3.diff are: - add alpha/osf1 support to pcred patch, missed in previous iterations - fix bug in newcred/oldcred handling introduced in kern_exec in pcred.3.diff Otherwise the changes remain the same. I notice that one of the comments I added about the saved uid behavior is consistent with the concerns expressed by Ruslan, and I think we should revisit these after I finish the pcred merge. For now, I'm attempting to maintain consistent behavior with the pre-pcred-merge, but we should discuss this in detail and figure out whether current behavior is "right", and document it properly if so, and fix it if not. Robert N M Watson FreeBSD Core Team, TrustedBSD Project robert@fledge.watson.org NAI Labs, Safeport Network Services ? compile/GENERIC ? compile/LINT ? i386/conf/LINT Index: alpha/osf1/osf1_misc.c =================================================================== RCS file: /home/ncvs/src/sys/alpha/osf1/osf1_misc.c,v retrieving revision 1.13 diff -u -r1.13 osf1_misc.c --- alpha/osf1/osf1_misc.c 2001/05/01 08:11:49 1.13 +++ alpha/osf1/osf1_misc.c 2001/05/13 03:23:41 @@ -1054,29 +1054,32 @@ { int error; uid_t uid; - register struct pcred *pc; + struct ucred *oldcred, *newcred; uid = SCARG(uap, uid); - pc = p->p_cred; + oldcred = p->p_ucred; if ((error = suser(p)) != 0 && - uid != pc->p_ruid && uid != pc->p_svuid) + uid != oldcred->cr_ruid && uid != oldcred->cr_svuid) return (error); + newcred = crdup(oldcred); if (error == 0) { - if (uid != pc->p_ruid) { - change_ruid(p, uid); + if (uid != oldcred->cr_ruid) { + change_ruid(newcred, uid); setsugid(p); } - if (pc->p_svuid != uid) { - pc->p_svuid = uid; + if (oldcred->cr_svuid != uid) { + change_svuid(newcred, uid); setsugid(p); } } - if (pc->pc_ucred->cr_uid != uid) { - change_euid(p, uid); + if (newcred->cr_uid != uid) { + change_euid(newcred, uid); setsugid(p); } + p->p_ucred = newcred; + crfree(oldcred); return (0); } @@ -1095,22 +1098,32 @@ { int error; gid_t gid; - register struct pcred *pc; + struct ucred *oldcred, *newcred; gid = SCARG(uap, gid); - pc = p->p_cred; + oldcred = p->p_ucred; if (((error = suser(p)) != 0 ) && - gid != pc->p_rgid && gid != pc->p_svgid) + gid != oldcred->cr_rgid && gid != oldcred->cr_svgid) return (error); - pc->pc_ucred = crcopy(pc->pc_ucred); - pc->pc_ucred->cr_gid = gid; + newcred = crdup(oldcred); if (error == 0) { - pc->p_rgid = gid; - pc->p_svgid = gid; + if (gid != oldcred->cr_rgid) { + change_rgid(newcred, gid); + setsugid(p); + } + if (oldcred->cr_svgid != gid) { + change_svgid(newcred, gid); + setsugid(p); + } + } + if (newcred->cr_groups[0] != gid) { + change_egid(newcred, gid); + setsugid(p); } - setsugid(p); + p->p_ucred = newcred; + crfree(oldcred); return (0); } Index: compat/linprocfs/linprocfs_misc.c =================================================================== RCS file: /home/ncvs/src/sys/compat/linprocfs/linprocfs_misc.c,v retrieving revision 1.24 diff -u -r1.24 linprocfs_misc.c --- compat/linprocfs/linprocfs_misc.c 2001/05/01 08:11:51 1.24 +++ compat/linprocfs/linprocfs_misc.c 2001/05/13 03:23:46 @@ -444,14 +444,14 @@ PROC_LOCK(p); sbuf_printf(&sb, "PPid:\t%d\n", p->p_pptr ? p->p_pptr->p_pid : 0); - sbuf_printf(&sb, "Uid:\t%d %d %d %d\n", p->p_cred->p_ruid, + sbuf_printf(&sb, "Uid:\t%d %d %d %d\n", p->p_ucred->cr_ruid, p->p_ucred->cr_uid, - p->p_cred->p_svuid, + p->p_ucred->cr_svuid, /* FreeBSD doesn't have fsuid */ p->p_ucred->cr_uid); - sbuf_printf(&sb, "Gid:\t%d %d %d %d\n", p->p_cred->p_rgid, + sbuf_printf(&sb, "Gid:\t%d %d %d %d\n", p->p_ucred->cr_rgid, p->p_ucred->cr_gid, - p->p_cred->p_svgid, + p->p_ucred->cr_svgid, /* FreeBSD doesn't have fsgid */ p->p_ucred->cr_gid); sbuf_cat(&sb, "Groups:\t"); @@ -543,7 +543,7 @@ char *freepath = NULL; p = PFIND(pfs->pfs_pid); - if (p == NULL || p->p_cred == NULL || p->p_ucred == NULL) { + if (p == NULL || p->p_ucred == NULL) { if (p != NULL) PROC_UNLOCK(p); printf("doexelink: pid %d disappeared\n", pfs->pfs_pid); Index: compat/linprocfs/linprocfs_vnops.c =================================================================== RCS file: /home/ncvs/src/sys/compat/linprocfs/linprocfs_vnops.c,v retrieving revision 1.23 diff -u -r1.23 linprocfs_vnops.c --- compat/linprocfs/linprocfs_vnops.c 2001/05/04 05:19:22 1.23 +++ compat/linprocfs/linprocfs_vnops.c 2001/05/13 03:23:46 @@ -432,7 +432,7 @@ procp = PFIND(pfs->pfs_pid); if (procp == NULL) return (ENOENT); - if (procp->p_cred == NULL || procp->p_ucred == NULL) { + if (procp->p_ucred == NULL) { PROC_UNLOCK(procp); return (ENOENT); } Index: compat/linux/linux_misc.c =================================================================== RCS file: /home/ncvs/src/sys/compat/linux/linux_misc.c,v retrieving revision 1.101 diff -u -r1.101 linux_misc.c --- compat/linux/linux_misc.c 2001/05/01 08:11:51 1.101 +++ compat/linux/linux_misc.c 2001/05/13 03:23:47 @@ -958,12 +958,11 @@ struct proc *p; struct linux_setgroups_args *uap; { - struct pcred *pc; + struct ucred *newcred, *oldcred = p->p_ucred; linux_gid_t linux_gidset[NGROUPS]; gid_t *bsd_gidset; int ngrp, error; - pc = p->p_cred; ngrp = uap->gidsetsize; /* @@ -972,22 +971,22 @@ * Keep cr_groups[0] unchanged to prevent that. */ - if ((error = suser_xxx(NULL, p, PRISON_ROOT)) != 0) + if ((error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) return (error); if (ngrp >= NGROUPS) return (EINVAL); - pc->pc_ucred = crcopy(pc->pc_ucred); + newcred = crdup(oldcred); if (ngrp > 0) { error = copyin((caddr_t)uap->gidset, (caddr_t)linux_gidset, ngrp * sizeof(linux_gid_t)); if (error) return (error); - pc->pc_ucred->cr_ngroups = ngrp + 1; + newcred->cr_ngroups = ngrp + 1; - bsd_gidset = pc->pc_ucred->cr_groups; + bsd_gidset = newcred->cr_groups; ngrp--; while (ngrp >= 0) { bsd_gidset[ngrp + 1] = linux_gidset[ngrp]; @@ -995,9 +994,13 @@ } } else - pc->pc_ucred->cr_ngroups = 1; + newcred->cr_ngroups = 1; setsugid(p); + + p->p_ucred = newcred; + crfree(oldcred); + return (0); } @@ -1006,14 +1009,14 @@ struct proc *p; struct linux_getgroups_args *uap; { - struct pcred *pc; + struct ucred *cred; linux_gid_t linux_gidset[NGROUPS]; gid_t *bsd_gidset; int bsd_gidsetsz, ngrp, error; - pc = p->p_cred; - bsd_gidset = pc->pc_ucred->cr_groups; - bsd_gidsetsz = pc->pc_ucred->cr_ngroups - 1; + cred = p->p_ucred; + bsd_gidset = cred->cr_groups; + bsd_gidsetsz = cred->cr_ngroups - 1; /* * cr_groups[0] holds egid. Returning the whole set Index: compat/svr4/svr4_misc.c =================================================================== RCS file: /home/ncvs/src/sys/compat/svr4/svr4_misc.c,v retrieving revision 1.30 diff -u -r1.30 svr4_misc.c --- compat/svr4/svr4_misc.c 2001/05/01 08:11:52 1.30 +++ compat/svr4/svr4_misc.c 2001/05/13 03:23:48 @@ -1283,7 +1283,7 @@ /* * Decrement the count of procs running with this uid. */ - (void)chgproccnt(q->p_cred->p_uidinfo, -1, 0); + (void)chgproccnt(q->p_ucred->cr_ruidinfo, -1, 0); /* * Release reference to text vnode. @@ -1294,13 +1294,8 @@ /* * Free up credentials. */ - PROC_LOCK(q); - if (--q->p_cred->p_refcnt == 0) { - crfree(q->p_ucred); - uifree(q->p_cred->p_uidinfo); - FREE(q->p_cred, M_SUBPROC); - q->p_cred = NULL; - } + crfree(q->p_ucred); + q->p_ucred = NULL; /* * Remove unused arguments Index: compat/svr4/svr4_sysvec.c =================================================================== RCS file: /home/ncvs/src/sys/compat/svr4/svr4_sysvec.c,v retrieving revision 1.20 diff -u -r1.20 svr4_sysvec.c --- compat/svr4/svr4_sysvec.c 2001/02/24 22:20:02 1.20 +++ compat/svr4/svr4_sysvec.c 2001/05/13 03:23:48 @@ -213,10 +213,10 @@ AUXARGS_ENTRY(pos, AT_FLAGS, args->flags); AUXARGS_ENTRY(pos, AT_ENTRY, args->entry); AUXARGS_ENTRY(pos, AT_BASE, args->base); - AUXARGS_ENTRY(pos, AT_UID, imgp->proc->p_cred->p_ruid); - AUXARGS_ENTRY(pos, AT_EUID, imgp->proc->p_cred->p_svuid); - AUXARGS_ENTRY(pos, AT_GID, imgp->proc->p_cred->p_rgid); - AUXARGS_ENTRY(pos, AT_EGID, imgp->proc->p_cred->p_svgid); + AUXARGS_ENTRY(pos, AT_UID, imgp->proc->p_ucred->cr_ruid); + AUXARGS_ENTRY(pos, AT_EUID, imgp->proc->p_ucred->cr_svuid); + AUXARGS_ENTRY(pos, AT_GID, imgp->proc->p_ucred->cr_rgid); + AUXARGS_ENTRY(pos, AT_EGID, imgp->proc->p_ucred->cr_svgid); AUXARGS_ENTRY(pos, AT_NULL, 0); free(imgp->auxargs, M_TEMP); Index: ddb/db_ps.c =================================================================== RCS file: /home/ncvs/src/sys/ddb/db_ps.c,v retrieving revision 1.22 diff -u -r1.22 db_ps.c --- ddb/db_ps.c 2001/03/28 09:17:49 1.22 +++ ddb/db_ps.c 2001/05/13 03:23:50 @@ -95,7 +95,7 @@ db_printf("%5d %8p %8p %4d %5d %5d %06x %d", p->p_pid, (volatile void *)p, (void *)p->p_addr, - p->p_cred ? p->p_cred->p_ruid : 0, pp->p_pid, + p->p_ucred ? p->p_ucred->cr_ruid : 0, pp->p_pid, p->p_pgrp ? p->p_pgrp->pg_id : 0, p->p_flag, p->p_stat); if (p->p_wchan) { db_printf(" %6s %8p", p->p_wmesg, (void *)p->p_wchan); Index: i386/linux/linux_sysvec.c =================================================================== RCS file: /home/ncvs/src/sys/i386/linux/linux_sysvec.c,v retrieving revision 1.78 diff -u -r1.78 linux_sysvec.c --- i386/linux/linux_sysvec.c 2001/05/01 08:12:52 1.78 +++ i386/linux/linux_sysvec.c 2001/05/13 03:24:04 @@ -186,10 +186,10 @@ AUXARGS_ENTRY(pos, AT_ENTRY, args->entry); AUXARGS_ENTRY(pos, AT_BASE, args->base); PROC_LOCK(imgp->proc); - AUXARGS_ENTRY(pos, AT_UID, imgp->proc->p_cred->p_ruid); - AUXARGS_ENTRY(pos, AT_EUID, imgp->proc->p_cred->p_svuid); - AUXARGS_ENTRY(pos, AT_GID, imgp->proc->p_cred->p_rgid); - AUXARGS_ENTRY(pos, AT_EGID, imgp->proc->p_cred->p_svgid); + AUXARGS_ENTRY(pos, AT_UID, imgp->proc->p_ucred->cr_ruid); + AUXARGS_ENTRY(pos, AT_EUID, imgp->proc->p_ucred->cr_svuid); + AUXARGS_ENTRY(pos, AT_GID, imgp->proc->p_ucred->cr_rgid); + AUXARGS_ENTRY(pos, AT_EGID, imgp->proc->p_ucred->cr_svgid); PROC_UNLOCK(imgp->proc); AUXARGS_ENTRY(pos, AT_NULL, 0); Index: kern/init_main.c =================================================================== RCS file: /home/ncvs/src/sys/kern/init_main.c,v retrieving revision 1.168 diff -u -r1.168 init_main.c --- kern/init_main.c 2001/04/29 02:44:48 1.168 +++ kern/init_main.c 2001/05/13 03:24:05 @@ -85,7 +85,6 @@ static struct session session0; static struct pgrp pgrp0; struct proc proc0; -static struct pcred cred0; static struct procsig procsig0; static struct filedesc0 filedesc0; static struct plimit limit0; @@ -321,12 +320,10 @@ callout_init(&p->p_slpcallout, 1); /* Create credentials. */ - cred0.p_refcnt = 1; - cred0.p_uidinfo = uifind(0); - p->p_cred = &cred0; p->p_ucred = crget(); p->p_ucred->cr_ngroups = 1; /* group 0 */ p->p_ucred->cr_uidinfo = uifind(0); + p->p_ucred->cr_ruidinfo = uifind(0); p->p_ucred->cr_prison = NULL; /* Don't jail it. */ /* Create procsig. */ @@ -380,7 +377,7 @@ /* * Charge root for one process. */ - (void)chgproccnt(cred0.p_uidinfo, 1, 0); + (void)chgproccnt(p->p_ucred->cr_ruidinfo, 1, 0); } SYSINIT(p0init, SI_SUB_INTRINSIC, SI_ORDER_FIRST, proc0_init, NULL) Index: kern/kern_acct.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_acct.c,v retrieving revision 1.33 diff -u -r1.33 kern_acct.c --- kern/kern_acct.c 2001/05/01 08:12:55 1.33 +++ kern/kern_acct.c 2001/05/13 03:24:05 @@ -222,8 +222,8 @@ acct.ac_io = encode_comp_t(r->ru_inblock + r->ru_oublock, 0); /* (6) The UID and GID of the process */ - acct.ac_uid = p->p_cred->p_ruid; - acct.ac_gid = p->p_cred->p_rgid; + acct.ac_uid = p->p_ucred->cr_ruid; + acct.ac_gid = p->p_ucred->cr_rgid; /* (7) The terminal from which the process was started */ if ((p->p_flag & P_CONTROLT) && p->p_pgrp->pg_session->s_ttyp) Index: kern/kern_descrip.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_descrip.c,v retrieving revision 1.100 diff -u -r1.100 kern_descrip.c --- kern/kern_descrip.c 2001/05/01 08:12:55 1.100 +++ kern/kern_descrip.c 2001/05/13 03:24:06 @@ -525,8 +525,6 @@ sigio->sio_pgid = pgid; crhold(curproc->p_ucred); sigio->sio_ucred = curproc->p_ucred; - /* It would be convenient if p_ruid was in ucred. */ - sigio->sio_ruid = curproc->p_cred->p_ruid; sigio->sio_myref = sigiop; s = splhigh(); *sigiop = sigio; Index: kern/kern_exec.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_exec.c,v retrieving revision 1.126 diff -u -r1.126 kern_exec.c --- kern/kern_exec.c 2001/05/01 08:12:56 1.126 +++ kern/kern_exec.c 2001/05/13 03:24:06 @@ -104,6 +104,7 @@ register struct execve_args *uap; { struct nameidata nd, *ndp; + struct ucred *oldcred = p->p_ucred, *newcred; register_t *stack_base; int error, len, i; struct image_params image_params, *imgp; @@ -274,13 +275,23 @@ } /* + * XXX: Note, the whole execve() is incredibly racey right now + * with regards to debugging and privilege/credential management. + * In particular, it's possible to race during exec() to attach + * debugging to a process that will gain privilege. + * + * This MUST be fixed prior to any release. + */ + + /* * Implement image setuid/setgid. * * Don't honor setuid/setgid if the filesystem prohibits it or if * the process is being traced. */ - if ((((attr.va_mode & VSUID) && p->p_ucred->cr_uid != attr.va_uid) || - ((attr.va_mode & VSGID) && p->p_ucred->cr_gid != attr.va_gid)) && + newcred = NULL; + if ((((attr.va_mode & VSUID) && oldcred->cr_uid != attr.va_uid) || + ((attr.va_mode & VSGID) && oldcred->cr_gid != attr.va_gid)) && (imgp->vp->v_mount->mnt_flag & MNT_NOSUID) == 0 && (p->p_flag & P_TRACED) == 0) { PROC_UNLOCK(p); @@ -288,7 +299,7 @@ * Turn off syscall tracing for set-id programs, except for * root. */ - if (p->p_tracep && suser(p)) { + if (p->p_tracep && suser_xxx(oldcred, NULL, PRISON_ROOT)) { p->p_traceflag = 0; vrele(p->p_tracep); p->p_tracep = NULL; @@ -296,25 +307,64 @@ /* * Set the new credentials. */ - p->p_ucred = crcopy(p->p_ucred); + newcred = crdup(oldcred); if (attr.va_mode & VSUID) - change_euid(p, attr.va_uid); + change_euid(newcred, attr.va_uid); if (attr.va_mode & VSGID) - p->p_ucred->cr_gid = attr.va_gid; + change_egid(newcred, attr.va_gid); setsugid(p); setugidsafety(p); } else { - if (p->p_ucred->cr_uid == p->p_cred->p_ruid && - p->p_ucred->cr_gid == p->p_cred->p_rgid) + if (oldcred->cr_uid == oldcred->cr_ruid && + oldcred->cr_gid == oldcred->cr_rgid) p->p_flag &= ~P_SUGID; PROC_UNLOCK(p); } /* * Implement correct POSIX saved-id behavior. - */ - p->p_cred->p_svuid = p->p_ucred->cr_uid; - p->p_cred->p_svgid = p->p_ucred->cr_gid; + * + * XXX: It's not clear that the existing behavior is + * POSIX-compliant. A number of courses indicate that the saved + * uid/gid should only be updated if the new ruid is not equal to + * the old ruid, or the new euid is not equal to the old euid and + * the new euid is not equal to the old ruid. The FreeBSD code + * always updates the saved uid/gid. Also, this code uses the new + * (replaced) euid and egid as the source, which may or may not be + * the right ones to use. + */ + if (newcred != NULL) { + change_svuid(newcred, newcred->cr_uid); + change_svgid(newcred, newcred->cr_gid); + } else { + /* + * Avoid allocated a newcred if we don't have one yet and + * update would be a noop. + */ + if (oldcred->cr_svuid != oldcred->cr_uid || + oldcred->cr_svgid != oldcred->cr_gid) { + newcred = crdup(oldcred); + change_svuid(newcred, newcred->cr_uid); + change_svgid(newcred, newcred->cr_gid); + } + + } + + if (newcred != NULL) { + /* + * If the credential was updated, replace it with the + * new credential. + * + * XXX: should setsugid() be called here? + */ + struct ucred *oldcred; + + oldcred = p->p_ucred; + PROC_LOCK(p); + p->p_ucred = newcred; + PROC_UNLOCK(p); + crfree(oldcred); + } /* * Store the vp for use in procfs Index: kern/kern_exit.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_exit.c,v retrieving revision 1.126 diff -u -r1.126 kern_exit.c --- kern/kern_exit.c 2001/05/04 16:13:28 1.126 +++ kern/kern_exit.c 2001/05/13 03:24:07 @@ -514,7 +514,7 @@ /* * Decrement the count of procs running with this uid. */ - (void)chgproccnt(p->p_cred->p_uidinfo, -1, 0); + (void)chgproccnt(p->p_ucred->cr_ruidinfo, -1, 0); /* * Release reference to text vnode @@ -539,12 +539,8 @@ /* * Free up credentials. */ - if (--p->p_cred->p_refcnt == 0) { - crfree(p->p_ucred); - uifree(p->p_cred->p_uidinfo); - FREE(p->p_cred, M_SUBPROC); - p->p_cred = NULL; - } + crfree(p->p_ucred); + p->p_ucred = NULL; /* * Remove unused arguments Index: kern/kern_fork.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_fork.c,v retrieving revision 1.111 diff -u -r1.111 kern_fork.c --- kern/kern_fork.c 2001/05/07 18:07:29 1.111 +++ kern/kern_fork.c 2001/05/13 03:24:07 @@ -257,7 +257,7 @@ * exceed the limit. The variable nprocs is the current number of * processes, maxproc is the limit. */ - uid = p1->p_cred->p_ruid; + uid = p1->p_ucred->cr_ruid; if ((nprocs >= maxproc - 1 && uid != 0) || nprocs >= maxproc) { tablefull("proc"); return (EAGAIN); @@ -272,7 +272,7 @@ * Increment the count of procs running with this uid. Don't allow * a nonprivileged user to exceed their current limit. */ - ok = chgproccnt(p1->p_cred->p_uidinfo, 1, + ok = chgproccnt(p1->p_ucred->cr_ruidinfo, 1, (uid != 0) ? p1->p_rlimit[RLIMIT_NPROC].rlim_cur : 0); if (!ok) { /* @@ -408,15 +408,9 @@ * We start off holding one spinlock after fork: sched_lock. */ p2->p_spinlocks = 1; - PROC_UNLOCK(p2); - MALLOC(p2->p_cred, struct pcred *, sizeof(struct pcred), - M_SUBPROC, M_WAITOK); - PROC_LOCK(p2); PROC_LOCK(p1); - bcopy(p1->p_cred, p2->p_cred, sizeof(*p2->p_cred)); - p2->p_cred->p_refcnt = 1; crhold(p1->p_ucred); - uihold(p1->p_cred->p_uidinfo); + p2->p_ucred = p1->p_ucred; if (p2->p_args) p2->p_args->ar_ref++; Index: kern/kern_ktrace.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_ktrace.c,v retrieving revision 1.52 diff -u -r1.52 kern_ktrace.c --- kern/kern_ktrace.c 2001/05/01 08:12:56 1.52 +++ kern/kern_ktrace.c 2001/05/13 03:24:08 @@ -531,17 +531,17 @@ ktrcanset(callp, targetp) struct proc *callp, *targetp; { - register struct pcred *caller = callp->p_cred; - register struct pcred *target = targetp->p_cred; + struct ucred *callcr = callp->p_ucred; + struct ucred *targetcr = targetp->p_ucred; - if (prison_check(callp->p_ucred, targetp->p_ucred)) + if (prison_check(callcr, targetcr)) return (0); - if ((caller->pc_ucred->cr_uid == target->p_ruid && - target->p_ruid == target->p_svuid && - caller->p_rgid == target->p_rgid && /* XXX */ - target->p_rgid == target->p_svgid && + if ((callcr->cr_uid == targetcr->cr_ruid && + targetcr->cr_ruid == targetcr->cr_svuid && + callcr->cr_rgid == targetcr->cr_rgid && /* XXX */ + targetcr->cr_rgid == targetcr->cr_svgid && (targetp->p_traceflag & KTRFAC_ROOT) == 0) || - caller->pc_ucred->cr_uid == 0) + !suser_xxx(callcr, NULL, PRISON_ROOT)) return (1); return (0); Index: kern/kern_proc.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_proc.c,v retrieving revision 1.93 diff -u -r1.93 kern_proc.c --- kern/kern_proc.c 2001/05/01 08:12:57 1.93 +++ kern/kern_proc.c 2001/05/13 03:24:08 @@ -424,15 +424,15 @@ kp->ki_textvp = p->p_textvp; kp->ki_fd = p->p_fd; kp->ki_vmspace = p->p_vmspace; - if (p->p_cred) { - kp->ki_uid = p->p_cred->pc_ucred->cr_uid; - kp->ki_ruid = p->p_cred->p_ruid; - kp->ki_svuid = p->p_cred->p_svuid; - kp->ki_ngroups = p->p_cred->pc_ucred->cr_ngroups; - bcopy(p->p_cred->pc_ucred->cr_groups, kp->ki_groups, + if (p->p_ucred) { + kp->ki_uid = p->p_ucred->cr_uid; + kp->ki_ruid = p->p_ucred->cr_ruid; + kp->ki_svuid = p->p_ucred->cr_svuid; + kp->ki_ngroups = p->p_ucred->cr_ngroups; + bcopy(p->p_ucred->cr_groups, kp->ki_groups, NGROUPS * sizeof(gid_t)); - kp->ki_rgid = p->p_cred->p_rgid; - kp->ki_svgid = p->p_cred->p_svgid; + kp->ki_rgid = p->p_ucred->cr_rgid; + kp->ki_svgid = p->p_ucred->cr_svgid; } if (p->p_procsig) { kp->ki_sigignore = p->p_procsig->ps_sigignore; @@ -653,7 +653,7 @@ case KERN_PROC_RUID: if (p->p_ucred == NULL || - p->p_cred->p_ruid != (uid_t)name[0]) + p->p_ucred->cr_ruid != (uid_t)name[0]) continue; break; } Index: kern/kern_prot.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_prot.c,v retrieving revision 1.89 diff -u -r1.89 kern_prot.c --- kern/kern_prot.c 2001/05/01 08:12:57 1.89 +++ kern/kern_prot.c 2001/05/13 03:24:09 @@ -210,7 +210,7 @@ struct getuid_args *uap; { - p->p_retval[0] = p->p_cred->p_ruid; + p->p_retval[0] = p->p_ucred->cr_ruid; #if defined(COMPAT_43) || defined(COMPAT_SUNOS) p->p_retval[1] = p->p_ucred->cr_uid; #endif @@ -253,7 +253,7 @@ struct getgid_args *uap; { - p->p_retval[0] = p->p_cred->p_rgid; + p->p_retval[0] = p->p_ucred->cr_rgid; #if defined(COMPAT_43) || defined(COMPAT_SUNOS) p->p_retval[1] = p->p_ucred->cr_groups[0]; #endif @@ -293,18 +293,18 @@ struct proc *p; register struct getgroups_args *uap; { - register struct pcred *pc = p->p_cred; - register u_int ngrp; + struct ucred *cred = p->p_ucred; + u_int ngrp; int error; if ((ngrp = uap->gidsetsize) == 0) { - p->p_retval[0] = pc->pc_ucred->cr_ngroups; + p->p_retval[0] = cred->cr_ngroups; return (0); } - if (ngrp < pc->pc_ucred->cr_ngroups) + if (ngrp < cred->cr_ngroups) return (EINVAL); - ngrp = pc->pc_ucred->cr_ngroups; - if ((error = copyout((caddr_t)pc->pc_ucred->cr_groups, + ngrp = cred->cr_ngroups; + if ((error = copyout((caddr_t)cred->cr_groups, (caddr_t)uap->gidset, ngrp * sizeof(gid_t)))) return (error); p->p_retval[0] = ngrp; @@ -427,7 +427,7 @@ struct proc *p; struct setuid_args *uap; { - register struct pcred *pc = p->p_cred; + struct ucred *oldcred = p->p_ucred, *newcred; register uid_t uid; int error; @@ -449,16 +449,17 @@ * 3: Change euid last. (after tests in #2 for "appropriate privs") */ uid = uap->uid; - if (uid != pc->p_ruid && /* allow setuid(getuid()) */ + if (uid != oldcred->cr_ruid && /* allow setuid(getuid()) */ #ifdef _POSIX_SAVED_IDS - uid != pc->p_svuid && /* allow setuid(saved gid) */ + uid != oldcred->cr_svuid && /* allow setuid(saved gid) */ #endif #ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */ - uid != pc->pc_ucred->cr_uid && /* allow setuid(geteuid()) */ + uid != oldcred->cr_uid && /* allow setuid(geteuid()) */ #endif - (error = suser_xxx(0, p, PRISON_ROOT))) + (error = suser_xxx(oldcred, NULL, PRISON_ROOT))) return (error); + newcred = crdup(oldcred); #ifdef _POSIX_SAVED_IDS /* * Do we have "appropriate privileges" (are we root or uid == euid) @@ -466,16 +467,16 @@ */ if ( #ifdef POSIX_APPENDIX_B_4_2_2 /* Use the clause from B.4.2.2 */ - uid == pc->pc_ucred->cr_uid || + uid == oldcred->cr_uid || #endif - suser_xxx(0, p, PRISON_ROOT) == 0) /* we are using privs */ + suser_xxx(oldcred, NULL, PRISON_ROOT) == 0) /* we are using privs */ #endif { /* * Set the real uid and transfer proc count to new user. */ - if (uid != pc->p_ruid) { - change_ruid(p, uid); + if (uid != oldcred->cr_ruid) { + change_ruid(newcred, uid); setsugid(p); } /* @@ -485,8 +486,8 @@ * the security of seteuid() depends on it. B.4.2.2 says it * is important that we should do this. */ - if (pc->p_svuid != uid) { - pc->p_svuid = uid; + if (uid != oldcred->cr_svuid) { + change_svuid(newcred, uid); setsugid(p); } } @@ -495,10 +496,12 @@ * In all permitted cases, we are changing the euid. * Copy credentials so other references do not see our changes. */ - if (pc->pc_ucred->cr_uid != uid) { - change_euid(p, uid); + if (uid != oldcred->cr_uid) { + change_euid(newcred, uid); setsugid(p); } + p->p_ucred = newcred; + crfree(oldcred); return (0); } @@ -513,23 +516,31 @@ struct proc *p; struct seteuid_args *uap; { - register struct pcred *pc = p->p_cred; - register uid_t euid; + struct ucred *oldcred = p->p_ucred, *newcred; + uid_t euid; int error; euid = uap->euid; - if (euid != pc->p_ruid && /* allow seteuid(getuid()) */ - euid != pc->p_svuid && /* allow seteuid(saved uid) */ - (error = suser_xxx(0, p, PRISON_ROOT))) + /* + * The new effective uid must equal the current real or saved + * uid. Appropriate privilege may override this restriction. + */ + if (euid != oldcred->cr_ruid && /* allow seteuid(getuid()) */ + euid != oldcred->cr_svuid && /* allow seteuid(saved uid) */ + (error = suser_xxx(oldcred, NULL, PRISON_ROOT))) return (error); + /* * Everything's okay, do it. Copy credentials so other references do * not see our changes. */ - if (pc->pc_ucred->cr_uid != euid) { - change_euid(p, euid); + newcred = crdup(oldcred); + if (oldcred->cr_uid != euid) { + change_euid(newcred, euid); setsugid(p); } + p->p_ucred = newcred; + crfree(oldcred); return (0); } @@ -544,7 +555,7 @@ struct proc *p; struct setgid_args *uap; { - register struct pcred *pc = p->p_cred; + struct ucred *oldcred = p->p_ucred, *newcred; register gid_t gid; int error; @@ -560,16 +571,17 @@ * For notes on the logic here, see setuid() above. */ gid = uap->gid; - if (gid != pc->p_rgid && /* allow setgid(getgid()) */ + if (gid != oldcred->cr_rgid && /* allow setgid(getgid()) */ #ifdef _POSIX_SAVED_IDS - gid != pc->p_svgid && /* allow setgid(saved gid) */ + gid != oldcred->cr_svgid && /* allow setgid(saved gid) */ #endif #ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */ - gid != pc->pc_ucred->cr_groups[0] && /* allow setgid(getegid()) */ + gid != oldcred->cr_groups[0] && /* allow setgid(getegid()) */ #endif - (error = suser_xxx(0, p, PRISON_ROOT))) + (error = suser_xxx(oldcred, NULL, PRISON_ROOT))) return (error); + newcred = crdup(oldcred); #ifdef _POSIX_SAVED_IDS /* * Do we have "appropriate privileges" (are we root or gid == egid) @@ -577,16 +589,16 @@ */ if ( #ifdef POSIX_APPENDIX_B_4_2_2 /* use the clause from B.4.2.2 */ - gid == pc->pc_ucred->cr_groups[0] || + gid == oldcred->cr_groups[0] || #endif - suser_xxx(0, p, PRISON_ROOT) == 0) /* we are using privs */ + suser_xxx(oldcred, NULL, PRISON_ROOT) == 0) /* we are using privs */ #endif { /* * Set real gid */ - if (pc->p_rgid != gid) { - pc->p_rgid = gid; + if (oldcred->cr_rgid != gid) { + change_rgid(newcred, gid); setsugid(p); } /* @@ -596,8 +608,8 @@ * the security of setegid() depends on it. B.4.2.2 says it * is important that we should do this. */ - if (pc->p_svgid != gid) { - pc->p_svgid = gid; + if (oldcred->cr_svgid != gid) { + change_svgid(newcred, gid); setsugid(p); } } @@ -605,11 +617,12 @@ * In all cases permitted cases, we are changing the egid. * Copy credentials so other references do not see our changes. */ - if (pc->pc_ucred->cr_groups[0] != gid) { - pc->pc_ucred = crcopy(pc->pc_ucred); - pc->pc_ucred->cr_groups[0] = gid; + if (oldcred->cr_groups[0] != gid) { + change_egid(newcred, gid); setsugid(p); } + p->p_ucred = newcred; + crfree(oldcred); return (0); } @@ -624,20 +637,27 @@ struct proc *p; struct setegid_args *uap; { - register struct pcred *pc = p->p_cred; - register gid_t egid; + struct ucred *oldcred = p->p_ucred, *newcred; + gid_t egid; int error; egid = uap->egid; - if (egid != pc->p_rgid && /* allow setegid(getgid()) */ - egid != pc->p_svgid && /* allow setegid(saved gid) */ - (error = suser_xxx(0, p, PRISON_ROOT))) + /* + * The new effective gid must be equal to either the current real or + * saved gid. Appropriate privilege may override this restriction. + */ + if (egid != oldcred->cr_rgid && /* allow setegid(getgid()) */ + egid != oldcred->cr_svgid && /* allow setegid(saved gid) */ + (error = suser_xxx(oldcred, NULL, PRISON_ROOT))) return (error); - if (pc->pc_ucred->cr_groups[0] != egid) { - pc->pc_ucred = crcopy(pc->pc_ucred); - pc->pc_ucred->cr_groups[0] = egid; + + newcred = crdup(oldcred); + if (oldcred->cr_groups[0] != egid) { + change_egid(newcred, egid); setsugid(p); } + p->p_ucred = newcred; + crfree(oldcred); return (0); } @@ -653,11 +673,11 @@ struct proc *p; struct setgroups_args *uap; { - register struct pcred *pc = p->p_cred; - register u_int ngrp; + struct ucred *oldcred = p->p_ucred, *newcred; + u_int ngrp; int error; - if ((error = suser_xxx(0, p, PRISON_ROOT))) + if ((error = suser_xxx(oldcred, NULL, PRISON_ROOT))) return (error); ngrp = uap->gidsetsize; if (ngrp > NGROUPS) @@ -666,7 +686,7 @@ * XXX A little bit lazy here. We could test if anything has * changed before crcopy() and setting P_SUGID. */ - pc->pc_ucred = crcopy(pc->pc_ucred); + newcred = crdup(oldcred); if (ngrp < 1) { /* * setgroups(0, NULL) is a legitimate way of clearing the @@ -674,14 +694,18 @@ * have the egid in the groups[0]). We risk security holes * when running non-BSD software if we do not do the same. */ - pc->pc_ucred->cr_ngroups = 1; + newcred->cr_ngroups = 1; } else { if ((error = copyin((caddr_t)uap->gidset, - (caddr_t)pc->pc_ucred->cr_groups, ngrp * sizeof(gid_t)))) + (caddr_t)newcred->cr_groups, ngrp * sizeof(gid_t)))) { + crfree(newcred); return (error); - pc->pc_ucred->cr_ngroups = ngrp; + } + newcred->cr_ngroups = ngrp; } setsugid(p); + p->p_ucred = newcred; + crfree(oldcred); return (0); } @@ -697,31 +721,52 @@ register struct proc *p; struct setreuid_args *uap; { - register struct pcred *pc = p->p_cred; - register uid_t ruid, euid; + struct ucred *oldcred = p->p_ucred, *newcred; + uid_t ruid, euid; int error; ruid = uap->ruid; euid = uap->euid; - if (((ruid != (uid_t)-1 && ruid != pc->p_ruid && ruid != pc->p_svuid) || - (euid != (uid_t)-1 && euid != pc->pc_ucred->cr_uid && - euid != pc->p_ruid && euid != pc->p_svuid)) && - (error = suser_xxx(0, p, PRISON_ROOT)) != 0) + /* + * If an real uid update is requested, the requested real uid must + * be equal to the current real or saved uid. If an effective uid + * update is requested, the requested euid must be equal to the + * current effective uid, real uid, or saved uid. Appropriate + * privilege may override these restrictions. + */ + if (((ruid != (uid_t)-1 && ruid != oldcred->cr_ruid && + ruid != oldcred->cr_svuid) || + (euid != (uid_t)-1 && euid != oldcred->cr_uid && + euid != oldcred->cr_ruid && euid != oldcred->cr_svuid)) && + (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) return (error); - if (euid != (uid_t)-1 && pc->pc_ucred->cr_uid != euid) { - change_euid(p, euid); + newcred = crdup(oldcred); + if (euid != (uid_t)-1 && oldcred->cr_uid != euid) { + change_euid(newcred, euid); setsugid(p); } - if (ruid != (uid_t)-1 && pc->p_ruid != ruid) { - change_ruid(p, ruid); + if (ruid != (uid_t)-1 && oldcred->cr_ruid != ruid) { + change_ruid(newcred, ruid); setsugid(p); } - if ((ruid != (uid_t)-1 || pc->pc_ucred->cr_uid != pc->p_ruid) && - pc->p_svuid != pc->pc_ucred->cr_uid) { - pc->p_svuid = pc->pc_ucred->cr_uid; + /* + * XXX: What is this intended to accomplish? In which cases should + * it be looking at the old values, and in which, the new values? + * + * Note current behavior is: + * If the ruid update is requested (even if the ruid is not changed) + * or the euid is not equal to the value of the ruid, a difference + * in the svuid and the euid will result in the svuid being + * updated to the new value of the euid. + */ + if ((ruid != (uid_t)-1 || newcred->cr_uid != newcred->cr_ruid) && + newcred->cr_svuid != newcred->cr_uid) { + change_svuid(newcred, newcred->cr_uid); setsugid(p); } + p->p_ucred = newcred; + crfree(oldcred); return (0); } @@ -737,30 +782,49 @@ register struct proc *p; struct setregid_args *uap; { - register struct pcred *pc = p->p_cred; - register gid_t rgid, egid; + struct ucred *oldcred = p->p_ucred, *newcred; + gid_t rgid, egid; int error; rgid = uap->rgid; egid = uap->egid; - if (((rgid != (gid_t)-1 && rgid != pc->p_rgid && rgid != pc->p_svgid) || - (egid != (gid_t)-1 && egid != pc->pc_ucred->cr_groups[0] && - egid != pc->p_rgid && egid != pc->p_svgid)) && - (error = suser_xxx(0, p, PRISON_ROOT)) != 0) + /* + * If a real gid update is requested, the requested real gid must + * be equal to the current real or saved gid. If an effective gid + * update is requested, the requested effective gid must be equal + * to the current effective gid, the current real gid, or the + * current saved gid. Apropriate privilege may override this + * restriction. + */ + if (((rgid != (gid_t)-1 && rgid != oldcred->cr_rgid && + rgid != oldcred->cr_svgid) || + (egid != (gid_t)-1 && egid != oldcred->cr_groups[0] && + egid != oldcred->cr_rgid && egid != oldcred->cr_svgid)) && + (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) return (error); - if (egid != (gid_t)-1 && pc->pc_ucred->cr_groups[0] != egid) { - pc->pc_ucred = crcopy(pc->pc_ucred); - pc->pc_ucred->cr_groups[0] = egid; + newcred = crdup(oldcred); + if (egid != (gid_t)-1 && oldcred->cr_groups[0] != egid) { + change_egid(newcred, egid); setsugid(p); } - if (rgid != (gid_t)-1 && pc->p_rgid != rgid) { - pc->p_rgid = rgid; + if (rgid != (gid_t)-1 && oldcred->cr_rgid != rgid) { + change_rgid(newcred, rgid); setsugid(p); } - if ((rgid != (gid_t)-1 || pc->pc_ucred->cr_groups[0] != pc->p_rgid) && - pc->p_svgid != pc->pc_ucred->cr_groups[0]) { - pc->p_svgid = pc->pc_ucred->cr_groups[0]; + /* + * XXX: What is this intended to accomplish? In which cases should + * it be looking at the old values, and in which, the new values? + * + * Note current behavior is: + * If the rgid update is requested (even if the rgid is not changed) + * or the egid is not equal to the value of the rgid, a difference + * in the svgid and the egid will result in the svuid being + * updated to the new value of the euid. + */ + if ((rgid != (gid_t)-1 || newcred->cr_groups[0] != newcred->cr_rgid) && + newcred->cr_svgid != newcred->cr_groups[0]) { + change_svgid(newcred, newcred->cr_groups[0]); setsugid(p); } return (0); @@ -784,33 +848,40 @@ register struct proc *p; struct setresuid_args *uap; { - register struct pcred *pc = p->p_cred; - register uid_t ruid, euid, suid; + struct ucred *oldcred = p->p_ucred, *newcred; + uid_t ruid, euid, suid; int error; ruid = uap->ruid; euid = uap->euid; suid = uap->suid; - if (((ruid != (uid_t)-1 && ruid != pc->p_ruid && ruid != pc->p_svuid && - ruid != pc->pc_ucred->cr_uid) || - (euid != (uid_t)-1 && euid != pc->p_ruid && euid != pc->p_svuid && - euid != pc->pc_ucred->cr_uid) || - (suid != (uid_t)-1 && suid != pc->p_ruid && suid != pc->p_svuid && - suid != pc->pc_ucred->cr_uid)) && - (error = suser_xxx(0, p, PRISON_ROOT)) != 0) + if (((ruid != (uid_t)-1 && ruid != oldcred->cr_ruid && + ruid != oldcred->cr_svuid && + ruid != oldcred->cr_uid) || + (euid != (uid_t)-1 && euid != oldcred->cr_ruid && + euid != oldcred->cr_svuid && + euid != oldcred->cr_uid) || + (suid != (uid_t)-1 && suid != oldcred->cr_ruid && + suid != oldcred->cr_svuid && + suid != oldcred->cr_uid)) && + (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) return (error); - if (euid != (uid_t)-1 && pc->pc_ucred->cr_uid != euid) { - change_euid(p, euid); + + newcred = crdup(oldcred); + if (euid != (uid_t)-1 && oldcred->cr_uid != euid) { + change_euid(newcred, euid); setsugid(p); } - if (ruid != (uid_t)-1 && pc->p_ruid != ruid) { - change_ruid(p, ruid); + if (ruid != (uid_t)-1 && oldcred->cr_ruid != ruid) { + change_ruid(newcred, ruid); setsugid(p); } - if (suid != (uid_t)-1 && pc->p_svuid != suid) { - pc->p_svuid = suid; + if (suid != (uid_t)-1 && oldcred->cr_svuid != suid) { + change_svuid(newcred, suid); setsugid(p); } + p->p_ucred = newcred; + crfree(oldcred); return (0); } @@ -832,35 +903,40 @@ register struct proc *p; struct setresgid_args *uap; { - register struct pcred *pc = p->p_cred; - register gid_t rgid, egid, sgid; + struct ucred *oldcred = p->p_ucred, *newcred; + gid_t rgid, egid, sgid; int error; rgid = uap->rgid; egid = uap->egid; sgid = uap->sgid; - if (((rgid != (gid_t)-1 && rgid != pc->p_rgid && rgid != pc->p_svgid && - rgid != pc->pc_ucred->cr_groups[0]) || - (egid != (gid_t)-1 && egid != pc->p_rgid && egid != pc->p_svgid && - egid != pc->pc_ucred->cr_groups[0]) || - (sgid != (gid_t)-1 && sgid != pc->p_rgid && sgid != pc->p_svgid && - sgid != pc->pc_ucred->cr_groups[0])) && - (error = suser_xxx(0, p, PRISON_ROOT)) != 0) + if (((rgid != (gid_t)-1 && rgid != oldcred->cr_rgid && + rgid != oldcred->cr_svgid && + rgid != oldcred->cr_groups[0]) || + (egid != (gid_t)-1 && egid != oldcred->cr_rgid && + egid != oldcred->cr_svgid && + egid != oldcred->cr_groups[0]) || + (sgid != (gid_t)-1 && sgid != oldcred->cr_rgid && + sgid != oldcred->cr_svgid && + sgid != oldcred->cr_groups[0])) && + (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) return (error); - if (egid != (gid_t)-1 && pc->pc_ucred->cr_groups[0] != egid) { - pc->pc_ucred = crcopy(pc->pc_ucred); - pc->pc_ucred->cr_groups[0] = egid; + newcred = crdup(oldcred); + if (egid != (gid_t)-1 && oldcred->cr_groups[0] != egid) { + change_egid(newcred, egid); setsugid(p); } - if (rgid != (gid_t)-1 && pc->p_rgid != rgid) { - pc->p_rgid = rgid; + if (rgid != (gid_t)-1 && oldcred->cr_rgid != rgid) { + change_rgid(newcred, rgid); setsugid(p); } - if (sgid != (gid_t)-1 && pc->p_svgid != sgid) { - pc->p_svgid = sgid; + if (sgid != (gid_t)-1 && oldcred->cr_svgid != sgid) { + change_svgid(newcred, sgid); setsugid(p); } + p->p_ucred = newcred; + crfree(oldcred); return (0); } @@ -877,18 +953,18 @@ register struct proc *p; struct getresuid_args *uap; { - struct pcred *pc = p->p_cred; + struct ucred *cred = p->p_ucred; int error1 = 0, error2 = 0, error3 = 0; if (uap->ruid) - error1 = copyout((caddr_t)&pc->p_ruid, - (caddr_t)uap->ruid, sizeof(pc->p_ruid)); + error1 = copyout((caddr_t)&cred->cr_ruid, + (caddr_t)uap->ruid, sizeof(cred->cr_ruid)); if (uap->euid) - error2 = copyout((caddr_t)&pc->pc_ucred->cr_uid, - (caddr_t)uap->euid, sizeof(pc->pc_ucred->cr_uid)); + error2 = copyout((caddr_t)&cred->cr_uid, + (caddr_t)uap->euid, sizeof(cred->cr_uid)); if (uap->suid) - error3 = copyout((caddr_t)&pc->p_svuid, - (caddr_t)uap->suid, sizeof(pc->p_svuid)); + error3 = copyout((caddr_t)&cred->cr_svuid, + (caddr_t)uap->suid, sizeof(cred->cr_svuid)); return error1 ? error1 : (error2 ? error2 : error3); } @@ -905,18 +981,18 @@ register struct proc *p; struct getresgid_args *uap; { - struct pcred *pc = p->p_cred; + struct ucred *cred = p->p_ucred; int error1 = 0, error2 = 0, error3 = 0; if (uap->rgid) - error1 = copyout((caddr_t)&pc->p_rgid, - (caddr_t)uap->rgid, sizeof(pc->p_rgid)); + error1 = copyout((caddr_t)&cred->cr_rgid, + (caddr_t)uap->rgid, sizeof(cred->cr_rgid)); if (uap->egid) - error2 = copyout((caddr_t)&pc->pc_ucred->cr_groups[0], - (caddr_t)uap->egid, sizeof(pc->pc_ucred->cr_groups[0])); + error2 = copyout((caddr_t)&cred->cr_groups[0], + (caddr_t)uap->egid, sizeof(cred->cr_groups[0])); if (uap->sgid) - error3 = copyout((caddr_t)&pc->p_svgid, - (caddr_t)uap->sgid, sizeof(pc->p_svgid)); + error3 = copyout((caddr_t)&cred->cr_svgid, + (caddr_t)uap->sgid, sizeof(cred->cr_svgid)); return error1 ? error1 : (error2 ? error2 : error3); } @@ -972,7 +1048,7 @@ int groupmember(gid, cred) gid_t gid; - register struct ucred *cred; + struct ucred *cred; { register gid_t *gp; gid_t *egp; @@ -1113,10 +1189,10 @@ * Generally, the object credential's ruid or svuid must match the * subject credential's ruid or euid. */ - if (p1->p_cred->p_ruid != p2->p_cred->p_ruid && - p1->p_cred->p_ruid != p2->p_cred->p_svuid && - p1->p_ucred->cr_uid != p2->p_cred->p_ruid && - p1->p_ucred->cr_uid != p2->p_cred->p_svuid) { + if (p1->p_ucred->cr_ruid != p2->p_ucred->cr_ruid && + p1->p_ucred->cr_ruid != p2->p_ucred->cr_svuid && + p1->p_ucred->cr_uid != p2->p_ucred->cr_ruid && + p1->p_ucred->cr_uid != p2->p_ucred->cr_svuid) { /* Not permitted, try privilege. */ error = suser_xxx(NULL, p1, PRISON_ROOT); if (error) @@ -1140,9 +1216,9 @@ if ((error = prison_check(p1->p_ucred, p2->p_ucred))) return (error); - if (p1->p_cred->p_ruid == p2->p_cred->p_ruid) + if (p1->p_ucred->cr_ruid == p2->p_ucred->cr_ruid) return (0); - if (p1->p_ucred->cr_uid == p2->p_cred->p_ruid) + if (p1->p_ucred->cr_uid == p2->p_ucred->cr_ruid) return (0); if (!suser_xxx(0, p1, PRISON_ROOT)) { @@ -1178,9 +1254,9 @@ /* not owned by you, has done setuid (unless you're root) */ /* add a CAP_SYS_PTRACE here? */ - if (p1->p_cred->pc_ucred->cr_uid != p2->p_cred->p_ruid || - p1->p_cred->p_ruid != p2->p_cred->p_ruid || - p1->p_cred->p_svuid != p2->p_cred->p_ruid || + if (p1->p_ucred->cr_uid != p2->p_ucred->cr_ruid || + p1->p_ucred->cr_ruid != p2->p_ucred->cr_ruid || + p1->p_ucred->cr_svuid != p2->p_ucred->cr_ruid || p2->p_flag & P_SUGID) { if ((error = suser_xxx(0, p1, PRISON_ROOT))) return (error); @@ -1308,6 +1384,7 @@ *newcr = *cr; mtx_init(&newcr->cr_mtx, "ucred", MTX_DEF); uihold(newcr->cr_uidinfo); + uihold(newcr->cr_ruidinfo); if (jailed(newcr)) prison_hold(newcr->cr_prison); newcr->cr_ref = 1; @@ -1375,48 +1452,123 @@ } /* - * Helper function to change the effective uid of a process + * change_euid(): Change a process's effective uid. + * Arguments: struct ucred *newcred, uid_t euid + * Returns: none + * Locks: none + * Side effects: newcred->cr_uid and newcred->cr_uidinfo will be modified. + * References: newcred must be an exclusive credential reference for the + * duration of the call. + * Notes: none */ void -change_euid(p, euid) - struct proc *p; - uid_t euid; +change_euid(newcred, euid) + struct ucred *newcred; + uid_t euid; { - struct pcred *pc; - struct uidinfo *uip; - pc = p->p_cred; - /* - * crcopy is essentially a NOP if ucred has a reference count - * of 1, which is true if it has already been copied. - */ - pc->pc_ucred = crcopy(pc->pc_ucred); - uip = pc->pc_ucred->cr_uidinfo; - pc->pc_ucred->cr_uid = euid; - pc->pc_ucred->cr_uidinfo = uifind(euid); - uifree(uip); + newcred->cr_uid = euid; + uifree(newcred->cr_uidinfo); + newcred->cr_uidinfo = uifind(euid); } /* - * Helper function to change the real uid of a process - * - * The per-uid process count for this process is transfered from - * the old uid to the new uid. + * change_egid(): Change a process's effective gid. + * Arguments: struct ucred *newcred, gid_t egid + * Returns: none + * Locks: none + * Side effects: newcred->cr_gid will be modified. + * References: newcred must be an exclusive credential reference for the + * duration of the call. + * Notes: none */ void -change_ruid(p, ruid) - struct proc *p; - uid_t ruid; +change_egid(newcred, egid) + struct ucred *newcred; + gid_t egid; +{ + + newcred->cr_groups[0] = egid; +} + +/* + * change_ruid(): Change a process's real uid. + * Arguments: struct ucred *newcred, uid_t ruid + * Returns: none + * Locks: none + * Side effects: newcred->cr_ruid will be updated, newcred->cr_ruidinfo + * will be updated, and the old and new cr_ruidinfo proc + * counts will be updated. + * References: newcred must be an exclusive credential reference for the + * duration of the call. + * Notes: none + */ +void +change_ruid(newcred, ruid) + struct ucred *newcred; + uid_t ruid; +{ + + (void)chgproccnt(newcred->cr_ruidinfo, -1, 0); + newcred->cr_ruid = ruid; + uifree(newcred->cr_ruidinfo); + newcred->cr_ruidinfo = uifind(ruid); + (void)chgproccnt(newcred->cr_ruidinfo, 1, 0); +} + +/* + * change_rgid(): Change a process's real gid. + * Arguments: struct ucred *newcred, gid_t rgid + * Returns: none + * Locks: none + * Side effects: newcred->cr_rgid will be updated. + * References: newcred must be an exclusive credential reference for the + * duration of the call. + * Notes: none + */ +void +change_rgid(newcred, rgid) + struct ucred *newcred; + gid_t rgid; +{ + + newcred->cr_rgid = rgid; +} + +/* + * change_svuid(): Change a process's saved uid. + * Arguments: struct ucred *newcred, uid_t svuid + * Returns: none + * Locks: none + * Side effects: newcred->cr_svuid will be updated. + * References: newcred must be an exclusive credential reference for the + * duration of the call. + * Notes: none + */ +void +change_svuid(newcred, svuid) + struct ucred *newcred; + uid_t svuid; +{ + + newcred->cr_svuid = svuid; +} + +/* + * change_svgid(): Change a process's saved gid. + * Arguments: struct ucred *newcred, gid_t svgid + * Returns: none + * Locks: none + * Side effects: newcred->cr_svgid will be updated. + * References: newcred must be an exclusive credential reference for the + * duration of the call. + * Notes: none + */ +void +change_svgid(newcred, svgid) + struct ucred *newcred; + gid_t svgid; { - struct pcred *pc; - struct uidinfo *uip; - pc = p->p_cred; - (void)chgproccnt(pc->p_uidinfo, -1, 0); - uip = pc->p_uidinfo; - /* It is assumed that pcred is not shared between processes */ - pc->p_ruid = ruid; - pc->p_uidinfo = uifind(ruid); - (void)chgproccnt(pc->p_uidinfo, 1, 0); - uifree(uip); + newcred->cr_svgid = svgid; } Index: kern/kern_sig.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_sig.c,v retrieving revision 1.118 diff -u -r1.118 kern_sig.c --- kern/kern_sig.c 2001/05/07 18:07:29 1.118 +++ kern/kern_sig.c 2001/05/13 03:24:11 @@ -98,14 +98,14 @@ "Log processes quitting on abnormal signals to syslog(3)"); /* - * Policy -- Can real uid ruid with ucred uc send a signal to process q? + * Policy -- Can ucred cr1 send SIGIO to process cr2? */ -#define CANSIGIO(ruid, uc, q) \ - ((uc)->cr_uid == 0 || \ - (ruid) == (q)->p_cred->p_ruid || \ - (uc)->cr_uid == (q)->p_cred->p_ruid || \ - (ruid) == (q)->p_ucred->cr_uid || \ - (uc)->cr_uid == (q)->p_ucred->cr_uid) +#define CANSIGIO(cr1, cr2) \ + ((cr1)->cr_uid == 0 || \ + (cr2)->cr_ruid == (cr2)->cr_ruid || \ + (cr2)->cr_uid == (cr2)->cr_ruid || \ + (cr2)->cr_ruid == (cr2)->cr_uid || \ + (cr2)->cr_uid == (cr2)->cr_uid) int sugid_coredump; SYSCTL_INT(_kern, OID_AUTO, sugid_coredump, CTLFLAG_RW, @@ -1610,8 +1610,8 @@ { CTR3(KTR_PROC, "killproc: proc %p (pid %d, %s)", p, p->p_pid, p->p_comm); - log(LOG_ERR, "pid %d (%s), uid %d, was killed: %s\n", p->p_pid, p->p_comm, - p->p_cred && p->p_ucred ? p->p_ucred->cr_uid : -1, why); + log(LOG_ERR, "pid %d (%s), uid %d, was killed: %s\n", p->p_pid, + p->p_comm, p->p_ucred ? p->p_ucred->cr_uid : -1, why); PROC_LOCK(p); psignal(p, SIGKILL); PROC_UNLOCK(p); @@ -1650,7 +1650,7 @@ log(LOG_INFO, "pid %d (%s), uid %d: exited on signal %d%s\n", p->p_pid, p->p_comm, - p->p_cred && p->p_ucred ? p->p_ucred->cr_uid : -1, + p->p_ucred ? p->p_ucred->cr_uid : -1, sig &~ WCOREFLAG, sig & WCOREFLAG ? " (core dumped)" : ""); } else { @@ -1870,8 +1870,7 @@ if (sigio->sio_pgid > 0) { PROC_LOCK(sigio->sio_proc); - if (CANSIGIO(sigio->sio_ruid, sigio->sio_ucred, - sigio->sio_proc)) + if (CANSIGIO(sigio->sio_ucred, sigio->sio_proc->p_ucred)) psignal(sigio->sio_proc, sig); PROC_UNLOCK(sigio->sio_proc); } else if (sigio->sio_pgid < 0) { @@ -1879,7 +1878,7 @@ LIST_FOREACH(p, &sigio->sio_pgrp->pg_members, p_pglist) { PROC_LOCK(p); - if (CANSIGIO(sigio->sio_ruid, sigio->sio_ucred, p) && + if (CANSIGIO(sigio->sio_ucred, p->p_ucred) && (checkctty == 0 || (p->p_flag & P_CONTROLT))) psignal(p, sig); PROC_UNLOCK(p); Index: kern/uipc_usrreq.c =================================================================== RCS file: /home/ncvs/src/sys/kern/uipc_usrreq.c,v retrieving revision 1.65 diff -u -r1.65 uipc_usrreq.c --- kern/uipc_usrreq.c 2001/05/01 08:12:59 1.65 +++ kern/uipc_usrreq.c 2001/05/13 03:24:12 @@ -988,8 +988,8 @@ if (cm->cmsg_type == SCM_CREDS) { cmcred = (struct cmsgcred *)(cm + 1); cmcred->cmcred_pid = p->p_pid; - cmcred->cmcred_uid = p->p_cred->p_ruid; - cmcred->cmcred_gid = p->p_cred->p_rgid; + cmcred->cmcred_uid = p->p_ucred->cr_ruid; + cmcred->cmcred_gid = p->p_ucred->cr_rgid; cmcred->cmcred_euid = p->p_ucred->cr_uid; cmcred->cmcred_ngroups = MIN(p->p_ucred->cr_ngroups, CMGROUP_MAX); Index: kern/vfs_syscalls.c =================================================================== RCS file: /home/ncvs/src/sys/kern/vfs_syscalls.c,v retrieving revision 1.189 diff -u -r1.189 vfs_syscalls.c --- kern/vfs_syscalls.c 2001/04/29 02:44:49 1.189 +++ kern/vfs_syscalls.c 2001/05/13 03:24:14 @@ -1711,8 +1711,8 @@ * rather than to modify the potentially shared process structure. */ tmpcred = crdup(cred); - tmpcred->cr_uid = p->p_cred->p_ruid; - tmpcred->cr_groups[0] = p->p_cred->p_rgid; + tmpcred->cr_uid = cred->cr_ruid; + tmpcred->cr_groups[0] = cred->cr_rgid; p->p_ucred = tmpcred; NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, SCARG(uap, path), p); @@ -3799,7 +3799,7 @@ } cnt = auio.uio_resid; error = VOP_SETEXTATTR(vp, attrnamespace, attrname, &auio, - p->p_cred->pc_ucred, p); + p->p_ucred, p); cnt -= auio.uio_resid; p->p_retval[0] = cnt; done: @@ -3912,7 +3912,7 @@ } cnt = auio.uio_resid; error = VOP_GETEXTATTR(vp, attrnamespace, attrname, &auio, - p->p_cred->pc_ucred, p); + p->p_ucred, p); cnt -= auio.uio_resid; p->p_retval[0] = cnt; done: @@ -3995,7 +3995,7 @@ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); error = VOP_SETEXTATTR(vp, attrnamespace, attrname, NULL, - p->p_cred->pc_ucred, p); + p->p_ucred, p); VOP_UNLOCK(vp, 0, p); vn_finished_write(mp); Index: miscfs/procfs/procfs_status.c =================================================================== RCS file: /home/ncvs/src/sys/miscfs/procfs/procfs_status.c,v retrieving revision 1.29 diff -u -r1.29 procfs_status.c --- miscfs/procfs/procfs_status.c 2001/05/01 08:13:09 1.29 +++ miscfs/procfs/procfs_status.c 2001/05/13 03:24:15 @@ -153,11 +153,11 @@ ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, " %lu %lu %lu", (u_long)cr->cr_uid, - (u_long)p->p_cred->p_ruid, - (u_long)p->p_cred->p_rgid); + (u_long)cr->cr_ruid, + (u_long)cr->cr_rgid); DOCHECK(); - /* egid (p->p_cred->p_svgid) is equal to cr_ngroups[0] + /* egid (cr->cr_svgid) is equal to cr_ngroups[0] see also getegid(2) in /sys/kern/kern_prot.c */ for (i = 0; i < cr->cr_ngroups; i++) { Index: miscfs/procfs/procfs_vnops.c =================================================================== RCS file: /home/ncvs/src/sys/miscfs/procfs/procfs_vnops.c,v retrieving revision 1.95 diff -u -r1.95 procfs_vnops.c --- miscfs/procfs/procfs_vnops.c 2001/05/01 08:13:09 1.95 +++ miscfs/procfs/procfs_vnops.c 2001/05/13 03:24:22 @@ -404,7 +404,7 @@ procp = PFIND(pfs->pfs_pid); if (procp == NULL) return (ENOENT); - if (procp->p_cred == NULL || procp->p_ucred == NULL) { + if (procp->p_ucred == NULL) { PROC_UNLOCK(procp); return (ENOENT); } @@ -942,8 +942,7 @@ */ case Pfile: procp = PFIND(pfs->pfs_pid); - if (procp == NULL || procp->p_cred == NULL || - procp->p_ucred == NULL) { + if (procp == NULL || procp->p_ucred == NULL) { if (procp != NULL) PROC_UNLOCK(procp); printf("procfs_readlink: pid %d disappeared\n", Index: nfs/nfs_lock.c =================================================================== RCS file: /home/ncvs/src/sys/nfs/nfs_lock.c,v retrieving revision 1.4 diff -u -r1.4 nfs_lock.c --- nfs/nfs_lock.c 2001/05/01 08:13:14 1.4 +++ nfs/nfs_lock.c 2001/05/13 03:24:34 @@ -236,9 +236,11 @@ /* Let root, or someone who once was root (lockd generally * switches to the daemon uid once it is done setting up) make - * this call + * this call. + * + * XXX */ - if ((error = suser(p)) != 0 && p->p_cred->p_svuid != 0) + if ((error = suser(p)) != 0 && p->p_ucred->cr_svuid != 0) return (error); /* the version should match, or we're out of sync */ Index: posix4/p1003_1b.c =================================================================== RCS file: /home/ncvs/src/sys/posix4/p1003_1b.c,v retrieving revision 1.9 diff -u -r1.9 p1003_1b.c --- posix4/p1003_1b.c 2001/05/06 16:15:42 1.9 +++ posix4/p1003_1b.c 2001/05/13 03:24:35 @@ -68,16 +68,17 @@ /* * This is stolen from CANSIGNAL in kern_sig: * - * Can process p, with pcred pc, do "write flavor" operations to process q? + * Can process with credential cr1 do "write flavor" operations to credential + * cr2. This check needs to use generalized checks. */ -#define CAN_AFFECT(p, q) \ - (!suser_xxx(NULL, p, PRISON_ROOT) || \ - (p)->p_cred->pc_ruid == (q)->p_cred->p_ruid || \ - (p)->p_ucred->cr_uid == (q)->p_cred->p_ruid || \ - (p)->p_cred->pc_ruid == (q)->p_ucred->cr_uid || \ - (p)->p_ucred->cr_uid == (q)->p_ucred->cr_uid) +#define CAN_AFFECT(cr1, cr2) \ + (!suser_xxx(cr1, NULL, PRISON_ROOT) || \ + (c1)->cr_ruid == (cr2)->cr_ruid || \ + (c1)->cr_uid == (cr2)->cr_ruid || \ + (c1)->cr_ruid == (cr2)->cr_uid || \ + (c1)->cr_uid == (cr2)->cr_uid) #else -#define CAN_AFFECT(p, q) (!suser_xxx(NULL, p, PRISON_ROOT)) +#define CAN_AFFECT(cr1, cr2) (!suser_xxx(cr1, NULL, PRISON_ROOT)) #endif /* @@ -99,7 +100,7 @@ { /* Enforce permission policy. */ - if (CAN_AFFECT(p, other_proc)) + if (CAN_AFFECT(p->p_ucred, other_proc->p_ucred)) *pp = other_proc; else ret = EPERM; Index: sys/filedesc.h =================================================================== RCS file: /home/ncvs/src/sys/sys/filedesc.h,v retrieving revision 1.26 diff -u -r1.26 filedesc.h --- sys/filedesc.h 2000/11/18 21:01:04 1.26 +++ sys/filedesc.h 2001/05/13 03:24:35 @@ -117,7 +117,6 @@ struct sigio **sio_myref; /* location of the pointer that holds * the reference to this structure */ struct ucred *sio_ucred; /* current credentials */ - uid_t sio_ruid; /* real user id */ pid_t sio_pgid; /* pgid for signals */ }; #define sio_proc sio_u.siu_proc Index: sys/proc.h =================================================================== RCS file: /home/ncvs/src/sys/sys/proc.h,v retrieving revision 1.161 diff -u -r1.161 proc.h --- sys/proc.h 2001/04/27 19:28:25 1.161 +++ sys/proc.h 2001/05/13 03:24:35 @@ -156,7 +156,7 @@ LIST_ENTRY(proc) p_list; /* (d) List of all processes. */ /* substructures: */ - struct pcred *p_cred; /* (c + k) Process owner's identity. */ + struct ucred *p_ucred; /* (c + k) Process owner's identity. */ struct filedesc *p_fd; /* (b) Ptr to open files structure. */ struct pstats *p_stats; /* (b) Accounting/statistics (CPU). */ struct plimit *p_limit; /* (m) Process limits. */ @@ -166,7 +166,6 @@ #define p_sigignore p_procsig->ps_sigignore #define p_sigcatch p_procsig->ps_sigcatch -#define p_ucred p_cred->pc_ucred #define p_rlimit p_limit->pl_rlimit int p_flag; /* (c) P_* flags. */ @@ -336,23 +335,6 @@ #define P_CAN_SEE 1 #define P_CAN_SCHED 3 #define P_CAN_DEBUG 4 - -/* - * MOVE TO ucred.h? - * - * Shareable process credentials (always resident). This includes a reference - * to the current user credentials as well as real and saved ids that may be - * used to change ids. - */ -struct pcred { - struct ucred *pc_ucred; /* Current credentials. */ - uid_t p_ruid; /* Real user id. */ - uid_t p_svuid; /* Saved effective user id. */ - gid_t p_rgid; /* Real group id. */ - gid_t p_svgid; /* Saved effective group id. */ - int p_refcnt; /* Number of references. */ - struct uidinfo *p_uidinfo; /* Per uid resource consumption. */ -}; #ifdef _KERNEL Index: sys/ucred.h =================================================================== RCS file: /home/ncvs/src/sys/sys/ucred.h,v retrieving revision 1.23 diff -u -r1.23 ucred.h --- sys/ucred.h 2001/05/01 08:13:18 1.23 +++ sys/ucred.h 2001/05/13 03:24:35 @@ -50,9 +50,14 @@ struct ucred { u_int cr_ref; /* reference count */ uid_t cr_uid; /* effective user id */ + uid_t cr_ruid; /* real user id */ + uid_t cr_svuid; /* saved user id */ short cr_ngroups; /* number of groups */ gid_t cr_groups[NGROUPS]; /* groups */ - struct uidinfo *cr_uidinfo; /* per uid resource consumption */ + gid_t cr_rgid; /* real group id */ + gid_t cr_svgid; /* saved user id */ + struct uidinfo *cr_uidinfo; /* per euid resource consumption */ + struct uidinfo *cr_ruidinfo; /* per ruid resource consumption */ struct prison *cr_prison; /* jail(4) */ struct mtx cr_mtx; /* protect refcount */ }; @@ -77,8 +82,12 @@ struct proc; -void change_euid __P((struct proc *p, uid_t euid)); -void change_ruid __P((struct proc *p, uid_t ruid)); +void change_euid __P((struct ucred *newcred, uid_t euid)); +void change_egid __P((struct ucred *newcred, gid_t egid)); +void change_ruid __P((struct ucred *newcred, uid_t ruid)); +void change_rgid __P((struct ucred *newcred, uid_t rgid)); +void change_svuid __P((struct ucred *newcred, uid_t svuid)); +void change_svgid __P((struct ucred *newcred, gid_t svgid)); struct ucred *crcopy __P((struct ucred *cr)); struct ucred *crdup __P((struct ucred *cr)); void crfree __P((struct ucred *cr)); Index: ufs/ufs/ufs_extattr.c =================================================================== RCS file: /home/ncvs/src/sys/ufs/ufs/ufs_extattr.c,v retrieving revision 1.31 diff -u -r1.31 ufs_extattr.c --- ufs/ufs/ufs_extattr.c 2001/04/29 02:45:28 1.31 +++ ufs/ufs/ufs_extattr.c 2001/05/13 03:24:36 @@ -621,7 +621,7 @@ auio.uio_rw = UIO_READ; auio.uio_procp = (struct proc *) p; - VOP_LEASE(backing_vnode, p, p->p_cred->pc_ucred, LEASE_WRITE); + VOP_LEASE(backing_vnode, p, p->p_ucred, LEASE_WRITE); vn_lock(backing_vnode, LK_SHARED | LK_NOPAUSE | LK_RETRY, p); error = VOP_READ(backing_vnode, &auio, IO_NODELOCKED, ump->um_extattr.uepm_ucred); @@ -702,7 +702,7 @@ * Processes with privilege, but in jail, are not allowed to * configure extended attributes. */ - if ((error = suser_xxx(p->p_cred->pc_ucred, p, 0))) { + if ((error = suser_xxx(p->p_ucred, p, 0))) { if (filename_vp != NULL) VOP_UNLOCK(filename_vp, 0, p); return (error); Index: ufs/ufs/ufs_vfsops.c =================================================================== RCS file: /home/ncvs/src/sys/ufs/ufs/ufs_vfsops.c,v retrieving revision 1.24 diff -u -r1.24 ufs_vfsops.c --- ufs/ufs/ufs_vfsops.c 2001/05/01 08:13:19 1.24 +++ ufs/ufs/ufs_vfsops.c 2001/05/13 03:24:37 @@ -108,14 +108,14 @@ int cmd, type, error; if (uid == -1) - uid = p->p_cred->p_ruid; + uid = p->p_ucred->cr_ruid; cmd = cmds >> SUBCMDSHIFT; switch (cmd) { case Q_SYNC: break; case Q_GETQUOTA: - if (uid == p->p_cred->p_ruid) + if (uid == p->p_ucred->cr_ruid) break; /* fall through */ default: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message