Skip to content

fix(security): harden ops log export via fd-based transfer and symlin… - #485

Closed
GongHeng2017 wants to merge 1 commit into
linuxdeepin:masterfrom
GongHeng2017:202607072144-master-fix
Closed

fix(security): harden ops log export via fd-based transfer and symlin…#485
GongHeng2017 wants to merge 1 commit into
linuxdeepin:masterfrom
GongHeng2017:202607072144-master-fix

Conversation

@GongHeng2017

Copy link
Copy Markdown
Contributor

…k-safe collection

Refactor the exportOpsLog flow to eliminate path exposure and symlink traversal risks:

  • Change exportOpsLog DBus API from returning a /tmp path to accepting a caller-provided file descriptor and streaming the zipped logs back over it (bool return), so the backend no longer exposes /var/log paths to callers and the frontend no longer needs a separate cleanup call.
  • Move user-permission log collection (per-user ~/.cache logs) out of the root backend into Utils::exportUserPermission* helpers in the application, while the backend OpsLogExport now only collects root-owned /var/log logs.
  • Create the backend temp dir under /var/log instead of /tmp, and clean it up with a TOCTOU-safe, fd-relative recursive removal (openat/fstatat/unlinkat with O_NOFOLLOW) instead of path-based deletion.
  • Skip symlink sources during copy and switch directory copy from "cp -rf" to "cp -rP" to preserve rather than follow symlinks.
  • Drop setDirectoryPermissionsSafe chown loop, no longer needed since ownership is not handed back to a non-root caller.
  • Add ReadWritePaths=/var/log to the systemd unit so the backend can create its temp export dir under the ProtectSystem=strict tree.
  • Update the D-Bus introspection XML for the new exportOpsLog signature.

Log: fix issue
Bug: https://pms.uniontech.com/bug-view-368003.html

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @GongHeng2017, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: GongHeng2017

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
  • 检测到敏感词export变动
