【TEE论文】IceClave: A Trusted Execution Environment for In-Storage Computing

摘要

使用现代固态硬盘(SSD)的存储中计算使开发人员能够将程序从主机转移到SSD上。这被证明是缓解I/O瓶颈的有效方法。为了促进存储中计算,已经提出了许多框架。然而,其中很少有框架将存储中的安全性作为首要任务。具体而言,由于现代SSD控制器没有可信执行环境,被转移到SSD上的(恶意)程序可能会窃取、修改甚至破坏存储在SSD中的数据。在本文中,我们首先调查了存储中计算可能进行的攻击。为了抵御这些攻击,我们构建了一个轻量级的可信执行环境,名为IceClave,用于存储中计算。IceClave利用TrustZone扩展,在存储中程序和包括闪存地址转换、数据访问控制和垃圾回收在内的闪存管理功能之间实现安全隔离。IceClave还通过对存储中DRAM的内存完整性验证,实现了存储中程序之间的安全隔离,而开销很低。为了保护从闪存芯片加载的数据,IceClave在闪存控制器中开发了轻量级的数据加密/解密机制。我们使用完整的系统模拟器开发了IceClave。我们使用各种数据密集型应用程序(如数据库)对IceClave进行评估。与现有的存储中计算方法相比,IceClave只引入了7.6%的性能开销,同时以最小的硬件成本在SSD控制器中实现了安全隔离。IceClave仍然保持了存储中计算的性能优势,比传统的基于主机的可信计算方法提供高达2.31倍的性能。

引言

存储中计算一直是加速数据密集型应用的一种有前景的技术,尤其适用于大规模数据处理和分析[15、20、33、39、45、52、56、57、72、81]。它将计算移动到存储设备(如基于闪存的固态硬盘SSD)中存储的数据附近,从而通过显著减少主机和存储设备之间传输的数据量来克服I/O瓶颈。

由于现代SSD在其控制器中采用了多个通用嵌入式处理器和大容量DRAM,使得在存储中进行计算成为今天的现实。为了促进存储中计算的广泛采用,已经提出了各种框架。例如,Willow [72]通过RPC协议使开发人员能够将代码从主机机器转移到SSD上,而Biscuit [39]则开发了一个支持多个存储中计算任务的存储中运行时系统,遵循MapReduce计算模型。所有这些先前的工作都展示了存储中计算在加速数据处理方面的巨大潜力。然而,它们中的大多数[19、33、34、52、56、57、72、82]都侧重于性能和可编程性,很少有人将安全性作为设计和实现中的首要任务,这对用户数据和SSD设备构成了巨大威胁,并进一步阻碍了其广泛采用。

由于存储中处理器独立于主机机器运行,并且现代SSD控制器未为在SSD内部运行的程序提供可信执行环境(TEE),它们对用户数据和闪存芯片构成严重的安全威胁。具体而言,一段被转移到存储中的(恶意)代码可能会:(1)篡改闪存传输层(FTL)中的映射表,以破坏闪存芯片的数据管理;(2)访问和破坏其他应用程序的数据;(3)在运行时窃取和修改共存的存储中程序的内存。

为了克服这些安全挑战,正如在现有存储中计算框架[39、72]中开发的那样,我们可以通过在SSD控制器的DRAM(SSD DRAM)中维护特权信息的副本,并强制对存储中程序进行权限检查来简化运行时系统。然而,这种解决方案仍然存在许多安全漏洞。例如,恶意的转移程序可以利用内存漏洞(如缓冲区溢出[28、79、88])来提升权限,以访问和修改SSD DRAM中FTL的缓存映射表;对手可以通过物理攻击(如冷启动攻击、总线窃听攻击和重放攻击[67、71、86])窃取和修改共存的存储中程序生成的中间数据和结果。另一种方法是采用英特尔的软件保护扩展(SGX)作为一种即插即用的解决方案。不幸的是,现代存储中处理器架构不支持SGX技术。而且SGX方法仍然存在显著的性能开销[11、25、50、63、70、80],这是存储中计算和SSD控制器目前无法承受的。

因此,为存储中计算提供安全、轻量级和可信执行环境是其广泛采用的重要一步。理想情况下,我们希望在享受存储中计算的性能优势的同时,能够在存储中程序、核心FTL功能和物理闪存芯片之间实现安全隔离,如图1所示。
在这里插入图片描述

图1:理想情况下的存储中计算安全隔离示意图。图示了连接到SSD控制器的主机机器,其中包括存储中处理器、SSD DRAM和物理闪存芯片。存储中处理器运行存储中程序,并与主机机器和闪存芯片进行通信。

为了解决这些安全挑战,我们提出了一种轻量级的可信执行环境IceClave,用于存储中计算。IceClave是一种专为现代固态硬盘(SSD)控制器和存储计算程序设计的可信执行环境(TEE)。与诸如SGX [25]等通用TEE解决方案不同,IceClave专门考虑了闪存属性和存储计算负载特性。IceClave通过确保安全隔离,包括以下方面的功能:(1)一种新的内存保护方案,以减少由闪存地址转换引起的上下文切换开销;(2)一种优化技术,通过利用大多数存储计算应用程序是读密集型的事实,来保护存储计算程序的存储DRAM;(3)一种用于安全传输存储处理器和闪存芯片之间数据的流密码引擎,具有低性能开销和能量消耗;(4)一种用于管理存储计算TEE生命周期的运行时系统。

具体而言,为了实现存储计算程序和FTL(图1中的1)之间的安全隔离,我们扩展了大多数SSD控制器中可用的ARM处理器的TrustZone。IceClave在安全世界中执行核心FTL功能,例如垃圾回收和磨损均衡,而在正常世界中运行卸载的程序,以使卸载的程序无法干预闪存管理。为了以低开销保护FTL的映射表,我们在正常世界引入了受保护的内存区域,并将映射表放在其中,以避免闪存地址转换的上下文切换。因此,只有受保护的FTL函数才能更新映射表,而卸载的存储计算程序只能通过强制执行的权限检查来读取映射表进行地址转换。

