漏洞分析。

Patch分析

公告中强调的ResultIterator是漏洞分析的切入点,首先回顾这个迭代器的相关逻辑:

#[derive(Debug)]
-   pub struct ResultIterator<'a>(pub *mut _CassIterator, usize, PhantomData<&'a CassResult>);
+   pub struct ResultIterator<'a>(*mut _CassIterator, usize, PhantomData<&'a _CassResult>);

-   // The underlying C type has no thread-local state, but does not support access
-   // from multiple threads: https://datastax.github.io/cpp-driver/topics/#thread-safety
-   unsafe impl<'a> Send for ResultIterator<'a> {}
+   // The underlying C type has no thread-local state, and forbids only concurrent
+   // mutation/free: https://datastax.github.io/cpp-driver/topics/#thread-safety
+   unsafe impl Send for ResultIterator<'_> {}
+   unsafe impl Sync for ResultIterator<'_> {}

    impl<'a> Drop for ResultIterator<'a> {
        fn drop(&mut self) {
            unsafe { cass_iterator_free(self.0) }
        }
    }

-   impl<'a> Iterator for ResultIterator<'a> {
-       type Item = Row<'a>;
-       fn next(&mut self) -> Option<<Self as Iterator>::Item> {
+   impl LendingIterator for ResultIterator<'_> {
+       type Item<'a> = Row<'a> where Self: 'a;
+
+       fn next(&mut self) -> Option<<Self as LendingIterator>::Item<'_>> {
            unsafe {
                match cass_iterator_next(self.0) {
                    cass_false => None,
                    cass_true => Some(self.get_row()),
                }
            }
        }
        fn size_hint(&self) -> (usize, Option<usize>) {
            (0, Some(self.1))
        }
    }
-   impl<'a> ResultIterator<'a> {
-       /// Gets the next row in the result set
-       pub fn get_row(&mut self) -> Row<'a> {
+   impl ResultIterator<'_> {
+       /// Gets the current row in the result set
+       pub fn get_row(&self) -> Row {
            unsafe { Row::build(cass_iterator_get_row(self.0)) }
    }
}

重点关注其中的next函数,我们会发现,代码修改前后都声明了Row对象和这个ResultIterator的生命周期,同时next函数功能为调用ResultIterator迭代器中实现的get_row函数。

这边的LendingIterator为库自身实现的一个接口,本质上和原先Iterator写法类似,所以这里只是省略了没写,但是也是一样声明了生命周期,后面会提及

这个get_row函数调用的函数cass_iterator_get_row为一个CPP实现的函数,其细节如下

const CassRow* cass_iterator_get_row(const CassIterator* iterator) {
  if (iterator->type() != CASS_ITERATOR_TYPE_RESULT) {
    return NULL;
  }
  return CassRow::to(static_cast<const ResultIterator*>(iterator->from())->row());
}

这里的ResultIterator是一个表示迭代器的类,其实现如下

class ResultIterator : public Iterator {
public:
  ResultIterator(const ResultResponse* result)
      : Iterator(CASS_ITERATOR_TYPE_RESULT)
      , result_(result)
      , index_(-1)
      , row_(result) {
    decoder_ = (const_cast<ResultResponse*>(result))->row_decoder();
    row_.values.reserve(result->column_count());
  }

  virtual bool next() {
    // skip code
  }

  const Row* row() const {
    assert(index_ >= 0 && index_ < result_->row_count());
    if (index_ > 0) {
      return &row_;
    } else {
      return &result_->first_row();
    }
  }
  private:
  const ResultResponse* result_;
  Decoder decoder_;
  int32_t index_;
  Row row_;
};

这里可以看到ResultIterator对象中,存放了一个叫做Row的对象,这个对象被创建的时候,对应的row_对象也会被初始化,并且在名为row的函数中,会根据当前的row_count返回不同的指针。那么在这里我们可以得出第一条结论

ResultIterator 和 Row 处在同一片内存空间中,当 ResultIterator 被销毁的时候,Row也将被销毁

接下来,确认这个ResultIterator在程序中是如何创建和使用的:

impl CassResult {
    /// Gets the number of rows for the specified result.
    // ...

    /// Creates a new iterator for the specified result. This can be
    /// used to iterate over rows in the result.
    pub fn iter(&self) -> ResultIterator {
        unsafe {
            ResultIterator(
                cass_iterator_from_result(self.0),
                cass_result_row_count(self.0),
                PhantomData,
            )
        }
    }
}

 

可以看到,迭代器对象由CassResult对象创建,这里的CaseResult对象指针正是前面ResultIterator对象创建时使用的指针:

