diff --git a/pkgs/tools/misc/dtach/default.nix b/pkgs/tools/misc/dtach/default.nix index 7ceecc3690ab..000f6cd0f93f 100644 --- a/pkgs/tools/misc/dtach/default.nix +++ b/pkgs/tools/misc/dtach/default.nix @@ -8,6 +8,8 @@ stdenv.mkDerivation rec { sha256 = "16614ebddf8ab2811d3dc0e7f329c7de88929ac6a9632d4cb4aef7fe11b8f2a9"; }; + patches = [ ./fix-CVE-2012-3368.patch ]; + installPhase = '' mkdir -p $out/bin cp dtach $out/bin/dtach diff --git a/pkgs/tools/misc/dtach/fix-CVE-2012-3368.patch b/pkgs/tools/misc/dtach/fix-CVE-2012-3368.patch new file mode 100644 index 000000000000..9e556d9325fb --- /dev/null +++ b/pkgs/tools/misc/dtach/fix-CVE-2012-3368.patch @@ -0,0 +1,49 @@ +Fix error handling for read from stdin in attach.c + +attach.c did not correctly handle a read from stdin when read returned +an error. The code assigned the return value of read to pkt.len (an +unsigned char) before checking the value. This prevented the error check +from working correctly, since an unsigned integer can never be < 0. + +A packet with an invalid length was then sent to the master, which then +sent 255 bytes of garbage to the program. + +Fix the bug in attach.c and the unchecked packet length bug in master.c. + +Report and initial patch by Enrico Scholz. + +--- a/master.c 2012/07/01 21:26:10 1.14 ++++ b/master.c 2012/07/01 21:44:34 1.15 +@@ -351,7 +351,10 @@ + + /* Push out data to the program. */ + if (pkt.type == MSG_PUSH) +- write(the_pty.fd, pkt.u.buf, pkt.len); ++ { ++ if (pkt.len <= sizeof(pkt.u.buf)) ++ write(the_pty.fd, pkt.u.buf, pkt.len); ++ } + + /* Attach or detach from the program. */ + else if (pkt.type == MSG_ATTACH) +--- a/attach.c 2012/07/01 21:26:10 1.12 ++++ b/attach.c 2012/07/01 21:44:34 1.13 +@@ -237,12 +237,16 @@ + /* stdin activity */ + if (n > 0 && FD_ISSET(0, &readfds)) + { ++ ssize_t len; ++ + pkt.type = MSG_PUSH; + memset(pkt.u.buf, 0, sizeof(pkt.u.buf)); +- pkt.len = read(0, pkt.u.buf, sizeof(pkt.u.buf)); ++ len = read(0, pkt.u.buf, sizeof(pkt.u.buf)); + +- if (pkt.len <= 0) ++ if (len <= 0) + exit(1); ++ ++ pkt.len = len; + process_kbd(s, &pkt); + n--; + }