为了实现存储计算程序之间的安全隔离(图1中的2),**我们构建了存储计算TEE来托管卸载的程序,并在数据通信和处理中强制执行数据加密和内存完整性检查。由于大多数存储计算工作负载是读密集型的,IceClave主要需要对存储计算生成的中间数据和结果进行完整性检查,这对存储计算程序的执行几乎没有性能开销。**为了保护存储在存储计算TEE中运行的存储器页面,我们还将轻量级流密码引擎集成到具有最小硬件成本的SSD控制器中。总之,我们在本文中做出了以下贡献:

  • 我们提出了一种用于存储计算的可信执行环境,其中通过扩展TrustZone来保护核心FTL功能。
  • 我们通过为SSD DRAM启用轻量级内存加密和完整性验证,支持存储计算程序之间的安全隔离。
  • 我们展示了IceClave所需的硬件和软件扩展是最小的,并且在现代SSD控制器中可行。
  • 我们使用SSD FPGA板开发了一个系统原型,以定量评估IceClave的开销,并使用全系统模拟器进行敏感性分析。

我们使用全系统模拟器gem5 [37]实现了IceClave,并将SSD模拟器SimpleSSD [38]和内存模拟器USIMM [21]集成到其中,以支持安全的存储中计算。我们还使用真实的OpenSSD Cosmos+ FPGA板开发了一个系统原型,用于验证IceClave的核心功能。我们使用了包括事务性数据库在内的各种数据密集型应用程序来评估IceClave的效率。与最先进的存储中计算方法相比,IceClave对存储中运行时间的性能开销仅为7.6%,同时对SSD控制器的面积和能源开销增加很少。我们的评估还表明,IceClave能够通过提供平均性能提升2.31倍,保持存储中计算的性能优势,而这比传统的基于主机的计算方法要好得多。

背景

2.1 基于闪存的固态硬盘

快速缩小的工艺技术使得固态硬盘(SSD)能够提升性能和容量,加速了它们在如今的数据中心等普通系统中的应用 [4, 43, 44]。我们在图2中展示了一个典型的SSD架构。一个SSD由三个主要组件组成:一组闪存芯片组、一个带有嵌入式处理器和DRAM的SSD控制器,以及闪存控制器 [23, 56]。闪存芯片组以层次结构的方式组织。每个SSD有多个通道,每个通道被多个闪存芯片组共享。每个芯片组由多个闪存芯片组成。每个芯片有多个平面,每个平面又被分成多个闪存块,每个块包含多个闪存页。由于闪存的特性,在一个空闲的闪存页被写入后,该页在未来的写入操作中无法再使用,直到该页被擦除。然而,擦除操作只能以块为单位进行,这是一项耗时的操作。因此,写入操作会被发送到已经擦除的空闲页(即就地写入),而不是等待昂贵的擦除操作。垃圾回收(GC)稍后会清理SSD中的过时数据。由于每个闪存块的使用寿命有限,块的均衡老化(即磨损平衡)非常重要。SSD采用就地写入、垃圾回收和磨损平衡等技术来克服SSD的缺点,并维护用于索引逻辑地址与物理地址映射的间接寻址。所有这些都由SSD控制器中的闪存转换层(FTL)来管理。
在这里插入图片描述

2.2 存储中计算

我们早就意识到传统以CPU为中心的计算对于需要从存储中传输大量数据的数据密集型应用的低效率。应用程序的性能受限于主机和SSD之间低带宽的PCIe接口。为了应对这一挑战,提出了各种存储中计算方法 [39, 52, 56, 72, 89]。通过利用SSD处理器和闪存芯片的高内部带宽,我们可以处理数据。它们显著的性能优势表明存储中计算是一种有前景的技术。然而,由于存储中的处理器是独立于主机运行的,它给存储中计算的采用带来了安全挑战,特别是在多租户环境中,多个应用实例共享物理SSD的情况下 [49, 55, 74–76, 92]。

2.3 存储中的漏洞

当特定代码被迁移到存储中的处理器时,特权信息的副本会被传输并保存在SSD控制器的DRAM中 [39, 72]。这种解决方案是在假设迁移的代码已经提前知道所访问数据的地址和大小的情况下开发的。然而,攻击者可以利用存储中的软件和固件漏洞,如缓冲区溢出 [28, 79, 88] 和总线窃听攻击 [71],实现特权提升。之后,它们可以进行各种进一步的攻击。我们在下面列举了一些攻击方式。
• 恶意用户可以通过软件和物理攻击来操纵存储中程序生成的中间数据和输出,导致计算结果错误。
• 恶意程序可以拦截SSD中的FTL(闪存转换层)功能,如垃圾回收和磨损平衡,并篡改闪存管理。这将导致数据丢失或设备损坏。
• 恶意用户可以通过物理攻击(如总线窃听攻击)窃取存储在闪存芯片中的用户数据,当存储中的程序将数据从闪存芯片加载到SSD DRAM时。
为了防御这些攻击,另一种解决方案是为存储中计算开发操作系统或虚拟化层。然而,由于SSD控制器的资源有限,运行一个完整的操作系统会给SSD带来显著的开销,并增加攻击面,因为操作系统的代码库庞大。此外,这些技术并不足以防御前面提到的诸如板级物理攻击之类的攻击。随着计算越来越靠近存储设备,为这种非传统计算范式提供一个轻量级的执行环境非常重要。由于SSD的设计假设是与主机隔离并纯粹用作存储而不是计算,现代计算系统并不为存储中计算提供安全的运行环境。正如在第1节中讨论的那样,一种直接的方法是采用类似SGX的解决方案 [25, 54]。然而,这需要对硬件进行重大改变,甚至需要替换现代SSD中的存储处理器。由于SGX是为主机机器开发的通用框架,很难实现存储中程序的最佳性能。

3 威胁模型

在本工作中,我们针对多租户场景,即多个应用实例在共享的SSD上运行。遵循当今云计算的威胁模型 [1, 16, 26, 35],我们假设云计算平台已经为终端用户提供了一个安全通道,使其能够将程序迁移到共享的SSD上。相关的代码迁移技术,如安全RPC和库 [22, 39, 72],已经在云平台上部署 [1, 48, 91]。然而,迁移到SSD上的程序可能包含(隐藏的)恶意代码。对于存储中计算,我们信任SSD供应商,他们使得迁移到SSD上的程序能够执行。我们假设硬件供应商没有在其设备中故意植入后门或恶意程序。然而,由于我们在共享平台(如公共云)中部署这些计算性能的SSD,我们不信任可能发起板级物理攻击的平台操作员,比如总线窃听和中间人攻击,或者利用主机机器来窃取或销毁存储在SSD中的数据。类似于SGX的威胁模型,我们将软件侧信道攻击(如缓存时间、页表侧信道攻击 [62] 和推测执行攻击 [51])排除在威胁模型之外,因为这些攻击方法在现实中往往比较麻烦 [25]。我们依靠闪存控制器中提供的纠错码(ECC)[40, 83] 来确保闪存页的完整性。为了防御来自云计算平台或恶意主机操作系统的攻击,通常鼓励用户在将数据存储到SSD之前对其进行加密。然而,在存储中计算过程中,数据仍然可能被泄露。因此,我们对实现IceClave的安全目标采取了更为保守的设计。我们认为我们的威胁模型是现实的。首先,作为系统范围的共享资源,SSD已经被多个应用广泛使用。现有的存储中计算框架已经使终端用户能够将其程序迁移到SSD上。其次,一旦程序被迁移到SSD上,存储中程序将逃离主机操作系统的控制,在新的执行环境中发起攻击。第三,我们的威胁模型考虑了不受信任的平台操作员可能发起的物理攻击。据我们所知,这是第一个面向存储中计算的TEE框架。它旨在防御三类攻击:(1)针对共存的存储中程序的攻击;(2)针对核心FTL功能的攻击;(3)针对从闪存芯片加载的数据和存储中程序生成的数据的潜在物理攻击。