详情
    {
    "export": {
        "application/dbusproxy/dldbushandler.cpp": {
            "a": [
                "QString DLDBusHandler::exportOpsLog()",
                "    QDBusPendingReply<QString> reply = m_dbus->exportOpsLog();",
                "        qCWarning(logApp) << \"call dbus iterface 'exportOpsLog()' failed. error info:\" << reply.error().message();"
            ],
            "b": [
                "bool DLDBusHandler::exportOpsLog(const QString &zipFilePath)",
                "        qCritical() << \"exportOpsLog: failed to open zip file for writing:\" << zipFilePath",
                "        qCritical() << \"exportOpsLog: invalid file descriptor for:\" << zipFilePath;",
                "    QDBusPendingReply<bool> reply = m_dbus->exportOpsLog(dbusFd);",
                "        qCritical() << \"call dbus interface 'exportOpsLog' failed. error info:\" << reply.error().message();"
            ]
        },
        "application/dbusproxy/dldbushandler.h": {
            "a": [
                "    QString exportOpsLog();"
            ],
            "b": [
                "    bool exportOpsLog(const QString &zipFilePath);"
            ]
        },
        "application/dbusproxy/dldbusinterface.h": {
            "a": [
                "    inline QDBusPendingReply<QString> exportOpsLog()"
            ],
            "b": [
                "    inline QDBusPendingReply<bool> exportOpsLog(const QDBusUnixFileDescriptor &fd)"
            ]
        },
        "application/logallexportthread.cpp": {
            "a": [
                "        QString opsLogPath = DLDBusHandler::instance(this)->exportOpsLog();",
                "            Utils::exportSomeOpsLogs(opsLogPath, userHomePath);"
            ],
            "b": [
                "            emit exportFinsh(false);",
                "        bool opsOk = DLDBusHandler::instance(this)->exportOpsLog(opsZipPath);",
                "            qCCritical(logApp) << \"exportOpsLog failed or zip not produced\";",
                "            emit exportFinsh(false);",
                "        Utils::exportUserPermissionOpsLogs(tmpOpsDirPath, userHomePath);"
            ]
        },
        "application/opslogpaths.h": {
            "b": [
                "// \u524d\u7aef\uff08application/utils.cpp \u7684 exportUserPermissionOpsLogs \u7cfb\u5217\uff09\u4e0e",
                "// root \u670d\u52a1\uff08logViewerService/opslogexport.cpp \u7684 createOpsLogDirStruct\uff09\u5fc5\u987b"
            ]
        },
        "application/utils.cpp": {
            "a": [
                "void Utils::exportSomeOpsLogs(const QString &outDir, const QString &userHomeDir)"
            ],
            "b": [
                "void Utils::exportUserPermissionAppLogs(const QString &outDir, const QString &userHomeDir)",
                "void Utils::exportUserPermissionSystemLogs(const QString &outDir, const QString &userHomeDir)",
                "void Utils::exportUserPermissionKernelLogs(const QString &outDir)",
                "void Utils::exportUserPermissionDDELogs(const QString &outDir, const QString &userHomeDir)",
                "void Utils::exportUserPermissionOpsLogs(const QString &outDir, const QString &userHomeDir)",
                "    Utils::exportUserPermissionAppLogs(outDir, userHomeDir);",
                "    Utils::exportUserPermissionSystemLogs(outDir, userHomeDir);",
                "    Utils::exportUserPermissionKernelLogs(outDir);",
                "    Utils::exportUserPermissionDDELogs(outDir, userHomeDir);"
            ]
        },
        "application/utils.h": {
            "a": [
                "    static void exportSomeOpsLogs(const QString &outDir, const QString &userHomeDir);"
            ],
            "b": [
                "    static void exportUserPermissionAppLogs(const QString &outDir, const QString &userHomeDir);",
                "    static void exportUserPermissionSystemLogs(const QString &outDir, const QString &userHomeDir);",
                "    static void exportUserPermissionKernelLogs(const QString &outDir);",
                "    static void exportUserPermissionDDELogs(const QString &outDir, const QString &userHomeDir);",
                "    static void exportUserPermissionOpsLogs(const QString &outDir, const QString &userHomeDir);"
            ]
        },
        "logViewerService/assets/data/com.deepin.logviewer.xml": {
            "b": [
                "    <method name=\"exportOpsLog\">"
            ]
        },
        "logViewerService/assets/data/deepin-log-viewer-daemon.service": {
            "b": [
                "# exportOpsLog \u9700\u8981\u5728 /var/log \u4e0b\u521b\u5efa\u4e34\u65f6\u5bfc\u51fa\u76ee\u5f55\uff0c\u987b\u663e\u5f0f\u653e\u5f00\u5199\u6743\u9650"
            ]
        },
        "logViewerService/logviewerservice.cpp": {
            "a": [
                "QString LogViewerService::exportOpsLog()"
            ],
            "b": [
                "// \u57fa\u4e8e fd \u7684 TOCTOU \u5b89\u5168\u65b9\u5f0f\u5220\u9664 exportOpsLog \u4ea7\u751f\u7684 /var/log \u4e34\u65f6\u76ee\u5f55\uff08opsDir\uff09\u3002",
                "// \u7531 exportOpsLog \u5728\u5199\u5165 fd \u5b8c\u6210\u540e\u81ea\u52a8\u8c03\u7528\uff0c\u786e\u4fdd /var/log \u4e0b\u4e0d\u6b8b\u7559\u542b\u7cfb\u7edf\u65e5\u5fd7\u7684\u76ee\u5f55\u3002",
                "bool LogViewerService::exportOpsLog(const QDBusUnixFileDescriptor &fd)",
                "        qCWarning(logService) << \"exportOpsLog: invalid file descriptor from caller\";",
                "        qCWarning(logService) << \"exportOpsLog: failed to create temporary dir under /var/log:\" << tmpOpsDir.errorString();",
                "        qCWarning(logService) << \"exportOpsLog: failed to create log collect dir:\" << logCollectDir;",
                "        qCWarning(logService) << \"exportOpsLog: zip failed, exitCode:\" << zipProc.exitCode()",
                "            qCWarning(logService) << \"exportOpsLog: failed to open temp zip for reading:\" << tmpZipPath;",
                "                qCWarning(logService) << \"exportOpsLog: failed to open caller fd for writing\";",
                "                    qCWarning(logService) << \"exportOpsLog: write to caller fd failed\";",
                "        qCWarning(logService) << \"exportOpsLog: aborted, failed to write zip to caller fd\";",
                "    qCDebug(logService) << \"exportOpsLog: ops logs zipped and written to caller fd successfully\";"
            ]
        },
        "logViewerService/logviewerservice.h": {
            "a": [
                "    Q_SCRIPTABLE QString exportOpsLog();"
            ],
            "b": [
                "    Q_SCRIPTABLE bool exportOpsLog(const QDBusUnixFileDescriptor &fd);",
                "    // \u57fa\u4e8e fd \u7684 TOCTOU \u5b89\u5168\u65b9\u5f0f\u5220\u9664 exportOpsLog \u4ea7\u751f\u7684 /var/log \u4e34\u65f6\u76ee\u5f55\uff08opsDir\uff09\u3002",
                "    // \u7531 exportOpsLog \u5199\u5165 fd \u5b8c\u6210\u540e\u81ea\u52a8\u8c03\u7528\u56de\u6536\uff0c\u6210\u529f\u8fd4\u56de true\u3002"
            ]
        },
        "logViewerService/opslogexport.cpp": {
            "a": [
                "            qWarning() << \"Failed to chown export path:\" << path << \"error:\" << strerror(errno);"
            ]
        }
    }
}

