From af4d0abc130d5219067b14b501e1de4823da8b84 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Mon, 5 Dec 2016 23:01:25 +0100 Subject: [PATCH] Correctly check getline() errors This fixes a security issue where signatures of the InRelease files could be circumvented in a man-in-the-middle attack, giving attackers the ability to serve any packages they want to a system, in turn giving them root access. Reported-By: Jann Horn --- apt-pkg/contrib/gpgv.cc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/apt-pkg/contrib/gpgv.cc b/apt-pkg/contrib/gpgv.cc index 856d56b..a5208d6 100644 --- a/apt-pkg/contrib/gpgv.cc +++ b/apt-pkg/contrib/gpgv.cc @@ -302,7 +302,8 @@ bool SplitClearSignedFile(std::string const &InFile, FileFd * const ContentFile, char *buf = NULL; size_t buf_size = 0; - while (getline(&buf, &buf_size, in) != -1) + // Must not exit this loop via a break, as we check errno afterwards + while ((errno = 0, getline(&buf, &buf_size, in) != -1)) { _strrstrip(buf); if (found_message_start == false) @@ -362,10 +363,17 @@ bool SplitClearSignedFile(std::string const &InFile, FileFd * const ContentFile, } // all the rest is whitespace, unsigned garbage or additional message blocks we ignore } + int errno_after_getline = errno; + fclose(in); if (buf != NULL) free(buf); + if (errno_after_getline != 0) { + errno = errno_after_getline; + return _error->Errno("getline()", InFile.c_str()); + } + if (found_signature == true) return _error->Error("Signature in file %s wasn't closed", InFile.c_str()); -- 2.10.2