4 设计与实现

我们提出了一种用于存储中计算的TEE,其性能和硬件成本都很低。我们在图3中展示了IceClave架构的概述。为了实现我们的目标,我们提出了扩展ARM TrustZone的方法,创建安全世界和普通世界,以实现FTL中不同实体的安全隔离和保护,同时使用内存加密引擎(MEE)进行内存加密和验证。

4.1 构建IceClave的挑战

为了开发IceClave,我们必须克服三个挑战。
• 首先,由于SSD被多个应用共享,我们需要确保适当的安全隔离。具体来说,我们需要在存储应用程序与FTL之间执行安全隔离,并在应用程序与IceClave运行时之间执行隔离(§4.2和§4.3)。
• 其次,为了在运行时保护存储中程序的数据安全,IceClave需要确保用户数据在离开闪存芯片时的安全性(§4.4)。
• 第三,SSD控制器的资源有限,如DRAM容量和处理能力;因此,IceClave应该是轻量级的,并且不会对存储应用程序的性能产生显著影响(§4.5和§4.6)。

在接下来的章节中,我们将详细讨论如何解决这些挑战。

4.2 保护闪存转换层

由于FTL管理闪存块并控制用户数据映射到每个闪存页,因此它的保护至关重要。如果任何恶意的存储应用程序控制了FTL,它们可以读取、擦除或覆写其他用户的数据,这可能导致严重后果,如数据丢失和泄露。IceClave运行时管理着在SSD内初始化每个存储应用程序的方式,并维护其元数据,例如存储中程序的身份。如果任何存储应用程序能够访问元数据,攻击者可以轻松破坏其他存储应用程序的安全性。为了保护FTL和IceClave运行时免受恶意存储应用程序的攻击,我们需要确保SSD中不同实体的内存保护。具体而言,我们必须确保卸载的应用程序无法访问FTL和IceClave运行时使用的内存区域。我们还需要确保卸载的应用程序在没有适当权限的情况下无法访问彼此的内存区域。为了实现这一点,一种直接的方法是使用TrustZone创建安全世界和普通世界,然后将FTL功能和IceClave运行时放置在安全世界中,将所有存储应用程序放置在普通世界中。然而,这将导致存储应用程序的显着性能开销。这是因为当应用程序每次访问一个闪存页时,它需要切换到托管FTL和其地址映射表的安全世界。类似地,使用类似SGX的方法,我们可以将FTL和存储应用程序放置在不同的enclave中,但这也会产生显着的性能开销,因为我们必须频繁地从一个enclave切换到另一个enclave。为了解决这个挑战,我们通过扩展TrustZone将整个物理主存空间划分为三个内存区域:普通、受保护和安全。我们在图4中展示了这些内存区域。具体而言,我们允许FTL和IceClave运行时在安全世界中执行。它们具有读/写权限以访问整个内存空间。这是必要的,因为FTL的核心功能需要管理地址映射表,而IceClave运行时需要管理每个存储应用程序,例如TEE的创建和删除。我们将存储应用程序放置在普通世界中;因此,它们无法访问属于FTL或IceClave运行时的任何代码或数据区域。对于普通世界中的受保护内存区域,我们使用它来托管共享的地址映射表,以便存储应用程序只能读取地址转换的映射表条目,而无需支付上下文切换的开销。图5展示了与FTL映射表在安全世界中的方案相比,这种优化平均可以提高存储应用程序的性能21.6%。我们将在第4.6节中讨论闪存访问过程及其相关保护的详细信息。我们在图6中展示了内存区域属性的详细信息。根据ARMv8的MMU规范[9],我们使用非安全(NS)位来指示内存访问是使用安全权限还是普通权限进行的。我们利用访问控制标志(AP[2:1])和保留位(ES位在图6中)来创建受保护的区域,在该区域中,IceClave向普通世界授予只读权限,并向安全世界授予读/写权限。值得注意的是,存储内存保护可以在旧版本的ARM处理器[7]中轻松实现,只需指定访问控制标志AP[2:0],以及其他处理器,如RISC-V(请参见第4.7节中的讨论)。
在这里插入图片描述
在这里插入图片描述

4.3 存储程序的访问控制

尽管每个存储程序在访问FTL的映射表时只具有读取访问权限,但恶意的存储程序可以探测管理其他存储程序数据地址转换的映射表条目(例如,通过暴力破解)。因此,攻击者可以轻松访问其他程序的数据。为了解决这个挑战,我们扩展了FTL的地址映射表。我们使用每个条目中的ID位(每个条目为8字节)来跟踪每个存储TEE的标识,并使用它们来验证存储TEE是否具有访问映射表条目的权限。闪存访问的权限检查是通过专用进程执行的。它从存储应用程序接收闪存访问请求,并在将请求发送到闪存芯片之前进行权限检查。该进程在普通世界中独占访问闪存芯片,防止恶意的存储程序进行未授权的闪存访问。我们默认使用四个位作为ID,这会对映射表引入小的存储成本(6.25%)。IceClave将在其运行时内为新创建的TEE重复使用ID,并在TEE创建时设置映射表中的ID位(详见第4.6节的详细信息)。每个存储程序只能访问FTL的地址映射表和已分配的内存空间。对其他内存位置的访问将导致内存管理单元中的故障。为了进一步增强存储程序的内存保护,我们还启用了内存加密和验证功能。

4.4 保护存储DRAM

在这里插入图片描述