@github-actions
github-actions Bot requested a review from liujianqiang-niu July 7, 2026 13:46
…k-safe collection

Refactor the exportOpsLog flow to eliminate path exposure and symlink
traversal risks:

- Change exportOpsLog DBus API from returning a /tmp path to accepting a
  caller-provided file descriptor and streaming the zipped logs back over
  it (bool return), so the backend no longer exposes /var/log paths to
  callers and the frontend no longer needs a separate cleanup call.
- Move user-permission log collection (per-user ~/.cache logs) out of the
  root backend into Utils::exportUserPermission* helpers in the
  application, while the backend OpsLogExport now only collects root-owned
  /var/log logs.
- Create the backend temp dir under /var/log instead of /tmp, and clean it
  up with a TOCTOU-safe, fd-relative recursive removal
  (openat/fstatat/unlinkat with O_NOFOLLOW) instead of path-based deletion.
- Skip symlink sources during copy and switch directory copy from
  "cp -rf" to "cp -rP" to preserve rather than follow symlinks.
- Drop setDirectoryPermissionsSafe chown loop, no longer needed since
  ownership is not handed back to a non-root caller.
- Add ReadWritePaths=/var/log to the systemd unit so the backend can
  create its temp export dir under the ProtectSystem=strict tree.
- Update the D-Bus introspection XML for the new exportOpsLog signature.

Log: fix issue
Bug: https://pms.uniontech.com/bug-view-368003.html
@GongHeng2017
GongHeng2017 force-pushed the 202607072144-master-fix branch from 3cd822b to 9b8846d Compare July 7, 2026 13:49
@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
  • 检测到敏感词export变动
