关于影子变量 【ChatGPT】

简介: 关于影子变量 【ChatGPT】

关于影子变量

影子变量是一种简单的方法,用于让 livepatch 模块将额外的“影子”数据与现有数据结构关联起来。影子数据是单独分配的,而父数据结构保持不变。本文档描述的影子变量 API 用于为它们的父对象分配/添加和移除/释放影子变量。

该实现引入了一个全局的内核哈希表,将父对象的指针和影子数据的数值标识符关联起来。数值标识符是一个简单的枚举,可用于描述影子变量的版本、类别或类型等。具体来说,父指针充当哈希表键,而数值标识符随后用于过滤哈希表查询。多个影子变量可以附加到同一个父对象上,但它们的数值标识符可以区分它们。

1. 简要 API 摘要

(请参阅 livepatch/shadow.c 中的完整 API 使用文档注释。)

一个哈希表引用了所有影子变量。这些引用通过 <obj, id> 对存储和检索。

  • klp_shadow 变量数据结构封装了跟踪元数据和影子数据:
  • 元数据
  • obj - 指向父对象的指针
  • id - 数据标识符
  • data[] - 用于存储影子数据

需要注意的是,klp_shadow_alloc() 和 klp_shadow_get_or_alloc() 默认会将变量清零。它们还允许在需要非零值时调用自定义构造函数。调用者应提供所需的互斥操作。

需要注意的是,构造函数是在 klp_shadow_lock 自旋锁下调用的。这允许执行只能在分配新变量时执行一次的操作。

  • klp_shadow_get() - 检索影子变量数据指针 - 在哈希表中搜索 <obj, id> 对
  • klp_shadow_alloc() - 分配并添加新的影子变量 - 在哈希表中搜索 <obj, id> 对
  • 如果存在
  • 发出警告并返回 NULL
  • 如果 <obj, id> 不存在
  • 分配一个新的影子变量
  • 使用自定义构造函数和数据初始化变量(如果提供)
  • 将 <obj, id> 添加到全局哈希表中
  • klp_shadow_get_or_alloc() - 获取现有或分配新的影子变量 - 在哈希表中搜索 <obj, id> 对
  • 如果存在
  • 返回现有的影子变量
  • 如果 <obj, id> 不存在
  • 分配一个新的影子变量
  • 使用自定义构造函数和数据初始化变量(如果提供)
  • 将 <obj, id> 对添加到全局哈希表中
  • klp_shadow_free() - 分离并释放 <obj, id> 影子变量 - 从全局哈希表中查找并移除 <obj, id> 引用
  • 如果找到
  • 如果已定义,调用析构函数
  • 释放影子变量
  • klp_shadow_free_all() - 分离并释放所有 <, id> 影子变量 - 从全局哈希表中查找并移除任何 <, id> 引用
  • 如果找到
  • 如果已定义,调用析构函数
  • 释放影子变量

2. 使用案例

(请参阅 samples/livepatch/ 中的示例影子变量 livepatch 模块,以获取完整的工作演示。)

对于以下使用案例示例,请考虑提交 1d147bfa6429("mac80211: fix AP powersave TX vs. wakeup race"),该提交在 net/mac80211/sta_info.h :: struct sta_info 中添加了一个自旋锁。每个使用案例示例都可以视为此修复的独立 livepatch 实现。

匹配父对象的生命周期

如果父数据结构经常被创建和销毁,将它们的影子变量生命周期与相同的分配和释放函数对齐可能是最简单的方法。在这种情况下,通常会分配、初始化父数据结构,然后以某种方式注册它们。影子变量的分配和设置可以被视为父对象的初始化的一部分,并且应在父对象“上线”之前完成(即,为此 <obj, id> 对进行任何影子变量 get-API 请求)。

对于提交 1d147bfa6429,当分配父 sta_info 结构时,分配 ps_lock 指针的影子副本,然后对其进行初始化:

#define PS_LOCK 1
struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
const u8 *addr, gfp_t gfp)
{
struct sta_info *sta;
spinlock_t *ps_lock;
/* 创建父结构 */
      sta = kzalloc(sizeof(*sta) + hw->sta_data_size, gfp);
/* 附加相应的影子变量,然后对其进行初始化 */
      ps_lock = klp_shadow_alloc(sta, PS_LOCK, sizeof(*ps_lock), gfp,
NULL, NULL);
if (!ps_lock)
goto shadow_fail;
      spin_lock_init(ps_lock);
      ...

在需要 ps_lock 时,查询影子变量 API 以检索特定 struct sta_info 的一个:

void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
{
spinlock_t *ps_lock;
/* 与 ieee80211_tx_h_unicast_ps_buf 同步 */
      ps_lock = klp_shadow_get(sta, PS_LOCK);
if (ps_lock)
              spin_lock(ps_lock);
      ...

当父 sta_info 结构被释放时,首先释放影子变量:

void sta_info_free(struct ieee80211_local *local, struct sta_info *sta)
{
      klp_shadow_free(sta, PS_LOCK, NULL);
      kfree(sta);
      ...

运行中的父对象

有时,可能不方便或不可能在运行中的父对象旁边分配影子变量。或者 livepatch 修复可能仅需要对父对象实例的子集使用影子变量。在这些情况下,可以使用 klp_shadow_get_or_alloc() 调用将影子变量附加到已在运行中的父对象上。

对于提交 1d147bfa6429,一个很好的分配影子自旋锁的位置是在 ieee80211_sta_ps_deliver_wakeup() 内部:

int ps_lock_shadow_ctor(void *obj, void *shadow_data, void *ctor_data)
{
spinlock_t *lock = shadow_data;
      spin_lock_init(lock);
return 0;
}
#define PS_LOCK 1
void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
{
spinlock_t *ps_lock;
/* 与 ieee80211_tx_h_unicast_ps_buf 同步 */
      ps_lock = klp_shadow_get_or_alloc(sta, PS_LOCK,
sizeof(*ps_lock), GFP_ATOMIC,
                      ps_lock_shadow_ctor, NULL);
if (ps_lock)
              spin_lock(ps_lock);
      ...

这种用法将仅在需要时创建一个影子变量,否则将使用已为此 <obj, id> 对创建的变量。

与之前的使用案例类似,影子自旋锁需要进行清理。影子变量可以在其父对象被释放之前释放,或者甚至在不再需要影子变量本身时释放。

其他使用案例

影子变量还可以用作指示数据结构是由新的、经过 livepatch 的代码分配的标志。在这种情况下,影子变量持有的数据值并不重要,其存在表明如何处理父对象。

3. 参考资料

  • livepatch 实现基于 kpatch 版本的影子变量。
  • Kritis Makris, Kyung Dong Ryu 于 2007 年提出了一种称为“影子数据结构”的数据类型更新技术。
相关文章
|
3月前
|
人工智能 安全 测试技术
当奖励成为漏洞:从对齐本质出发自动越狱大语言模型
【9月更文挑战第26天】在人工智能领域,大型语言模型(LLMs)的广泛应用引发了对其安全性和可靠性的担忧,特别是在面对对抗攻击时的脆弱性。论文《Jailbreaking as a Reward Misspecification Problem》提出将这种脆弱性归因于对齐过程中的奖励误设,并引入ReGap指标来量化这一问题。基于此,研究人员开发了ReMiss系统,用于自动对抗各种目标对齐的LLMs,并在AdvBench基准测试中取得了领先成果。尽管方法存在局限性,但该论文为提升LLMs安全性提供了新方向。[论文链接:https://arxiv.org/pdf/2406.14393]
47 4
|
3月前
|
安全
原子替换和累积补丁 【ChatGPT】
原子替换和累积补丁 【ChatGPT】
|
5月前
|
人工智能
Sora信息问题之模拟对象状态变化存在的局限如何解决
Sora信息问题之模拟对象状态变化存在的局限如何解决
45 0
|
6月前
|
机器学习/深度学习 算法 计算机视觉
完全让ChatGPT写一个风格迁移的例子,不改动任何代码
完全让ChatGPT写一个风格迁移的例子,不改动任何代码
58 1
|
PHP 开发者
很多人觉得正则表达式中的【反向引用】这个概念很难, 其实特别简单 一个案例就明白了,没你想的那么高大上!
一个案例让你明白正则表达式中的【反向引用】,其实没有你想得那么难!
103 1
很多人觉得正则表达式中的【反向引用】这个概念很难, 其实特别简单 一个案例就明白了,没你想的那么高大上!
|
机器学习/深度学习 存储 人工智能
【网安AIGC专题11.8】论文15 ChatGPT在软件工程中的全面作用:程序语法(AST生成、表达式匹配) 静态行为、动态分析(数据依赖和污点分析、指针分析) 提示设计(角色提示、指令提示)
【网安AIGC专题11.8】论文15 ChatGPT在软件工程中的全面作用:程序语法(AST生成、表达式匹配) 静态行为、动态分析(数据依赖和污点分析、指针分析) 提示设计(角色提示、指令提示)
124 0
|
机器学习/深度学习 自然语言处理 安全
【网安AIGC专题10.11】论文1:生成式模型GPT\CodeX填充式模型CodeT5\INCODER+大模型自动程序修复(生成整个修复函数、修复代码填充、单行代码生产、生成的修复代码排序和过滤)
【网安AIGC专题10.11】论文1:生成式模型GPT\CodeX填充式模型CodeT5\INCODER+大模型自动程序修复(生成整个修复函数、修复代码填充、单行代码生产、生成的修复代码排序和过滤)
198 0
|
人工智能 JSON API
Prompt learning 教学技巧篇:通过增加示例、引导词、特殊符号指令等方式让chatgpt输出更好的答案
Prompt learning 教学技巧篇:通过增加示例、引导词、特殊符号指令等方式让chatgpt输出更好的答案
ChatGPT的引申想法及其功能全介绍
ChatGPT的引申想法及其功能全介绍
|
缓存 Java 编译器
Java包装类、方法传参机制都有什么值得注意的?来自《卷Ⅰ》的灵魂提问(一)
Java包装类、方法传参机制都有什么值得注意的?来自《卷Ⅰ》的灵魂提问(一)
211 0
Java包装类、方法传参机制都有什么值得注意的?来自《卷Ⅰ》的灵魂提问(一)