存储程序将数据从闪存芯片加载到SSD DRAM中进行数据处理。为了隐藏从闪存芯片读取的数据,IceClave通过在数据在内部总线上传输之前对访问的数据进行加密来保护数据传输过程。现代SSD已经采用了专用的加密引擎[31],但它主要用于全盘加密。在这项工作中,我们在SSD控制器中开发了一个轻量级的流密码引擎,用于保护从闪存芯片到存储处理器的数据传输(详见第5节的实现细节)。尽管我们在SSD DRAM和闪存控制器之间传输数据时启用了数据加密,但用户数据,包括原始数据、中间数据和生成的结果,在运行时仍然可能泄漏。为了解决这个挑战,IceClave同时启用了内存加密和完整性验证
在这里插入图片描述

内存加密。内存加密的目标是保护内存访问中的任何数据或代码不被泄漏。为了实现这一目标,一种常见的方法是在将缓存行写入内存时对其进行加密。目前最先进的工作通常使用分割计数器加密[12, 80, 90]。它通过使用伪一次性密码(OTP)对缓存行进行异或来加密缓存行,而OTP是通过对计数器进行块密码(如AES)加密生成的。在每次写回后,计数器增加以确保时间上的唯一性。它被编码为主计数器和次计数器的串联。当次计数器溢出时,主计数器递增,并且所有其他次计数器被重置。相关的内存块也需要重新加密。因此,这种加密方案具有显著的性能开销。对于存储计算来说,这不是一个太大的问题,因为它以读取为主。我们对典型的存储应用程序进行了研究(见表4),并在运行它们时进行了内存访问次数的剖析(见第6.1节的实验设置)。我们观察到,大多数应用程序在内存写入方面只有很小的部分(见表1)。这些写入通常是由存储程序在运行时产生的中间数据引起的。基于这个观察,我们设计了混合计数器方案。
混合计数器方案的关键思想是,我们只对只读页面使用主计数器,对可写页面使用传统的分割计数器方案。只要页面是只读的,次计数器就不会改变,因此我们不需要只读页面的次计数器。在这种情况下,我们可以缓存存储更多的计数器(对于只读页面,每个缓存行可以有八个计数器)来提高存储应用程序的缓存性能。混合计数器方案维护两种类型的计数器块:用于可写页面的分割计数器块和用于只读页面的主计数器块,如图7所示。我们使用两个完整性树分别存储这两种类型的计数器块。尽管这需要稍微多一些内存空间(占4GB DRAM容量的0.01%)[1]来存储完整性树,并且需要两个处理器寄存器来存储两个根消息认证码(MAC)以进行完整性验证,但与当前的分割计数器方案相比,混合计数器方案平均提高了43%的性能(见图8)。**由于在IceClave中使用了混合计数器方案,我们利用页表条目中的读/写权限位来决定应访问哪些计数器块。我们还支持IceClave中每个内存页面的动态权限更改。**具体而言,对于只读页面,其对应的计数器存储在主计数器树中。当页面变为可写并进行更新时,其对应的主计数器递增,并复制到分割计数器树中的相应条目中,同时初始化该条目中的次计数器。同时,使用新的分割计数器条目重新加密页面,以供以后访问使用。当可写页面变为只读时,其对应的主计数器递增,并被复制回主计数器树中。存储计算程序可以使用ARM处理器提供的内存保护机制(见图6)来更新内存页面的权限。例如,对于用于存储存储程序输入的内存区域,其页面被设置为只读;对于分配用于存储中间数据的内存区域,其页面被设置为可写。
内存完整性验证。为了确保处理器接收到的内容与最近写入内存的内容完全相同,每个内存块都生成一个消息认证码(MAC),通过对其数据和加密计数器进行散列计算得到。在每次内存访问时,使用数据和加密计数器重新计算MAC,并与存储的MAC进行比较,以便检测到数据或计数器的任何更改。完整性树还防止了可以将数据和MAC回滚到其旧版本的重放攻击。如图7所示,完整性树以层次结构组织MAC,并且父MAC确保其子MAC的完整性。树的根安全地存储在处理器芯片中。当缓存行写回到内存时,Merkle树将更新从数据块到根的所有节点的路径上的节点。在IceClave中,我们采用了Bonsai Merkle Tree(BMT)[65]。它通过对计数器块而不是数据块进行散列计算来生成其第一级MAC。正如前面讨论的,IceClave维护两棵Merkle树,但与传统的BMT相比,额外的内存成本是可以忽略的。对于4GB DRAM,IceClave需要0.5MB用于图7(a)中使用的Merkle树,以及4MB用于图7(b)中使用的Merkle树。
在这里插入图片描述

4.5 IceClave运行时

在本节中,我们讨论了IceClave运行时如何促进存储中的可信执行环境(TEE)的执行。它提供了管理存储中的TEE所需的基本功能,如TEE设置、TEE生命周期和元数据管理,以及与安全世界的交互。IceClave运行时还与部署在主机机器上的IceClave库进行交互。需要注意的是,IceClave库只向最终用户提供基本的卸载接口(如RPC)。这不仅减小了可信计算基础,还简化了存储中程序的开发。我们在表2中列出了IceClave的API。IceClave允许用户使用两个API与SSD进行交互:OffloadCode和GetResult。一旦程序被卸载到SSD上,IceClave运行时将执行CreateTEE()来创建一个新的TEE。同时,它将调用SetIDBits()来设置FTL中相应地址映射表条目(参见§4.3)的ID位(访问权限),其中包含由存储中程序指定的逻辑页面地址列表。根据我们对流行的存储中程序的研究,它们的代码大小为28-528KB。然而,对于一个大小超过SSD DRAM可用空间的卸载程序,TEE的创建将失败。在执行存储中程序期间,将调用ThrowOutTEE()来处理程序异常情况。IceClave运行时将中止这些情况下的TEE,包括(1)违反访问控制、(2)TEE内存或元数据损坏,以及(3)存储中程序抛出异常。一旦存储中程序完成,IceClave运行时将调用TerminateTEE()来终止TEE的执行。在TrustZone的帮助下,IceClave支持在每个TEE内进行动态内存分配。为了避免内存碎片化,IceClave将预分配一个大的连续内存区域(默认为16MB)。在删除TEE时,IceClave运行时将释放预分配的内存区域。
在这里插入图片描述

4.6 将所有内容整合起来