详情
    {
    "export": {
        "application/dbusproxy/dldbushandler.cpp": {
            "a": [
                "QString DLDBusHandler::exportOpsLog()",
                "    QDBusPendingReply<QString> reply = m_dbus->exportOpsLog();",
                "        qCWarning(logApp) << \"call dbus iterface 'exportOpsLog()' failed. error info:\" << reply.error().message();"
            ],
            "b": [
                "bool DLDBusHandler::exportOpsLog(const QString &zipFilePath)",
                "        qCritical() << \"exportOpsLog: failed to open zip file for writing:\" << zipFilePath",
                "        qCritical() << \"exportOpsLog: invalid file descriptor for:\" << zipFilePath;",
                "    QDBusPendingReply<bool> reply = m_dbus->exportOpsLog(dbusFd);",
                "        qCritical() << \"call dbus interface 'exportOpsLog' failed. error info:\" << reply.error().message();"
            ]
        },
        "application/dbusproxy/dldbushandler.h": {
            "a": [
                "    QString exportOpsLog();"
            ],
            "b": [
                "    bool exportOpsLog(const QString &zipFilePath);"
            ]
        },
        "application/dbusproxy/dldbusinterface.h": {
            "a": [
                "    inline QDBusPendingReply<QString> exportOpsLog()"
            ],
            "b": [
                "    inline QDBusPendingReply<bool> exportOpsLog(const QDBusUnixFileDescriptor &fd)"
            ]
        },
        "application/logallexportthread.cpp": {
            "a": [
                "        QString opsLogPath = DLDBusHandler::instance(this)->exportOpsLog();",
                "            Utils::exportSomeOpsLogs(opsLogPath, userHomePath);"
            ],
            "b": [
                "            emit exportFinsh(false);",
                "        bool opsOk = DLDBusHandler::instance(this)->exportOpsLog(opsZipPath);",
                "            qCCritical(logApp) << \"exportOpsLog failed or zip not produced\";",
                "            emit exportFinsh(false);",
                "        Utils::exportUserPermissionOpsLogs(tmpOpsDirPath, userHomePath);"
            ]
        },
        "application/opslogpaths.h": {
            "b": [
                "// \u524d\u7aef\uff08application/utils.cpp \u7684 exportUserPermissionOpsLogs \u7cfb\u5217\uff09\u4e0e",
                "// root \u670d\u52a1\uff08logViewerService/opslogexport.cpp \u7684 createOpsLogDirStruct\uff09\u5fc5\u987b"
            ]
        },
        "application/utils.cpp": {
            "a": [
                "void Utils::exportSomeOpsLogs(const QString &outDir, const QString &userHomeDir)"
            ],
            "b": [
                "void Utils::exportUserPermissionAppLogs(const QString &outDir, const QString &userHomeDir)",
                "void Utils::exportUserPermissionSystemLogs(const QString &outDir, const QString &userHomeDir)",
                "void Utils::exportUserPermissionKernelLogs(const QString &outDir)",
                "void Utils::exportUserPermissionDDELogs(const QString &outDir, const QString &userHomeDir)",
                "void Utils::exportUserPermissionOpsLogs(const QString &outDir, const QString &userHomeDir)",
                "    Utils::exportUserPermissionAppLogs(outDir, userHomeDir);",
                "    Utils::exportUserPermissionSystemLogs(outDir, userHomeDir);",
                "    Utils::exportUserPermissionKernelLogs(outDir);",
                "    Utils::exportUserPermissionDDELogs(outDir, userHomeDir);"
            ]
        },
        "application/utils.h": {
            "a": [
                "    static void exportSomeOpsLogs(const QString &outDir, const QString &userHomeDir);"
            ],
            "b": [
                "    static void exportUserPermissionAppLogs(const QString &outDir, const QString &userHomeDir);",
                "    static void exportUserPermissionSystemLogs(const QString &outDir, const QString &userHomeDir);",
                "    static void exportUserPermissionKernelLogs(const QString &outDir);",
                "    static void exportUserPermissionDDELogs(const QString &outDir, const QString &userHomeDir);",
                "    static void exportUserPermissionOpsLogs(const QString &outDir, const QString &userHomeDir);"
            ]
        },
        "logViewerService/assets/data/com.deepin.logviewer.xml": {
            "b": [
                "    <method name=\"exportOpsLog\">"
            ]
        },
        "logViewerService/assets/data/deepin-log-viewer-daemon.service": {
            "b": [
                "# exportOpsLog \u9700\u8981\u5728 /var/log \u4e0b\u521b\u5efa\u4e34\u65f6\u5bfc\u51fa\u76ee\u5f55\uff0c\u987b\u663e\u5f0f\u653e\u5f00\u5199\u6743\u9650"
            ]
        },
        "logViewerService/logviewerservice.cpp": {
            "a": [
                "QString LogViewerService::exportOpsLog()"
            ],
            "b": [
                "// \u57fa\u4e8e fd \u7684 TOCTOU \u5b89\u5168\u65b9\u5f0f\u5220\u9664 exportOpsLog \u4ea7\u751f\u7684 /var/log \u4e34\u65f6\u76ee\u5f55\uff08opsDir\uff09\u3002",
                "// \u7531 exportOpsLog \u5728\u5199\u5165 fd \u5b8c\u6210\u540e\u81ea\u52a8\u8c03\u7528\uff0c\u786e\u4fdd /var/log \u4e0b\u4e0d\u6b8b\u7559\u542b\u7cfb\u7edf\u65e5\u5fd7\u7684\u76ee\u5f55\u3002",
                "bool LogViewerService::exportOpsLog(const QDBusUnixFileDescriptor &fd)",
                "        qCWarning(logService) << \"exportOpsLog: invalid file descriptor from caller\";",
                "        qCWarning(logService) << \"exportOpsLog: failed to create temporary dir under /var/log:\" << tmpOpsDir.errorString();",
                "        qCWarning(logService) << \"exportOpsLog: failed to create log collect dir:\" << logCollectDir;",
                "        qCWarning(logService) << \"exportOpsLog: zip failed, exitCode:\" << zipProc.exitCode()",
                "            qCWarning(logService) << \"exportOpsLog: failed to open temp zip for reading:\" << tmpZipPath;",
                "                qCWarning(logService) << \"exportOpsLog: failed to open caller fd for writing\";",
                "                    qCWarning(logService) << \"exportOpsLog: write to caller fd failed\";",
                "        qCWarning(logService) << \"exportOpsLog: aborted, failed to write zip to caller fd\";",
                "    qCDebug(logService) << \"exportOpsLog: ops logs zipped and written to caller fd successfully\";"
            ]
        },
        "logViewerService/logviewerservice.h": {
            "a": [
                "    Q_SCRIPTABLE QString exportOpsLog();"
            ],
            "b": [
                "    Q_SCRIPTABLE bool exportOpsLog(const QDBusUnixFileDescriptor &fd);",
                "    // \u57fa\u4e8e fd \u7684 TOCTOU \u5b89\u5168\u65b9\u5f0f\u5220\u9664 exportOpsLog \u4ea7\u751f\u7684 /var/log \u4e34\u65f6\u76ee\u5f55\uff08opsDir\uff09\u3002",
                "    // \u7531 exportOpsLog \u5199\u5165 fd \u5b8c\u6210\u540e\u81ea\u52a8\u8c03\u7528\u56de\u6536\uff0c\u6210\u529f\u8fd4\u56de true\u3002"
            ]
        },
        "logViewerService/opslogexport.cpp": {
            "a": [
                "            qWarning() << \"Failed to chown export path:\" << path << \"error:\" << strerror(errno);"
            ]
        }
    }
}