ResultIterator(const ResultResponse* result)
      : Iterator(CASS_ITERATOR_TYPE_RESULT)
      , result_(result)         // CaseResult pointer
      , index_(-1)
      , row_(result)            // CaseResult pointer

于是,这里能得到第二个结论

CaseResult 的裸指针 传递给了 ResultIterator,并且ResultIterator中会使用 result_ 来操作对象

那么这里就能看到第一个问题:当 CaseResult 在 ResultIterator 销毁前被销毁,ResultIterator使用next的时候就将访问一个未初始化的内存。。。吗?尝试编写一个这样的poc

{
    let result = get_result();
    tmp_iter = result.iter();
}
println!("Using tmp iter here {:?}", tmp_iter);

很容易就会发现编译器报错,说明rust编译器会检查这种问题。这要归功于 ResultIterator 声明的 PhantomData字段:

#[derive(Debug)]
-   pub struct ResultIterator<'a>(pub *mut _CassIterator, usize, PhantomData<&'a CassResult>);
+   pub struct ResultIterator<'a>(*mut _CassIterator, usize, PhantomData<&'a _CassResult>);

可以看到,无论修改前还是修改后,PhantomData逻辑都是保留的,所以ResultIterator的生命周期始终和CassREsult保持同步,保护始终生效。换句话说,这个想法并非为当前报告中提及的漏洞点。

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

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

相关文章

Nodejs -- 流程控制库

