[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
system/2201: overflowable buffer in rpc.yppasswdd with -m option
- To: <gnats@openbsd.org>
- Subject: system/2201: overflowable buffer in rpc.yppasswdd with -m option
- From: Jose Nazario <jose@biocserver.BIOC.cwru.edu>
- Date: Mon, 26 Nov 2001 12:31:50 -0500 (EST)
- Resent-Date: Mon, 26 Nov 2001 10:30:03 -0700 (MST)
- Resent-From: gnats@cvs.openbsd.org (GNATS Management)
- Resent-Message-Id: <200111261730.fAQHU3ZQ029459@cvs.openbsd.org>
- Resent-Reply-To: gnats@cvs.openbsd.org,Received: "from openbsd.cs.colorado.edu (openbsd.cs.colorado.edu [128.138.192.83]) by cvs.openbsd.org (8.12.1/8.10.1) with ESMTP id fAQHLB5t005943 for" <gnats@cvs.openbsd.org>;,Mon@naughty.monkey.org, 26@naughty.monkey.org,Nov@naughty.monkey.org, 2001@naughty.monkey.org,10:21:12.-0700@cvs.openbsd.org (MST)
- Resent-To: bugs@cvs.openbsd.org
>Number: 2201
>Category: system
>Synopsis: overflowable buffer in rpc.yppasswdd with -m option
>Confidential: yes
>Severity: non-critical
>Priority: low
>Responsible: bugs
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Mon Nov 26 10:30:02 MST 2001
>Last-Modified:
>Originator: jose
>Organization:
net
>Release: 3.0-current
>Environment:
System : OpenBSD 3.0
Architecture: OpenBSD.i386
Machine : i386
>Description:
hi guys
small overflowable buffer in /usr/libexec/rpc.yppasswdd with the -m
argument. the code looks like it was never audited (ie CVS tags with
1997 dates). the suspect code fragment is here:
(CVS tag: $OpenBSD: rpc.yppasswdd.c,v 1.9 1997/08/19 07:00:51 niklas Exp $)
59 char make_arg[1024] = "make";
/* SNIP */
74 int
75 main(argc, argv)
76 int argc;
77 char *argv[];
78 {
79 SVCXPRT *transp;
80 int i = 1;
81
82 while (i < argc) {
83 if (argv[i][0] == '-') {
/* SNIP */
90 } else if (strcmp("-m", argv[i]) == 0) {
91 domake = 1;
92 while (i < argc) {
93 strcat(make_arg, " ");
94 strcat(make_arg, argv[i]);
95 i++;
96 }
/* SNIP */
106 }
we enter a while loop in like 92 with an arbitrary endpoint, argc. this
is then used to strcat() a constant space (line 93) and the value of
the argument in line 94. this is appended to the char make_arg, which at
line 59 was set to a fixed buffer size of 1024.
furthermore this argument is used later on in a system() call:
file: /usr/src/libexec/rpc.yppasswdd/yppasswdd_mkpw.c
$OpenBSD: yppasswdd_mkpw.c,v 1.21 2001/08/17 14:04:36 espie Exp $
230 if (fork() == 0) {
231 chdir("/var/yp");
232 (void)umask(022);
233 system(make_arg);
234 exit(0);
235 }
make_arg is never sanitized in this executable.
long story short: while this is overflowable and a tainted source of input
(make_arg), its not suid root nor is it remotly callable with the -m
option. this isn't a security concern, but it's a quality issue, worth
fixing.
>How-To-Repeat:
its trivial to overflow this leading to a segfault:
$ rpc.yppasswdd -m `perl -e 'print "A"x4000'`
Memory fault (core dumped)
here's a gdb of it really quick:
$ gdb /usr/src/libexec/rpc.yppasswdd/rpc.yppasswdd
GNU gdb 4.16.1
Copyright 1996 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-unknown-openbsd3.0"...
(gdb) set args -m `perl -e 'print "A"x4000'`
(gdb) run
Starting program: /usr/src/libexec/rpc.yppasswdd/rpc.yppasswdd -m `perl -e 'prin
t "A"x4000'`
Program received signal SIGSEGV, Segmentation fault.
0x40088819 in strcat ()
(gdb) bt
#0 0x40088819 in strcat ()
#1 0x4284 in make_arg ()
>Fix:
here is a patch for rpc.yppasswdd.c (stolen, in large measure, from
netbsd's patch to the code):
--- rpc.yppasswdd.c.orig Mon Nov 26 12:09:42 2001
+++ rpc.yppasswdd.c Mon Nov 26 12:12:48 2001
@@ -88,10 +88,19 @@
} else if (strcmp("-nopw", argv[i]) == 0) {
nopw = 1;
} else if (strcmp("-m", argv[i]) == 0) {
+ int len;
domake = 1;
+
+ len = strlen(make_arg);
while (i < argc) {
+ int arglen;
+
+ arglen = strlen(argv[i]);
+ if ((len + arglen) > (sizeof(make_arg)-2))
+ errx(EXIT_FAILURE, strerror(E2BIG));
strcat(make_arg, " ");
strcat(make_arg, argv[i]);
+ len += arglen;
i++;
}
} else if (strcmp("-d", argv[i]) == 0
____________________________
jose nazario jose@cwru.edu
PGP: 89 B0 81 DA 5B FD 7E 00 99 C3 B2 CD 48 A0 07 80
PGP key ID 0xFD37F4E5 (pgp.mit.edu)
>Audit-Trail:
>Unformatted:
X-sendbug-version: 3.97