@deepin-ci-robot

Copy link
Copy Markdown

deepin pr auto review

★ 总体评分:60分

■ 【总体评价】

代码成功重构了日志导出架构,通过传递文件描述符彻底消除了原有的TOCTOU竞态条件,但存在栈溢出及进程阻塞风险
逻辑正确但因引入栈上大内存分配与缺少进程超时控制等安全漏洞扣40分

■ 【详细分析】

  • 1.语法逻辑(基本正确)✓

前后端分离收集日志的逻辑清晰,前端负责用户态日志收集与解压,后端负责系统日志收集与压缩写入。基于fd的D-Bus通信闭环设计合理,safeRemoveDirRecursive使用openat/unlinkat相对路径操作避免了路径重解析竞态,目录清理逻辑严密
建议:在Utils::safeCpSkipSymlinks中,若所有源文件均为符号链接被过滤,会导致执行cp -P dest缺少操作数而报错,建议增加args.size() > 2的判断

  • 2.代码质量(良好)✓

提取了opslogpaths.h公共头文件保证了前后端目录结构一致性,消除了硬编码重复。将原有的巨型函数拆分为exportUserPermissionAppLogs等子函数,职责划分明确。注释详尽,准确解释了安全设计意图
建议:Utils::exportUserPermissionAppLogs中存在大量结构相似的safeCpSkipSymlinks调用,可考虑通过配置数组结合循环来进一步降低冗余度

  • 3.代码性能(存在性能问题)✕

LogViewerService::exportOpsLog函数中直接在栈上分配了1MB的缓冲区char buf[bufSize]。系统守护进程的线程栈大小通常受限,在栈上分配如此巨大的空间极易导致栈溢出崩溃,引发服务拒绝服务
建议:将栈分配改为堆分配,使用QByteArray buffer(bufSize, Qt::Uninitialized)std::vector<char>来承载缓冲区

  • 4.代码安全(存在 3 个安全漏洞(中危2个,低危1个))✕

