热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Linux下杀毒软件CPU占用率为何持续升高?

作者|beyondma责编|张文来源|CSDN博客头图|CSDN下载自视觉中国最近笔者遇到这样一个相对比较疑难的事件,某个在Linux下运行的杀毒软件启动后ÿ

作者 | beyondma  责编 | 张文

来源 | CSDN 博客

头图 | CSDN 下载自视觉中国

最近笔者遇到这样一个相对比较疑难的事件,某个在 Linux 下运行的杀毒软件启动后,在某些情况下 CPU 占用率会持续升高,而且在交易量较高的情况下极易复现。而奇怪的是,我们之前已经对于杀毒软件的 CPU 使用率进行了上限限定。出现这样异常事件表明:杀毒软件并没有执行之前设定的资源占用控制策略,CPU 使用率始终持续异常偏高。

分析下来这个事件还是很有借鉴意义的。

由于此事件涉及一些敏感信息,具体不便公开的细节就不透露了,仅把可以公开的情况梳理一下,供各位读者参考。

首先我们先明确一下钩子(hook)函数的概念,简单来讲这就是一类改变其它函数行为的函数。举个简单的例子,我每次进入会议室的时候都是直接推开门然后进入的,但是现在我在进入门之前要先向向会议室主持人申请,得到许可才能进入,那么向主持人申请的动作就被 attatch 到了进入会议室这个动作上了,整个过程就可以简单的理解为 hook。

我们知道在 Linux 下想改变系统的行为,需要代码运行的内核态。比如 kprobe、fsnotify 等机制,提供了 root 用户 hook 到内核代码的权限,并最终将自己的代码段 attach 到内核调用中。

CPU 使用率过高的原因分析

经确认这款杀毒软件的 CPU 占用率控制模型如下图,其守护模块会定时判断 agent 资源使用情况,如果超标则将释放扫描模块使用的 CPU 与内存资源。

但是具体分析下来,这样的机制在 IO 频繁的系统上存在缺陷,具体原因扫描模块在内核态下执行时下无法释放 CPU 资源。

分析过程如下:

经确认杀毒软件 agent 在行为监测时,在进程将文件加载到内存前,会使用 hook 技术对于 open 等系统调用进行 attach,确定加载的文件不含恶意代码后,才允许进程加载该文件。因此在 Linux 内核找到系统调用的 attatch 机制的相关代码进行分析。

1. 系统调用中 sys_open 函数,使用 fsnotify 机制对于 attach 注入到 sys_open 函数的进程进行回调通知。(具体代码位置在 kernel/open.c)

2. attach 到 sys_open 的代码执行过程始终是处于内核态中的,同时 Linux 的 fsnotify 机制也会加内核锁,在内核锁解锁前该进程无法释放 CPU,不能被打断。(具体代码位置在 kernel/fsnotify.c)

杀毒软件扫描模块 attach 内核函数的机制与 fsnotify 类似,因此其扫描模块在进行行为检测时会在内核态执行且不能被打断,而在系统中原本就有大量 IO 操作的情况下,守护模块将失效。

在 POC 测试时,该杀毒软件在文件扫描时其 CPU 占用率始终不高,这其中的原因是由于在扫描文件时该杀毒软件全部运行于用户态下,不存在内核态运行的情况,因此守护模块可正常调节 CPU 使用情况。

解决方案浅析

先说一下实测结论:在加入 attach 延时操作后,IO 吞吐量巨幅下降。经访照该杀毒软件的机制进行实测模拟,在内核 sys_open 函数 attach 加入延时操作,观察对于系统 IO 的影响。

在加入将内核 sys_open 延时一倍的操作后,我在华为的在鲲鹏 4C/8G 的平台实测上,每秒钟文件打开、关闭文件操作的次数,由每秒 867次 的峰值下降到了 72 次,出现了 90%以上的下降。这可能与内核锁的雪崩效应有关。

经确认,在之前的版本之所以没有出现问题,是由于当守护进程在确认 CPU 调节失效后会对自身 agent 进行整体自毁操作(modelu_exit),因此不会触发类似于 CPU 占用率持续升高的案例。

那么针对这样的机制具体的解决方案如下:

  1. 对于内核态代码执行,加入全局并发数限制,对于所有执行在内核态的扫描线程,进行全局并发锁限制,具体并发数的设置还需要进行进一步测试后得出结果,在鲲鹏 4C/8G 的平台上测试最大并发数设置为 4 基本不会对系统正常调用产生影响,建议先将系统 CPU 个数设定为最大并发数,进行测试。

  2. 对于对于内核态代码执行加入每秒执行次数限制,对于所有执行在内核态的扫描线程,进行全局的执行次数限制,加入执行令牌,每秒执行次数不应该大于最大 IO 数量的 10%,在此方案下也可避免对于系统正常调用的影响。

  3. 加入扫描任务调度机制:避免在内核态执行耗时的扫描任务,只是快速收到系统的 open 调用指令后,将相关的扫描任务加入调试队列,就立刻返回,在用户态统一执行扫描任务,也可避免由于代码长时间运行于内核态造成的问题。

