Epoll 小叙

一、概述

  • epoll 是 Linux 内核为了处理大批量的文件描述符而改进的 poll,是 Linux 下多路复用IO接口select/poll的增强版本。epoll可以显著提高程序在大量并发连接中只有少量活跃的情况下的系统的CPU利用率。

  • 服务器要管理多个客户端的连接,而 recv 函数只能监视单个 socket,因此引入了 select/poll。

    但 select 能监测的文件描述符个数限制在 FD_SETSIZE,通常是1024个。这对于并发量达到上万的服务器来说显然不够。与之相对的是,epoll所支持的fd上限是最大可以打开的数目,具体数字可以cat /proc/sys/fs/file-max查看(本人机器上该值为9223372036854775807)。

  • 当存在部分活跃socket时,传统 select/poll 会线性扫描整个socket集合,这会让效率随着socket数量的增加而线性下降,而这就是限制了 select 最大监视数量的原因,程序被唤醒后不知道是哪个 socket 处于活跃状态,需要遍历。

    而 epoll 是基于每个 fd 上面的 callback 函数实现,因此只会对活跃的 socket 进行处理,效率更高。

  • select、poll、epoll之间的区别

    • select:只知道有I/O事件发生,但不知道是具体哪一个,因此只能无差别遍历所有流。时间复杂度$O(n)$,fd数量限制在 FD_SETSIZWE。
    • poll:大致同上,轮询所有套接字,时间复杂度为 $O(n)$,但fd没有数量限制,因为它使用链表存储fd。
    • epoll: 事件驱动,epoll会把哪个流发生了怎样的IO事件通知给用户。时间复杂度$O(1)$。
  • epoll提供了两种触发方式

    • 一种是传统 select/poll 的水平触发(Level Triggered, LT),缺省工作模式,同时还支持阻塞非阻塞的socket。当某个文件描述符准备就绪后,内核会持续通知用户,直到重新变为未就绪状态。
    • 再一种是边缘触发(Edge Triggered),高速工作模式,只支持非阻塞的socket。当某个文件描述符从未就绪变成就绪时,内核会通过epoll通知用户。注意,只通知一次。通知动作只会在文件描述符从未就绪变成就绪这个时刻触发。如果一个已经就绪的文件描述符迟迟不被处理,即一直位于就绪状态,那么该文件描述符就一直不会触发通知。
阅读更多...

WebServer v1.0 文档

概述

WebServer 1.0 简单实现了一个基础的 多并发网络服务程序 。在该版本中,主要实现了以下重要内容:

  • 线程互斥锁 & 条件变量的封装
  • 线程池的设计,以支持并发
  • 基础网络连接的实现
  • http 协议的简略支持
    • 支持部分常用 HTTP 报文
      • 200 OK
      • 400 Bad Request
      • 500 Internal Server Error
      • 501 Not Implemented
      • 505 HTTP Version Not Supported
    • 支持 HTTP GET 请求
    • 支持 HTTP/1.1 持续连接 特性

1.0 版本的项目代码位于 Kiprey/WebServer CommitID: 4095cc - github

最新版本的项目代码位于 Kiprey/WebServer - github

阅读更多...

V8 TurboFan 生成图简析

一、简介

v8 turbolizer 有助于我们分析 JIT turbofan 的优化方式以及优化过程。但我们常常对于 turbolizer 生成的 IR 图一知半解,不清楚具体符号所代表的意思。以下为笔者阅读相关代码后所做的笔记。

阅读更多...

WSL64 运行 32 位程序

WSL1 下执行 x86 程序较为困难,需要进行较多步骤,并且存在局限性;

WSL2 下可以直接执行 x86 程序,但需要从 WSL1 中升级上去。

两种操作均较为麻烦,因此这里记录了一点笔者走过的弯路。

阅读更多...

CVE-2018-16065 分析

一、前言

CVE-2018-16065 是 v8 中 EmitBigTypedArrayElementStore 函数内部的一个漏洞。该漏洞在检查相应 ArrayBuffer 是否被 Detach(即是否是neutered)之后,执行了一个带有副作用的(即可调用用户 JS callback 代码的) ToBigInt 函数。而用户可在对应回调函数中将原先通过上述检查的 BigIntArray (即不是 neutered 的 TypedArray)重新变成 neutered

这将使一部分数据被非法写入至一块已经 Detached 的 ArrayBuffer上。如果 GC 试图回收该 ArrayBuffer 的 backing store ,则会触发 CRASH。

阅读更多...

CVE-2019-5755 分析

一、前言

  • CVE-2019-5755 是一个位于 v8 turboFan 的类型信息缺失漏洞。该漏洞将导致 SpeculativeSafeIntegerSubtract 的计算结果缺失 MinusZero (即 -0)这种类型。这将允许 turboFan 计算出错误的 Range 并可进一步构造出越界读写原语,乃至执行 shellcode。

  • 复现用的 v8 版本为 7.1.302.28 (或者commit ID a62e9dd69957d9b1d0a56f825506408960a283fc 前的版本也可)

阅读更多...

CVE-2019-13764 分析

一、前言

  • CVE-2019-13764 是 v8 中的一个位于 JIT TyperPhase TypeInductionVariablePhi 函数的漏洞。我们可以通过这个例子简单学习一下 TyperPhase 中对 InductionVariablePhi 的处理方式,以及越界读取构造方式。

  • 复现用的 v8 版本为 7.8.279.23(chromium 78.0.3904.108) 。

阅读更多...

CVE-2020-6468 分析

一、前言

  • CVE-2020-6468 是 v8 中的一个位于 DeadCodeElimination::ReduceDeoptimizeOrReturnOrTerminateOrTailCall 函数的 JIT 漏洞。通过该漏洞攻击者可触发类型混淆修改数组的长度,这会导致任意越界读写并可进一步达到 RCE

    具体的说,就是可以在 CheckMaps 结点前向目标对象内部写入 -1,在被认出对象类型前成功修改数组长度。

  • 测试用的 v8 版本为 8.1.307

阅读更多...

CVE-2021-3156分析

一、前言

  • sudo是Linux中一个非常重要的管理权限的软件,它允许用户使用 root 权限来运行程序。而CVE-2021-3156是sudo中存在一个堆溢出漏洞。通过该漏洞,任何没有特权的用户均可使用默认的sudo配置获取root权限。

  • 该漏洞可以影响从1.8.2~1.8.31p2下的所有旧版本sudo,以及1.9.0~1.9.5p1的所有稳定版sudo。

    Qualys漏洞团队于2021-01-13联系 sudo 团队、2021-01-26正式披露。

  • 由于这个漏洞原理较为简单,同时又涉及到提权这种高危操作,并且其影响广泛(笔者一台虚拟机、一个WSL以及一台阿里云服务器均可被攻击),相当有趣。所以我们接下来就来简单分析一下这个漏洞。

阅读更多...
  • Copyrights © 2020-2023 Kiprey
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~