流程控制库 尾触发和next 尾触发最多的应用是在Connect的中间件 var app connect() app.use(connect.staticCache()) app.use(connect.static(__dirname /public)) app.use(conect.cokkieParser()) app.use(connect.session()) app.use(connect.query()) app.use(connect.…

跨平台终端软件——quardCRT

作为一个技术栈比较复杂的程序&#xff0c;工作常常会在windows/linux/macos等不同的平台切换开发&#xff0c;开发过程中最常用的就是终端工具了&#xff0c;一个趁手的终端可以成倍的提高工作效率&#xff0c;因此我一直希望能找个一个跨平台体验一致无缝切换的终端软件&…

Unity Audio Filter 入门

概述&#xff1a; 如果你在你项目中需要一些特殊的声音效果&#xff0c;那这部分声音过滤器的部分一定不要错过喔&#xff0c;让我们来学习这部分的内容吧&#xff01; 这部分理论性比较强&#xff0c;认真看我的注解哈&#xff0c;我尽量解释的易懂一点。 Audio Chorus Filter…

街道征迁项目档案管理系统

街道征迁项目档案管理系统是一个用于管理街道征迁项目档案的软件系统。该系统的主要功能包括档案录入、档案存储、档案检索、档案共享等。 系统的用户可以通过该系统录入征迁项目相关的档案信息&#xff0c;包括项目名称、征迁范围、土地面积、征迁补偿费用等。同时&#xff0c…

vue本地调试devtools

一、谷歌浏览器加载扩展程序 二、把解压的压缩包添加即可&#xff0c;重启浏览器 三、启动前端本地项目&#xff0c;即可看到Vue小图标

AD | Altium Designer(原理图设计、电路仿真、PCB绘图)汉化版

Altium Designer(原理图设计、电路仿真、PCB绘图) 通知公告 Altium Designer(AD)是一种功能强大的电子设计自动化(EDA)软件。它主要用于设计和开发电子产品,如电路板(PCB)、集成电路(IC)和嵌入式系统。AD提供了完整的设计工具套件,包括原理图设计、PCB布局、仿真、设…

ICode国际青少年编程竞赛- Python-1级训练场-识别循环规律1

ICode国际青少年编程竞赛- Python-1级训练场-识别循环规律1 1、 for i in range(4):Dev.step(6)Dev.turnLeft()2、 for i in range(3):Dev.turnLeft()Dev.step(2)Dev.turnRight()Dev.step(2)3、 for i in range(3):Spaceship.step(5)Spaceship.turnLeft()Spaceship.step(…

互联网轻量级框架整合之MyBatis底层运转逻辑

MyBatis运转过程中主要步骤有两个&#xff0c;其一读取配置文件缓存到Configuration对象&#xff0c;用于构建SqlSessionFactory&#xff1b;其二是SqlSession的执行过程&#xff0c;这其中SqlSessionFactory的构建过程相对很好理解&#xff0c;而SqlSession的执行过程就相对复…

LT6911GX HDMI2.1 至四端口 MIPI/LVDS,带音频 龙迅方案

1. 描述LT6911GX 是一款面向 VR / 显示应用的高性能 HDMI2.1 至 MIPI 或 LVDS 芯片。HDCP RX作为HDCP中继器的上游&#xff0c;可以与其他芯片的HDCP TX配合使用&#xff0c;实现中继器功能。对于 HDMI2.1 输入&#xff0c;LT6911GX 可配置为 3/4 通道。自适应均衡功能使其适合…

vue3+vite+js 实现移动端,PC端响应式布局

目前使用的是vue3vite&#xff0c;没有使用ts 纯移动端|PC端 这种适用于只适用一个端的情况 方法&#xff1a;amfe-flexible postcss-pxtorem相结合 ① 执行以下两个命令 npm i -S amfe-flexible npm install postcss-pxtorem --save-dev② main.js文件引用 import amfe-f…

FreeRTOS信号量

信号量简介 def 1&#xff1a; 信号量是一种解决问题的机制&#xff0c;可以实现共享资源的访问 信号量浅显理解例子&#xff1a; 空车位&#xff1a; 信号量资源&#xff08;计数值&#xff09; 让出占用车位&#xff1a; 释放信号量&#xff08;计数值&#xff09; 占用车…

LT6911UXB HDMI2.0 至四端口 MIPI DSI/CSI,带音频 龙迅方案

1. 描述LT6911UXB 是一款高性能 HDMI2.0 至 MIPI DSI/CSI 转换器&#xff0c;适用于 VR、智能手机和显示应用。HDMI2.0 输入支持高达 6Gbps 的数据速率&#xff0c;可为4k60Hz视频提供足够的带宽。此外&#xff0c;数据解密还支持 HDCP2.2。对于 MIPI DSI / CSI 输出&#xff0…

jvm 马士兵 01

01.JVM是什么 JVM是一个跨平台的标准 JVM只识别class文件&#xff0c;符合JVM规范的class文件都可以被识别

知乎广告开户流程,知乎广告的优势是什么?

社交媒体平台不仅是用户获取知识、分享见解的场所&#xff0c;更是品牌展示、产品推广的重要舞台。知乎作为国内知名的知识分享社区&#xff0c;以其高质量的内容生态和庞大的用户基础&#xff0c;成为了众多企业进行广告投放的优选之地。云衔科技通过其专业服务&#xff0c;助…

数字身份管理:Facebook如何利用区块链技术?

随着数字化进程的加速&#xff0c;个人身份管理已成为一个关键议题。在这方面&#xff0c;区块链技术正在逐渐展现其巨大潜力。作为全球最大的社交媒体平台&#xff0c;Facebook也在积极探索和应用区块链技术来改进其数字身份管理系统。本文将深入探讨Facebook如何利用区块链技…

<Linux> 权限

目录 权限人员相对于文件来说的分类更改权限文件的拥有者与所属组 权限 权限是操作系统用来限制对资源访问的机制&#xff0c;权限一般分为读、写、执行。系统中的每个文件都拥有特定的权限、所属用户及所属组&#xff0c;通过这样的机制来限制哪些用户、哪些组可以对特定文件…

Node私库Verdaccio使用记录,包的构建,推送和拉取

Node私库Verdaccio使用记录&#xff0c;包的构建&#xff0c;推送和拉取 Verdaccio是一个轻量级的私有npm代理注册中心&#xff0c;它可以帮助你在本地搭建一个npm仓库&#xff0c;非常适合企业内部使用。通过使用Verdaccio&#xff0c;你可以控制和缓存依赖包&#xff0c;提高…

政安晨:【Keras机器学习示例演绎】(二十七)—— 利用 NNCLR 进行自我监督对比学习

目录 简介 自我监督学习 对比学习 NNCLR 设置 超参数 加载数据集 增强 准备扩增模块 编码器结构 用于对比预训练的 NNCLR 模型 预训练 NNCLR 政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 收录专栏: TensorFlow与Keras机器学习实战 希望…

DRF限流组件源码分析

DRF限流组件源码分析 开发过程中&#xff0c;如果某个接口不想让用户访问过于频繁&#xff0c;可以使用限流的机制 限流&#xff0c;限制用户访问频率&#xff0c;例如&#xff1a;用户1分钟最多访问100次 或者 短信验证码一天每天可以发送50次&#xff0c; 防止盗刷。 对于…

Spring - 7 ( 13000 字 Spring 入门级教程 )

一&#xff1a;Spring Boot 日志 1.1 日志概述 日志对我们来说并不陌生&#xff0c;我们可以通过打印日志来发现和定位问题, 或者根据日志来分析程序的运行过程&#xff0c;但随着项目的复杂度提升, 我们对日志的打印也有了更高的需求, 而不仅仅是定位排查问题 比如有时需要…