我们在图9中说明了使用IceClave运行存储中程序的整个工作流程。与现有的存储中计算框架[39, 72]类似,IceClave库具有基于PCIe的主机到设备通信层,允许用户在主机和SSD之间传输数据。如§3所讨论的,我们利用现代云计算平台中开发的安全通道来实现主机与共享SSD之间的交互。调用§4.5中描述的OffloadCode API(1)来卸载程序。其参数bin表示以机器代码形式预编译的程序,lpa是卸载程序所需的数据的逻辑页面地址(LPAs)列表。它使用任务ID(tid)作为索引来标识卸载的过程。IceClave运行时将使用CreateTEE(2)为卸载的程序创建一个新的TEE。在创建时,IceClave运行时将从正常内存区域为TEE分配内存页,而TEE元数据将在安全内存区域中进行初始化和维护。IceClave还执行SetIDBits以设置LPAs的地址映射表中的访问权限。TEE不依赖FTL来获取物理页面地址(参见§4.2),因为它可以访问受保护内存区域中的映射表(3)。然而,存储中程序可能偶尔遇到缓存未命中,即访问的LPA的映射条目未缓存在SSD DRAM中。在这种情况下,TEE必须通过ReadMappingEntry(4)将地址转换请求重定向到FTL。这时,TEE将被暂停并切换到安全世界,以便FTL加载缺失的映射表页(5),更新受保护内存区域中的缓存映射表,并将PPA返回给TEE。为了避免存储中程序探测SSD的整个物理空间,我们强制执行访问控制(参见§4.3)。通往TEE的数据路径上的任何数据都会使用流密码引擎进行加密(6)。需要注意的是,鼓励用户加密其数据以防范恶意主机操作系统的攻击。他们将随着卸载的程序一起发送解密密钥到TEE,并在TEE中的运行时对数据进行解密。一旦存储中程序在TEE中准备就绪,IceClave运行时将调用TEE。IceClave运行时不断监视启动的TEE的状态,保护内存区域,并确保映射表权限的保护。如果有任何前述完整性受到损害,将抛出异常。在整个TEE的生命周期中,将强制执行§4.4中描述的硬件保护机制,以防止物理内存攻击。IceClave还将在TEE和FTL之间实施强隔离。§4.2中描述的内存保护也将在现有的TrustZone内存控制器(TZASC)[8]中实施。当达到TEE程序的末尾时,在终止TEE并回收已使用资源之前,结果将被复制到TEE的元数据区域(8)。IceClave将使用NVMe中断发起DMA传输请求,表示结果的就绪状态。结果通过IceClave库中提供的GetResult(7)返回到主机内存中。总之,IceClave可以以低开销保护存储中计算免受软件和物理攻击:(1)它可以对SSD DRAM进行低开销的内存加密和验证;(2)它可以在正常世界和安全世界之间进行频繁的上下文切换,保护共享FTL;(3)它可以通过SSD控制器中高效的流密码引擎,保护从闪存芯片到SSD DRAM的数据传输。
在这里插入图片描述

4.7 讨论与未来工作

在本文中,我们利用ARM处理器中的TrustZone技术,实现了存储中程序与FTL函数之间的内存保护。这是因为现代SSD控制器中广泛采用了ARM处理器。由于设备供应商也考虑在其控制器中采用开源的RISC-V架构[32, 41, 73],IceClave的关键思想也可以用新型处理器实现。具体而言,RISC-V定义了三个特权级别,包括应用级别、监管级别和机器级别[36]。我们可以将正常的、受保护的和安全的内存区域(参见§4.2)分别映射到RISC-V的不同内存区域中。除了使用ARM和RISC-V处理器进行存储中计算外,最近的研究还在SSD控制器中部署了硬件加速器[13, 24, 45, 46, 56, 57, 87]。然而,它们还不支持存储中TEE的功能。作为未来的工作,我们希望将IceClave扩展到这些存储中的硬件加速器上。

5 实现细节

在这里插入图片描述

完整系统模拟器。我们使用基于SimpleSSD [38]、Gem5 [37]和USIMM [21]模拟器开发的计算SSD模拟器来实现IceClave。这使我们能够使用不同的SSD配置进行研究,而这在真实的SSD板上很难进行。我们使用SimpleSSD来模拟现代SSD及其存储操作。我们在表3中展示了SSD的配置。为了在模拟器中实现存储中计算,我们利用Gem5来模拟SSD控制器中的乱序ARM处理器。我们还在集成模拟器中实现了流密码,以便在存储中的应用程序从闪存芯片加载数据时进行数据加密/解密。我们使用CACTI 6.5 [61]估计其硬件成本,并发现密码引擎仅对一款现代SSD控制器(如Intel DC P4500 SSD)引入1.6%的面积开销。由于IceClave将在SSD DRAM中实现内存验证,我们利用USIMM来模拟SSD中的DRAM。我们在USIMM模拟器中实现了Bonsai Merkle树(BMT),并使用混合计数器模式(参见§4.4)作为内存加密方案。正如讨论的那样,完整性树的根存储在安全的芯片上寄存器中。计数器缓存大小为128KB。为了实现内存加密和完整性验证,我们强制要求每个内存访问都会触发MAC和完整性树的验证和更新。由于我们使用Gem5开发了一个完整的系统模拟器,我们运行真实的数据密集型工作负载,比如事务数据库,以评估IceClave的效率。真实系统原型。为了验证IceClave的核心功能,包括TEE的创建/删除、FTL和流密码引擎,我们还使用具有双ARM Cortex-A9处理器的OpenSSD Cosmos+ FPGA板实现了IceClave [84]。我们测量了它们的开销,并在表5中显示了它们。我们在图10中展示了流密码引擎的架构。其密钥初始化模块接受对称密钥和任意初始化向量(IV)作为输入,用于初始化密码。IceClave将密钥存储在安全寄存器中,而IV可以是公开的。一旦初始化,流密码每个周期生成64个密钥流位。生成的密钥流按位与从闪存芯片读取的数据进行异或运算,以生成加密数据。解密使用相同的密钥和IV来解码加密数据。IV由时间上唯一的随机数和空间上唯一的地址位构成。这种正交唯一性强制确保在一定时间段内不会重复使用相同的IV值。我们使用的流密码算法是Trivium [30]。为了为不同的闪存页面提供唯一性,我们通过将物理页面地址(PPA)和伪随机数生成器(PRNG)的输出连接起来来构造IV。
在这里插入图片描述

6 评估

我们的评估结果表明:
(1)IceClave对存储中的工作负载引入了最小的性能开销,同时在SSD控制器中实施安全隔离(§6.2和§6.3);
(2)随着我们增加SSD的内部带宽,IceClave可以提高存储中应用程序的性能(§6.4);
(3)IceClave可以使不同访问延迟的各种SSD设备受益(§6.5);
(4)在变化存储中计算能力的情况下,IceClave仍然显著优于传统的基于主机的计算,并提供安全隔离(§6.6和§6.7);
(5)IceClave可以在低性能开销的情况下实现多个存储中程序的并发执行(§6.8)。

6.1 实验设置

在这里插入图片描述

我们使用一组合成工作负载和真实应用程序对IceClave进行评估,如表4所示。在合成工作负载中,我们使用数据库系统中的几个基本操作符,包括算术、聚合和过滤操作。至于真实应用程序,我们运行来自TPC-H基准测试的真实查询。具体而言,我们使用TPC-H查询1、3、12、14和19,其中包括多个连接和聚合操作的组合。除了这些工作负载,我们还运行写入密集型工作负载TPC-B、TPC-C和Wordcount,以进一步评估IceClave的加密和完整性验证开销。在所有这些工作负载中,我们将它们的数据集(表)扩展到32GB的大小,并将它们分布在SSD的通道中。

我们将IceClave与几种最先进的解决方案进行比较。特别地,我们将IceClave与主机机器中可用的Intel SGX进行比较,其中我们将数据从SSD加载到主机内存,并在SGX中执行查询。对于此设置,我们使用一台真实的服务器,其配备了Intel i7-7700K处理器(主频4.2GHz)、16GB DDR4-3600 DRAM和1TB Intel DC P4500 SSD。为了公平比较,我们遵循Intel DC P4500 SSD的规格来配置我们的SSD模拟器。

我们还将IceClave与当前不提供TEE用于卸载程序的存储中计算方法进行比较。它们列举如下:

  • Host:将数据从SSD加载到主机内存,并使用主机处理器执行数据查询。主机机器和SSD设置如上所述。
  • Host+SGX:在从SSD加载数据后,在Intel SGX中运行数据查询。我们在实验中使用的SGX SDK版本是2.5.101。
  • In-Storage Computing (ISC):使用SSD控制器中的ARM处理器运行数据查询,以便利用SSD的高内部带宽。

6.2 IceClave的性能

在这里插入图片描述

我们在图11中展示了运行每个查询基准的规范化性能。我们以Host作为基准,在其中我们在主机机器上运行查询工作负载,同时从SSD加载数据集。如图11所示,IceClave的性能分别比Host和Host+SGX平均提高了2.31倍和2.38倍。这表明IceClave不会损害存储中计算的性能优势。由于这些数据查询工作负载受到存储I/O的限制,主机机器上的SGX(Host+SGX)会稍微降低工作负载的性能。与未启用安全隔离的存储中计算(ISC)相比,IceClave引入了7.6%的性能开销,这是由于在存储中的TEE中使用的安全技术。

为了进一步了解IceClave的性能行为,我们还在图11中展示了性能细分情况。对于Host和Host+SGX方案,我们将它们的工作流程分为两个主要部分:数据加载时间和计算时间。正如我们所见,Host+SGX平均增加了103%的计算时间,这是由于SGX在主机机器上运行导致的。对于ISC和IceClave方案,我们对其进行了性能剖析,包括从闪存芯片加载数据的时间、使用存储中处理器执行数据查询的时间,以及IceClave进行内存加密和验证所引起的开销。如图11所示,IceClave和ISC在加载时间上需要的时间更少,因为SSD的内部带宽高于其外部带宽。它们需要更多的时间(平均提高2.47倍)来执行数据查询。与ISC相比,IceClave需要进行内存加密和验证。对于诸如Wordcount之类的写入密集型工作负载,IceClave会稍微增加内存加密开销。这是因为Merkle树本质上支持并行更新,并且我们的混合计数器设计默认保留了这个属性。然而,对于大多数存储中的工作负载,IceClave仍然显著优于基于主机的方法。

6.3 IceClave中的开销来源

在这里插入图片描述

我们还对使用IceClave运行存储中程序的整个工作流程进行了剖析。我们在表5中展示了IceClave的关键组件及其开销。IceClave分别需要95微秒和58微秒(在实际的SSD FPGA板上测量)来创建和删除SSD内部的TEE。安全世界和正常世界之间的上下文切换开销为3.8微秒。如§4.2中所讨论的,IceClave在运行时有很少的上下文切换,因为它将频繁访问的地址映射表放在受保护的内存区域中。上下文切换主要发生在受保护的内存区域中缺少映射表条目的情况下,IceClave需要切换到安全世界从闪存芯片中获取映射表,并在受保护的内存区域中进行更新。此外,IceClave的内存加密和验证操作开销较小,因为大多数存储中的工作负载是读密集型(见§4.4和表1)。每个内存加密和验证操作的平均执行时间分别为102.6纳秒和151.2纳秒。我们对内存加密和完整性验证中由于获取和溢出计数器而引起的额外内存访问进行了剖析(见表6)。我们在表6中显示了相对于不强制内存安全的常规内存访问的额外内存流量的百分比。平均而言,内存加密使内存流量增加了20.26%,验证操作使内存流量增加了14.51%。

我们还对从TEE请求的闪存地址转换数量进行了剖析,并发现只有0.17%的这些地址转换在受保护的内存区域的缓存映射表中未命中。这表明存储中的程序不会频繁地引起从正常世界到安全世界的上下文切换,表明IceClave对于存储中的工作负载来说是轻量级的。

6.4 SSD带宽的影响

在这里插入图片描述

我们现在评估IceClave在更改不同SSD参数时的性能敏感性。首先,我们通过改变闪存通道的数量从4个变为32个来改变SSD的内部带宽。通过这样做,聚合的内部I/O带宽呈线性增长,而外部带宽受到PCIe带宽的限制[18, 52]。我们将IceClave与基于主机的方法(Host)进行比较,并在图12中展示了归一化加速比。对于每个数据查询工作负载,随着通道数量的增加,IceClave的性能优势显著扩大。具体而言,IceClave相比于Host将性能提速了1.7倍至5.0倍,表明IceClave对存储中计算的性能影响可以忽略不计。对于涉及更复杂计算的存储中工作负载(如TPC-B、TPC-C和Wordcount),增加内部带宽可以带来1.2倍至1.8倍的性能提升;而对于其他工作负载,如合成工作负载和TPC-H,IceClave获得了更多的性能优势(1.9倍至6.2倍)。值得注意的是,IceClave甚至比Host+SGX获得了更多的性能优势,因为SGX引入了额外的开销(参见图11和§6.2)。而且,IceClave为存储中的程序提供了TEE。当我们改变内部SSD带宽时,我们还将IceClave与ISC进行了比较。如图13所示,与ISC相比,IceClave将应用程序的性能降低了最多28%(平均为8.6%)。随着通道数量的增加,对于像TPC-C这样的复杂数据查询,其额外的开销略有增加。这主要是由于内存加密和完整性验证的开销增加。然而,IceClave为卸载的程序提供了TEE,使我们相信这样的努力是值得的。
在这里插入图片描述

