From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by finch.gentoo.org (Postfix) with ESMTPS id 54AFC138334 for ; Sat, 9 Jun 2018 07:18:43 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 1E04EE08BB; Sat, 9 Jun 2018 07:18:42 +0000 (UTC) Received: from smtp.gentoo.org (dev.gentoo.org [IPv6:2001:470:ea4a:1:5054:ff:fec7:86e4]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id C0867E08BB for ; Sat, 9 Jun 2018 07:18:41 +0000 (UTC) Received: from oystercatcher.gentoo.org (oystercatcher.gentoo.org [148.251.78.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id 7DE14335CA6 for ; Sat, 9 Jun 2018 07:18:39 +0000 (UTC) Received: from localhost.localdomain (localhost [IPv6:::1]) by oystercatcher.gentoo.org (Postfix) with ESMTP id 1E6303D for ; Sat, 9 Jun 2018 07:18:37 +0000 (UTC) From: "Andreas Sturmlechner" To: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: 8bit Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "Andreas Sturmlechner" Message-ID: <1528528697.aff1af8e4bca8bdc6b3dd078b3bd4e9ed0ad6e73.asturm@gentoo> Subject: [gentoo-commits] repo/gentoo:master commit in: kde-frameworks/ktexteditor/files/, kde-frameworks/ktexteditor/ X-VCS-Repository: repo/gentoo X-VCS-Files: kde-frameworks/ktexteditor/files/ktexteditor-5.46.0-CVE-2018-10361.patch kde-frameworks/ktexteditor/ktexteditor-5.46.0-r1.ebuild X-VCS-Directories: kde-frameworks/ktexteditor/ kde-frameworks/ktexteditor/files/ X-VCS-Committer: asturm X-VCS-Committer-Name: Andreas Sturmlechner X-VCS-Revision: aff1af8e4bca8bdc6b3dd078b3bd4e9ed0ad6e73 X-VCS-Branch: master Date: Sat, 9 Jun 2018 07:18:37 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org X-Archives-Salt: 4431148e-da25-4400-b66b-8cba457a324f X-Archives-Hash: b0ff39e5a0e089eb1e6ab722f078e5f9 commit: aff1af8e4bca8bdc6b3dd078b3bd4e9ed0ad6e73 Author: Andreas Sturmlechner gentoo org> AuthorDate: Sat Jun 9 07:18:17 2018 +0000 Commit: Andreas Sturmlechner gentoo org> CommitDate: Sat Jun 9 07:18:17 2018 +0000 URL: https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=aff1af8e kde-frameworks/ktexteditor: Fix CVE-2018-10361 Package-Manager: Portage-2.3.40, Repoman-2.3.9 .../files/ktexteditor-5.46.0-CVE-2018-10361.patch | 187 +++++++++++++++++++++ .../ktexteditor/ktexteditor-5.46.0-r1.ebuild | 58 +++++++ 2 files changed, 245 insertions(+) diff --git a/kde-frameworks/ktexteditor/files/ktexteditor-5.46.0-CVE-2018-10361.patch b/kde-frameworks/ktexteditor/files/ktexteditor-5.46.0-CVE-2018-10361.patch new file mode 100644 index 00000000000..d3b9b5d480a --- /dev/null +++ b/kde-frameworks/ktexteditor/files/ktexteditor-5.46.0-CVE-2018-10361.patch @@ -0,0 +1,187 @@ +From c81af5aa1d4f6e0f8c44b2e85ca007ba2a1e4590 Mon Sep 17 00:00:00 2001 +From: Christoph Cullmann +Date: Thu, 7 Jun 2018 16:12:25 +0200 +Subject: CVE-2018-10361: privilege escalation + +improve handling of temporary file to avoid possible race-condition + +Differential Revision: https://phabricator.kde.org/D12513 +--- + src/buffer/katesecuretextbuffer.cpp | 99 +++++++++++++++++-------------------- + src/buffer/katesecuretextbuffer_p.h | 4 -- + 2 files changed, 46 insertions(+), 57 deletions(-) + +diff --git a/src/buffer/katesecuretextbuffer.cpp b/src/buffer/katesecuretextbuffer.cpp +index 0647bee..c014608 100644 +--- a/src/buffer/katesecuretextbuffer.cpp ++++ b/src/buffer/katesecuretextbuffer.cpp +@@ -53,39 +53,37 @@ ActionReply SecureTextBuffer::savefile(const QVariantMap &args) + bool SecureTextBuffer::saveFileInternal(const QString &sourceFile, const QString &targetFile, + const QByteArray &checksum, const uint ownerId, const uint groupId) + { +- QFileInfo targetFileInfo(targetFile); +- if (!QDir::setCurrent(targetFileInfo.dir().path())) { ++ /** ++ * open source file for reading ++ * if not possible, signal error ++ */ ++ QFile readFile(sourceFile); ++ if (!readFile.open(QIODevice::ReadOnly)) { + return false; + } + +- // get information about target file +- const QString targetFileName = targetFileInfo.fileName(); +- targetFileInfo.setFile(targetFileName); +- const bool newFile = !targetFileInfo.exists(); +- +- // open source and target file +- QFile readFile(sourceFile); +- //TODO use QSaveFile for saving contents and automatic atomic move on commit() when QSaveFile's security problem +- // (default temporary file permissions) is fixed +- // +- // We will first generate temporary filename and then use it relatively to prevent an attacker +- // to trick us to write contents to a different file by changing underlying directory. +- QTemporaryFile tempFile(targetFileName); ++ /** ++ * construct file info for target file ++ * we need to know things like path/exists/permissions ++ */ ++ const QFileInfo targetFileInfo(targetFile); ++ ++ /** ++ * create temporary file in current directory to be able to later do an atomic rename ++ * we need to pass full path, else QTemporaryFile uses the temporary directory ++ * if not possible, signal error, this catches e.g. a non-existing target directory, too ++ */ ++ QTemporaryFile tempFile(targetFileInfo.absolutePath() + QStringLiteral("/secureXXXXXX")); + if (!tempFile.open()) { + return false; + } +- tempFile.close(); +- QString tempFileName = QFileInfo(tempFile).fileName(); +- tempFile.setFileName(tempFileName); +- if (!readFile.open(QIODevice::ReadOnly) || !tempFile.open()) { +- return false; +- } +- const int tempFileDescriptor = tempFile.handle(); + +- // prepare checksum maker ++ /** ++ * copy contents + do checksumming ++ * if not possible, signal error ++ */ + QCryptographicHash cryptographicHash(checksumAlgorithm); +- +- // copy contents ++ const qint64 bufferLength = 4096; + char buffer[bufferLength]; + qint64 read = -1; + while ((read = readFile.read(buffer, bufferLength)) > 0) { +@@ -95,30 +93,43 @@ bool SecureTextBuffer::saveFileInternal(const QString &sourceFile, const QString + } + } + +- // check that copying was successful and checksum matched +- QByteArray localChecksum = cryptographicHash.result(); +- if (read == -1 || localChecksum != checksum || !tempFile.flush()) { ++ /** ++ * check that copying was successful and checksum matched ++ * we need to flush the file, as QTemporaryFile keeps the handle open ++ * and we later do things like renaming of the file! ++ * if not possible, signal error ++ */ ++ if ((read == -1) || (cryptographicHash.result() != checksum) || !tempFile.flush()) { + return false; + } + +- tempFile.close(); +- +- if (newFile) { ++ /** ++ * try to preserve the permissions ++ */ ++ if (!targetFileInfo.exists()) { + // ensure new file is readable by anyone + tempFile.setPermissions(tempFile.permissions() | QFile::Permission::ReadGroup | QFile::Permission::ReadOther); + } else { + // ensure the same file permissions + tempFile.setPermissions(targetFileInfo.permissions()); ++ + // ensure file has the same owner and group as before +- setOwner(tempFileDescriptor, ownerId, groupId); ++ setOwner(tempFile.handle(), ownerId, groupId); + } + +- // rename temporary file to the target file +- if (moveFile(tempFileName, targetFileName)) { ++ /** ++ * try to (atomic) rename temporary file to the target file ++ */ ++ if (moveFile(tempFile.fileName(), targetFileInfo.filePath())) { + // temporary file was renamed, there is nothing to remove anymore + tempFile.setAutoRemove(false); + return true; + } ++ ++ /** ++ * we failed ++ * QTemporaryFile will handle cleanup ++ */ + return false; + } + +@@ -141,28 +152,10 @@ bool SecureTextBuffer::moveFile(const QString &sourceFile, const QString &target + { + #if !defined(Q_OS_WIN) && !defined(Q_OS_ANDROID) + const int result = std::rename(QFile::encodeName(sourceFile).constData(), QFile::encodeName(targetFile).constData()); +- if (result == 0) { +- syncToDisk(QFile(targetFile).handle()); +- return true; +- } +- return false; ++ return (result == 0); + #else + // use racy fallback for windows + QFile::remove(targetFile); + return QFile::rename(sourceFile, targetFile); + #endif + } +- +-void SecureTextBuffer::syncToDisk(const int fd) +-{ +-#ifndef Q_OS_WIN +-#if HAVE_FDATASYNC +- fdatasync(fd); +-#else +- fsync(fd); +-#endif +-#else +- // no-op for windows +-#endif +-} +- +diff --git a/src/buffer/katesecuretextbuffer_p.h b/src/buffer/katesecuretextbuffer_p.h +index a38285b..e00721c 100644 +--- a/src/buffer/katesecuretextbuffer_p.h ++++ b/src/buffer/katesecuretextbuffer_p.h +@@ -56,8 +56,6 @@ public: + static const QCryptographicHash::Algorithm checksumAlgorithm = QCryptographicHash::Algorithm::Sha512; + + private: +- static const qint64 bufferLength = 4096; +- + /** + * Saves file contents using sets permissions. + */ +@@ -66,8 +64,6 @@ private: + + static bool moveFile(const QString &sourceFile, const QString &targetFile); + +- static void syncToDisk(const int fd); +- + public Q_SLOTS: + /** + * KAuth action to perform both prepare or move work based on given parameters. +-- +cgit v0.11.2 diff --git a/kde-frameworks/ktexteditor/ktexteditor-5.46.0-r1.ebuild b/kde-frameworks/ktexteditor/ktexteditor-5.46.0-r1.ebuild new file mode 100644 index 00000000000..6920f6f7c32 --- /dev/null +++ b/kde-frameworks/ktexteditor/ktexteditor-5.46.0-r1.ebuild @@ -0,0 +1,58 @@ +# Copyright 1999-2018 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +EAPI=6 + +VIRTUALX_REQUIRED="test" +inherit kde5 + +DESCRIPTION="Framework providing a full text editor component" +LICENSE="LGPL-2+" +KEYWORDS="~amd64 ~arm ~arm64 ~x86" +IUSE="editorconfig git" + +RDEPEND=" + $(add_frameworks_dep karchive) + $(add_frameworks_dep kauth) + $(add_frameworks_dep kcodecs) + $(add_frameworks_dep kcompletion) + $(add_frameworks_dep kconfig) + $(add_frameworks_dep kconfigwidgets) + $(add_frameworks_dep kcoreaddons) + $(add_frameworks_dep kguiaddons) + $(add_frameworks_dep ki18n) + $(add_frameworks_dep kiconthemes) + $(add_frameworks_dep kio) + $(add_frameworks_dep kitemviews) + $(add_frameworks_dep kjobwidgets) + $(add_frameworks_dep kparts) + $(add_frameworks_dep ktextwidgets) + $(add_frameworks_dep kwidgetsaddons) + $(add_frameworks_dep kxmlgui) + $(add_frameworks_dep sonnet) + $(add_frameworks_dep syntax-highlighting) + $(add_qt_dep qtdeclarative) + $(add_qt_dep qtgui) + $(add_qt_dep qtprintsupport) + $(add_qt_dep qtwidgets) + $(add_qt_dep qtxml) + editorconfig? ( app-text/editorconfig-core-c ) + git? ( dev-libs/libgit2:= ) +" +DEPEND="${RDEPEND} + $(add_qt_dep qtxmlpatterns) + test? ( $(add_frameworks_dep kservice) ) +" + +RESTRICT+=" test" + +PATCHES=( "${FILESDIR}/${P}-CVE-2018-10361.patch" ) + +src_configure() { + local mycmakeargs=( + $(cmake-utils_use_find_package editorconfig EditorConfig) + $(cmake-utils_use_find_package git LibGit2) + ) + + kde5_src_configure +}