声明:本文为作者独立观点,不代表 CSDN 立场。

☞程序员的反击!每天一个离职小技巧☞人均 11878 元,2020 年研发岗年终奖最高!技术、产品岗均榜上有名☞被法拉第夸、狄更斯为她读诗、英王参加她的成人礼,程序员祖师的人生有多传奇?
☞程序员因拒绝带电脑回家被开除,获赔 19.4 万元

点分享

点收藏

点点赞

点在看



推荐阅读
  • MySQL数据库锁机制及其应用(数据库锁的概念)
    本文介绍了MySQL数据库锁机制及其应用。数据库锁是计算机协调多个进程或线程并发访问某一资源的机制,在数据库中,数据是一种供许多用户共享的资源,如何保证数据并发访问的一致性和有效性是数据库必须解决的问题。MySQL的锁机制相对简单,不同的存储引擎支持不同的锁机制,主要包括表级锁、行级锁和页面锁。本文详细介绍了MySQL表级锁的锁模式和特点,以及行级锁和页面锁的特点和应用场景。同时还讨论了锁冲突对数据库并发访问性能的影响。 ... [详细]
  • 本文介绍了操作系统的定义和功能,包括操作系统的本质、用户界面以及系统调用的分类。同时还介绍了进程和线程的区别,包括进程和线程的定义和作用。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 基于事件驱动的并发编程及其消息通信机制的同步与异步、阻塞与非阻塞、IO模型的分类
    本文介绍了基于事件驱动的并发编程中的消息通信机制,包括同步和异步的概念及其区别,阻塞和非阻塞的状态,以及IO模型的分类。同步阻塞IO、同步非阻塞IO、异步阻塞IO和异步非阻塞IO等不同的IO模型被详细解释。这些概念和模型对于理解并发编程中的消息通信和IO操作具有重要意义。 ... [详细]
  • Tomcat/Jetty为何选择扩展线程池而不是使用JDK原生线程池?
    本文探讨了Tomcat和Jetty选择扩展线程池而不是使用JDK原生线程池的原因。通过比较IO密集型任务和CPU密集型任务的特点,解释了为何Tomcat和Jetty需要扩展线程池来提高并发度和任务处理速度。同时,介绍了JDK原生线程池的工作流程。 ... [详细]
  • 海马s5近光灯能否直接更换为H7?
    本文主要介绍了海马s5车型的近光灯是否可以直接更换为H7灯泡,并提供了完整的教程下载地址。此外,还详细讲解了DSP功能函数中的数据拷贝、数据填充和浮点数转换为定点数的相关内容。 ... [详细]
  • Android工程师面试准备及设计模式使用场景
    本文介绍了Android工程师面试准备的经验,包括面试流程和重点准备内容。同时,还介绍了建造者模式的使用场景,以及在Android开发中的具体应用。 ... [详细]
  • 本文介绍了H5游戏性能优化和调试技巧,包括从问题表象出发进行优化、排除外部问题导致的卡顿、帧率设定、减少drawcall的方法、UI优化和图集渲染等八个理念。对于游戏程序员来说,解决游戏性能问题是一个关键的任务,本文提供了一些有用的参考价值。摘要长度为183字。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • 如何在服务器主机上实现文件共享的方法和工具
    本文介绍了在服务器主机上实现文件共享的方法和工具,包括Linux主机和Windows主机的文件传输方式,Web运维和FTP/SFTP客户端运维两种方式,以及使用WinSCP工具将文件上传至Linux云服务器的操作方法。此外,还介绍了在迁移过程中需要安装迁移Agent并输入目的端服务器所在华为云的AK/SK,以及主机迁移服务会收集的源端服务器信息。 ... [详细]
  • r2dbc配置多数据源
    R2dbc配置多数据源问题根据官网配置r2dbc连接mysql多数据源所遇到的问题pom配置可以参考官网,不过我这样配置会报错我并没有这样配置将以下内容添加到pom.xml文件d ... [详细]
  • 本文介绍了在Android开发中使用软引用和弱引用的应用。如果一个对象只具有软引用,那么只有在内存不够的情况下才会被回收,可以用来实现内存敏感的高速缓存;而如果一个对象只具有弱引用,不管内存是否足够,都会被垃圾回收器回收。软引用和弱引用还可以与引用队列联合使用,当被引用的对象被回收时,会将引用加入到关联的引用队列中。软引用和弱引用的根本区别在于生命周期的长短,弱引用的对象可能随时被回收,而软引用的对象只有在内存不够时才会被回收。 ... [详细]
  • 深入解析Linux下的I/O多路转接epoll技术
    本文深入解析了Linux下的I/O多路转接epoll技术,介绍了select和poll函数的问题,以及epoll函数的设计和优点。同时讲解了epoll函数的使用方法,包括epoll_create和epoll_ctl两个系统调用。 ... [详细]
author-avatar
手机用户2502917141
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有