漏洞对比统计:新增漏洞 3 个,减少漏洞 0 个,持平 0 个
代码修复了原接口的严重TOCTOU与符号链接劫持漏洞,但引入了新的内存安全与进程控制风险

  • 安全漏洞1(中危):[栈缓冲区溢出] 在 [LogViewerService::exportOpsLog/logviewerservice.cpp] 中,[使用constexpr qint64 bufSize = 1 << 20; char buf[bufSize];在栈上分配1MB空间。当D-Bus调用线程栈空间不足时,将触发段错误导致log-viewer-service守护进程崩溃,攻击者可通过频繁触发导出操作造成本地拒绝服务] ——非常重要

  • 安全漏洞2(中危):[进程无超时控制] 在 [LogViewerService::exportOpsLog/logviewerservice.cpp] 中,[调用zipProc.waitForFinished(-1)等待压缩进程结束且未设置超时阈值。若收集的日志目录中存在异常大文件或由于磁盘I/O挂起,zip进程将无限期阻塞,导致D-Bus服务线程被永久占用,所有后续日志导出请求均会挂起] ——非常重要

  • 安全漏洞3(低危):[路径遍历导致文件覆盖] 在 [LogAllExportThread::run/logallexportthread.cpp] 中,[使用unzip -o解压后端传来的压缩包且未校验内部条目路径。若后端临时目录被污染(如存在名为../../.bashrc的文件),打包后解压会覆盖用户家目录下的敏感文件。虽然触发需root配合且仅限当前用户权限,但违背了最小影响面原则] ——非常重要

  • 建议:将1MB栈变量改为堆分配的QByteArray;为zipProc.waitForFinished添加300秒超时限制并在超时后执行kill();使用libzip库替代unzip命令行工具,在解压时显式拒绝包含..的路径条目

■ 【改进建议代码示例】

// 修复 LogViewerService::exportOpsLog 中的栈溢出与进程阻塞漏洞
bool LogViewerService::exportOpsLog(const QDBusUnixFileDescriptor &fd)
{
    // ... 前置鉴权与临时目录创建逻辑保持不变 ...

    QProcess zipProc;
    zipProc.setWorkingDirectory(logCollectDir);
    zipProc.start(QStringLiteral("zip"), QStringList() << QStringLiteral("-r")
                                                       << tmpZipPath << QStringLiteral("."));
    // 修复安全漏洞2:增加超时限制,防止进程无限阻塞导致服务挂起
    static constexpr int kZipTimeoutMs = 300000;
    if (!zipProc.waitForFinished(kZipTimeoutMs) || zipProc.exitCode() != 0) {
        qCWarning(logService) << "exportOpsLog: zip failed or timed out, exitCode:" << zipProc.exitCode()
                              << "stderr:" << zipProc.readAllStandardError();
        zipProc.kill();
        QFile::remove(tmpZipPath);
        removeOpsTempDirByPathInternal(opsDir);
        return false;
    }

    bool writeOk = false;
    {
        QFile zipIn(tmpZipPath);
        if (!zipIn.open(QIODevice::ReadOnly)) {
            qCWarning(logService) << "exportOpsLog: failed to open temp zip for reading:" << tmpZipPath;
        } else {
            QFile fdOut;
            if (!fdOut.open(fdi, QIODevice::WriteOnly)) {
                qCWarning(logService) << "exportOpsLog: failed to open caller fd for writing";
            } else {
                constexpr qint64 bufSize = 1 << 20;  // 1 MiB
                // 修复安全漏洞1:将栈分配改为堆分配,避免栈溢出导致守护进程崩溃
                QByteArray buffer(bufSize, Qt::Uninitialized);
                char *buf = buffer.data();
                
                qint64 n = 0;
                bool error = false;
                while ((n = zipIn.read(buf, bufSize)) > 0) {
                    qint64 written = 0;
                    while (written < n) {
                        qint64 w = fdOut.write(buf + written, n - written);
                        if (w < 0) {
                            error = true;
                            break;
                        }
                        written += w;
                    }
                    if (error)
                        break;
                }
                if (error || n < 0) {
                    qCWarning(logService) << "exportOpsLog: write to caller fd failed";
                } else {
                    fdOut.flush();
                    writeOk = true;
                }
                fdOut.close();
            }
            zipIn.close();
        }
    }

    QFile::remove(tmpZipPath);
    removeOpsTempDirByPathInternal(opsDir);

    if (!writeOk) {
        qCWarning(logService) << "exportOpsLog: aborted, failed to write zip to caller fd";
        return false;
    }

    qCDebug(logService) << "exportOpsLog: ops logs zipped and written to caller fd successfully";
    return true;
}

@deepin-ci-robot

Copy link
Copy Markdown

@GongHeng2017: The following test failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
github-pr-review-ci 9b8846d link true /test github-pr-review-ci

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants