Running 'vncpasswd foo' and entering a password that's, say, 12
characters long results in a buffer overflow. It is caught by glibc:
*** glibc detected *** vncpasswd: free(): invalid next size (fast): 0x09292110
***
======= Backtrace: =========
/lib/libc.so.6[0x49c384]
/lib/libc.so.6(__libc_free+0x77)[0x49c8bf]
/usr/lib/libstdc++.so.6(_ZdlPv+0x21)[0xf78279]
/usr/lib/libstdc++.so.6(_ZdaPv+0x1d)[0xf782c5]
vncpasswd[0x8048fe4]
vncpasswd[0x804919a]
vncpasswd(__gxx_personality_v0+0x355)[0x8048d0d]
/lib/libc.so.6(__libc_start_main+0xc6)[0x44dd46]
vncpasswd(__gxx_personality_v0+0x59)[0x8048a11]
======= Memory map: ========
0041b000-00435000 r-xp 00000000 03:02 8585218 /lib/ld-2.3.5.so
00435000-00436000 r-xp 00019000 03:02 8585218 /lib/ld-2.3.5.so
00436000-00437000 rwxp 0001a000 03:02 8585218 /lib/ld-2.3.5.so
00439000-0055d000 r-xp 00000000 03:02 8585234 /lib/libc-2.3.5.so
0055d000-0055f000 r-xp 00124000 03:02 8585234 /lib/libc-2.3.5.so
0055f000-00561000 rwxp 00126000 03:02 8585234 /lib/libc-2.3.5.so
00561000-00563000 rwxp 00561000 00:00 0
00565000-00587000 r-xp 00000000 03:02 8585269 /lib/libm-2.3.5.so
00587000-00588000 r-xp 00021000 03:02 8585269 /lib/libm-2.3.5.so
00588000-00589000 rwxp 00022000 03:02 8585269 /lib/libm-2.3.5.so
006c8000-006d1000 r-xp 00000000 03:02 8585233
/lib/libgcc_s-4.0.0-20050622.so.1
006d1000-006d2000 rwxp 00009000 03:02 8585233
/lib/libgcc_s-4.0.0-20050622.so.1
0077a000-0077b000 r-xp 0077a000 00:00 0
00ec6000-00fa3000 r-xp 00000000 03:02 10296197 /usr/lib/libstdc++.so.6.0.5
00fa3000-00fa8000 rwxp 000dd000 03:02 10296197 /usr/lib/libstdc++.so.6.0.5
00fa8000-00fad000 rwxp 00fa8000 00:00 0
08048000-0804b000 r-xp 00000000 03:02 10300081 /usr/bin/vncpasswd
0804b000-0804d000 rw-p 00002000 03:02 10300081 /usr/bin/vncpasswd
09292000-092b3000 rw-p 09292000 00:00 0 [heap]
b7e00000-b7e21000 rw-p b7e00000 00:00 0
b7e21000-b7f00000 ---p b7e21000 00:00 0
b7fac000-b7fae000 rw-p b7fac000 00:00 0
b7fba000-b7fbc000 rw-p b7fba000 00:00 0
bfda7000-bfdbc000 rw-p bfda7000 00:00 0 [stack]
Aborted
The reason is that the getpassword() function creates a PlainPasswd
like this:
PlainPasswd buf(256);
..but there is no such constructor. The way the compiler handles this
is to create an ObfuscatedPasswd first (which *does* take a length
parameter in its constructor), and make a PlainPasswd from that.
However, in doing so the length is truncated to 9:
PlainPasswd::PlainPasswd(const ObfuscatedPasswd& obfPwd) : CharArray(9) {
...
}
The fix is to declare the constructor that is intended to be used:
--- vnc-4_1_1-unixsrc/common/rfb/Password.cxx.vncpasswd 2005-06-27
15:08:30.000000000 +0100
+++ vnc-4_1_1-unixsrc/common/rfb/Password.cxx 2005-06-27 15:18:28.000000000
+0100
@@ -38,6 +38,9 @@
PlainPasswd::PlainPasswd(char* pwd) : CharArray(pwd) {
}
+PlainPasswd::PlainPasswd(int len) : CharArray(len) {
+}
+
PlainPasswd::PlainPasswd(const ObfuscatedPasswd& obfPwd) : CharArray(9) {
if (obfPwd.length < 8)
throw rdr::Exception("bad obfuscated password length");
--- vnc-4_1_1-unixsrc/common/rfb/Password.h.vncpasswd 2005-06-27
15:18:46.000000000 +0100
+++ vnc-4_1_1-unixsrc/common/rfb/Password.h 2005-06-27 15:18:56.000000000
+0100
@@ -28,6 +28,7 @@
public:
PlainPasswd();
PlainPasswd(char* pwd);
+ PlainPasswd(int l);
PlainPasswd(const ObfuscatedPasswd& obfPwd);
~PlainPasswd();
void replaceBuf(char* b);
Original bug report:
https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=160471
Tim.
*/
_______________________________________________
VNC-List mailing list
[email protected]
To remove yourself from the list visit:
http://www.realvnc.com/mailman/listinfo/vnc-list