6.5 数据访问延迟的影响

为了了解数据访问延迟对IceClave性能的影响,我们将从访问闪存页面的读取延迟从10微秒变化到110微秒,模拟超低延迟的NVMe SSD [2, 6]到常规TLC闪存的SSD [60]。我们将写入延迟保持为300微秒,因为大多数存储中的工作负载是读取密集型,涉及较少的写入操作。我们在SSD中使用8个通道。我们在图14中展示了实验结果。如图14所示,与受外部PCIe带宽限制的基于主机的计算方法相比,IceClave在具有不同访问延迟的各种SSD设备上提供了性能优势(1.8倍至3.2倍)。对于需要更多计算资源进行哈希连接操作的TPC-B、TPC-C和TPC-H Q19查询工作负载,在具有超低延迟的SSD上,IceClave的性能优势较小,因为主机机器中的处理器提供了更强大的计算资源。
在这里插入图片描述

6.6 计算能力的影响

利用嵌入式处理器来运行存储中的应用程序,了解存储中计算能力如何影响IceClave的效率是很有意思的。我们通过使用不同型号的嵌入式处理器来改变此参数。我们使用存储中计算模拟器来模拟具有典型乱序(OoO)ARM处理器A72和不同频率的顺序处理器A53,并将其与基准的Host进行比较,基准Host使用Intel i7-7700K处理器,频率为4.2GHz。我们在图15中展示了归一化加速比。随着ARM处理器的CPU频率降低,IceClave的性能下降了13.7%至33.4%。在相同的CPU频率下,具有乱序处理器A72的性能略优于顺序处理器A53。这表明IceClave可以与不同类型的ARM处理器配合使用,并提供合理的性能优势。
在这里插入图片描述

6.7 SSD中DRAM容量的影响

为了评估SSD中DRAM容量对IceClave性能的影响,我们将SSD中的DRAM大小从4GB降低到2GB,同时使用与表3中描述的相同配置。我们在图16中展示了实验结果。随着SSD中DRAM容量的减小,ISC的性能下降了12%至44%,因为它有限的内存空间无法存储其数据集。IceClave的性能也呈现相同的趋势。然而,与ISC相比,IceClave仍然引入了最小的性能开销。
在这里插入图片描述

6.8 多租户IceClave的性能

为了进一步评估IceClave的效率,我们同时运行多个IceClave实例,每个实例托管一个存储中工作负载,如表4所述。我们将应用程序性能与独立运行每个存储中应用程序而不与其他实例共存的情况进行比较。如图17所示,当我们将TPC-C实例与其他工作负载共存时,存储中应用程序的性能下降了6.1%至15.7%。当我们增加共存实例的数量时(参见图18),它们的性能平均下降了21.4%。这主要是由于(1)共存的IceClave实例之间的计算干扰,以及(2)受保护内存区域中缓存映射表的缓存未命中增加(高达8.7%)所导致的。然而,这些存储中程序仍然比受限于SSD外部I/O带宽的基于主机的方法表现更好。
在这里插入图片描述

7 相关工作

存储中计算。存储中计算近年来得到了广泛的发展。研究人员一直在探索将其应用于数据库查询[33, 34, 47, 52]、键值存储[72]、MapReduce工作负载[39, 47]、信号处理[19]和科学数据分析[81, 82]等领域。为了在现代SSD中实现存储中计算,这些前期工作开发了各种框架[39, 52, 66, 72]。然而,大多数工作关注的是可编程性和性能方面。尽管在这些方面仍有改进的空间,例如为存储中计算提供SSD阵列和文件系统支持[66],但我们必须克服存储中计算的安全挑战,以便广泛部署它,因为它对用户数据和闪存设备构成威胁。据我们所知,我们是第一个提出为存储中计算构建可信执行环境的。

可信执行环境。为了保护应用程序免受恶意系统软件的攻击,人们开发了可信硬件设备。一个典型的例子是Intel SGX [17],它可以为应用程序创建可信执行环境。由于启用了安全隔离,SGX被扩展或定制以支持各种计算平台[5, 11, 27, 53, 78]和应用程序[14, 50, 63, 70]。具有TPM [3]的硬件设备利用了AMD和Intel等商用处理器中的可验证性,以达到类似的目的[58, 59, 77]。对于常用于移动设备和存储控制器的ARM处理器,它们提供了TrustZone,可以在操作系统之外创建安全的隔离世界[42, 69]。不幸的是,这些硬件设备都不能直接应用于存储中计算。最近的工作ShieldStore [50]和Speicher [14]将SGX应用于键值存储,然而,它们都不能保护存储中程序的执行。我们为存储中应用程序开发了专门的可信执行环境。

存储加密和安全性。随着计算越来越接近存储设备中的数据,可信计算基础必然增加,这对用户数据构成安全威胁。为了在实现近数据计算的同时保护敏感用户数据,一种常见的方法是数据加密[64]。然而,由于现代SSD控制器缺乏可信执行环境的支持,数据泄露或丢失仍然可能发生在运行时。同时,攻击者还可以发起物理攻击来窃取/破坏用户数据。另一种方法是在加密数据上进行计算[29, 93]。然而,这种方法需要大量的计算资源,而由于有限的资源预算[15, 39, 56, 85],现代SSD控制器无法满足这种需求。我们的IceClave提供了一种轻量级的方法,可以为存储中应用程序提供安全隔离,并防御物理攻击。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/558201.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

WebLogic 数据源连接泄露

编码时,有时会忘记释放使用的数据源连接,造成连接泄露,没有连接资源可用。 现象 java.sql.SQLException: Cannot obtain XAConnectionat weblogic.jdbc.jta.DataSource.refreshXAConnAndEnlist(DataSource.java:1691)at weblogic.jdbc.jta.…

ssm062会员管理系统+jsp

会员管理系统 摘 要 随着科学技术的飞速发展,各行各业都在努力与现代先进技术接轨,通过科技手段提高自身的优势;对于会员管理系统当然也不能排除在外,随着网络技术的不断成熟,带动了会员管理系统,它彻底改…

Java项目引入log4j2

log4j2 单独使用 引入依赖 <dependencies><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-api</artifactId><version>2.14.0</version></dependency><dependency><groupId>o…

[管理者与领导者-174] :人际网络-1- 网络概述,是由一个个人组成的网络,每个节点是“人”

目录 一、数据通信网络 二、移动通信网络 三、人际网络 四、计算机网络与人际网络的比较 五、人际网络中节点-人的分层架构 5.1 人&#xff08;节点&#xff09;的分层架构&#xff1a;个体生理、个体心理、人际关系、社会功能 5.2 什么是人性 5.3 人性的特点 5.3 人性…

智能化新浪潮:国产智能体势在必行,一探究竟!

回顾之前的文章 GPTs大爆发&#xff1a;我的智能助手累计使用71k&#xff0c;荣登全球排名79&#xff0c;我们已经见证了智能助手的强劲增长势头。今天&#xff0c;我兴奋地分享一个新的里程碑&#xff1a;我的GPTs使用量已经突破10万次&#xff0c;排名再次提升&#xff01; 接…

盲人出行新助手:无障碍技术的进步

作为一名资深记者&#xff0c;我始终关注着社会弱势群体的生活权益&#xff0c;尤其是对于视障人士这一特殊群体。在科技日新月异的今天&#xff0c;我们欣喜地看到&#xff0c;盲人无障碍设施这一概念正在以更为先进、人性化的形式实现落地&#xff0c;其中&#xff0c;一款名…

与上级意见不合时如何恰当地表达自己的观点?

在工作中与上级意见不合时&#xff0c;恰当表达自己的观点并寻求共识是一个需要谨慎处理的问题。以下是一些建议&#xff1a; 1. **尊重与礼貌**&#xff1a;在任何情况下&#xff0c;都应保持对上级的尊重和礼貌。即使在意见不合时&#xff0c;也要避免情绪化&#xff0c;保持…

简单二分应用

思路&#xff1a;首先二分需要数列有二分性&#xff0c;我们要对数列排序&#xff0c;然后二分距离&#xff0c;直到出现一个距离可以满足&#xff0c;点数大于等于k。 代码&#xff1a; void solve(){int n, q;cin >> n >> q;vector<int>a(n);for(int i …

代码随想录:二叉树11-12

目录 222.完全二叉树的节点个数 题目 代码&#xff08;层序迭代&#xff09; 代码&#xff08;后序递归&#xff09; 代码&#xff08;满二次树递归&#xff09; 总结 110.平衡二叉树 题目 代码&#xff08;后序递归&#xff09; 代码&#xff08;层序迭代&#xff0…

设置表格高度后,数值改变但实际不变

1.选中表格 2.点击“开始”——>“段落设置”的选项启动按钮&#xff0c;设置为单倍行距 3.可以看到&#xff0c;表格的行高被调小了。

如何高效建立企业绩效评估体系?这家世界500强企业用BI工具这么做

在目前经济下行&#xff0c;竞争激烈&#xff0c;向精细化管理要效益的社会背景下&#xff0c;如何对资金结算部门做好绩效管理&#xff0c;以保障组织的正常运作&#xff0c;是各大企业面对的重要痛点。 本文将基于某世界500强公司的财务共享资金结算部门的绩效管理办法&…

河北专升本(c语言各种编程题)

目录 第一类、递归调用 第二类、特殊数字 第三类、多维数组 第四类、字符处理 第五类、数学问题 第六类、排序算法 第七类、循环问题 第八类、进制转换 第九类、实际应用 第十类、图形输出 第一类、递归调用 1.汉诺塔&#xff1a;请输入盘子数&#xff0c;输出盘子移动…

海外媒体如何发布软文通稿

大舍传媒-带您了解海外发布新潮流 随着全球化的不断深入&#xff0c;越来越多的中国企业开始关注海外市场。为了在国际舞台上树立品牌形象&#xff0c;企业纷纷寻求与海外媒体合作&#xff0c;通过发布软文通稿的方式&#xff0c;传递正面信息&#xff0c;提升品牌知名度。作为…

【4071】基于小程序实现的活动报名管理系统

作者主页&#xff1a;Java码库 主营内容&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app等设计与开发。 收藏点赞不迷路 关注作者有好处 文末获取源码 技术选型 【后端】&#xff1a;Java 【框架】&#xff1a;ssm 【…

抹机王的使用教程以及常见问题

首先请确保你已经正常安装了XPosed/EDXP/LSP框架并已激活抹机王模块&#xff0c;其中XP和EDXP模块均只需要框架内激活抹机王并重启即可&#xff0c;LSPosed注意作用域需要勾选上自己想要修改的APP&#xff08;如果你还是一意孤行只勾选系统框架那改机完全没用就是你自己的想法了…

设计模式之模板方法模式详解(下)

3&#xff09;钩子方法的使用 1.概述 钩子方法的引入使得子类可以控制父类的行为。 2.结构图 3.代码实现 将公共方法和框架代码放在抽象父类中 abstract class DataViewer {//抽象方法&#xff1a;获取数据public abstract void GetData();//具体方法&#xff1a;转换数据…

每日一题 — 最小覆盖子串

76. 最小覆盖子串 - 力扣&#xff08;LeetCode&#xff09; 解法一&#xff1a;暴力遍历哈希表 解法二&#xff1a;滑动窗口哈希表 定义left和right初始化为零&#xff0c;固定left&#xff0c;先向右遍历right&#xff0c;放到哈希表中这个时候我们需要统计有效字符的个数&…

深入挖掘C语言 ---- 文件操作

目录 1. 文件的打开和关闭1.1 流和标准流1.1.1流1.1.2标准流 1.2 文件指针1.3 文件的打开和关闭 2. 顺序读写3. 随机读写3.1 fseek3.2 ftell3.3 rewind 4. 读取结束判定 正文开始 1. 文件的打开和关闭 1.1 流和标准流 1.1.1流 我们程序的数据需要输出到各种外部设备, 也需要…

Leetcode算法训练日记 | day30

一、重新安排行程 1.题目 Leetcode&#xff1a;第 332 题 给你一份航线列表 tickets &#xff0c;其中 tickets[i] [fromi, toi] 表示飞机出发和降落的机场地点。请你对该行程进行重新规划排序。 所有这些机票都属于一个从 JFK&#xff08;肯尼迪国际机场&#xff09;出发…

java算法day2

螺旋矩阵搜索插入位置查找元素第一个位置和最后一个位置 螺旋矩阵 解法&#xff1a;模拟&#xff0c;核心在于你怎么转&#xff0c;还有就是处理边界&#xff0c;边界如何收缩&#xff0c;什么时候停止旋转。最内圈的时候怎么处理。 通过上图的模拟来解决这个问题&#xff1a;…
最新文章