高品质的音视频能力是怎样的? | Qcon 全球软件开发大会·上海站邀请函 了解详情
写点什么

Marshal.ReleaseComObject 存安全隐患

  • 2010-04-04
  • 本文字数:1247 字

    阅读完需:约 4 分钟

Visual Studio 团队版首席开发工程师 Paul Harrington 撰文指出,在调用 Marshal.ReleaseComObject() 方法处理来自托管代码的 COM 对象时,会产生安全隐患并建议大家不要使用该函数。 Harrington 使用 Marshal.ReleaseComObject 方法把 Visual2010 部分组件、Windows 管理器、命令行栏和文本编辑器由本地代码转换成托管代码时发现了该问题。 VS 2005 和 2008 已用本地代码编写这些组件,他们过去也能正常运行,直到把它们转换为托管代码时才出现问题。

在托管代码要使用 COM 功能时,它会通过

COM Interop 来完成。在调用 COM 对象的时候,CLR 返回封装在

运行时可调用封装器 (RCW) 中的对象,它服从托管对象规则和垃圾回收规则(GC)。这表示在 GC 决定要清理时,就会释放 RCW。如果应用程序使用的资源不多,那么 GC 可能很迟都不会进行清理工作,甚至要到应用程序关闭才会采取行动。在那段时间内,RCW 也许会占用一个待处理的庞大 COM 对象,如果应用程序关闭且 GC 还没运行的话,该漏洞就会存在风险。

要避免遗留未处理的 COM 对象,COM Interop 已提供 Marshal.ReleaseComObject 方法,它降低 RCW 引用计数器的使用次数,该计算器用于计算有多少客户调用该对象。该方法返回引用次数的新值,该值“在运行时可调用封装器对封装的 COM 对象仅剩一个引用时通常为零,而不管当前托管客户端正调用它的次数”。与此同时,COM 对象消耗的底层资源也因此释放。

这个机制在Visual Studio 之前的版本非常奏效,Visual Studio 可多次调用Marshal.ReleaseComObject。 但是某些控件被重写为托管代码时却发生变化。为了保持与其余代码的兼容性,新组件经由

COM 可调用封装器通过 Interop 层进行访问。所以,调用器会认为自己正处理本地 COM 对象,而事实上它正使用托管对象。一切运行正常,直到调用 Marshal.ReleaseComObject 函数,它最初是用于释放 COM 资源的。运行时会抛出 ArgumentException 异常,提示信息为“该对象的类型必须是 __ComObject 或继承至 __ComObject”。问题在于要释放的是 COM 对象而非托管对象。

使用 Marshal.ReleaseComObject 还会产生另一个问题。调用该方法后,一般会释放 COM 资源并通常返回零。那表示 COM 对象由 RCW 封装器释放。如果其它客户要调用同样的 COM 对象,他就会得到

InvalidComObjectException 异常,提示信息为“COM 对象已从底层 RCW 中分离,不能使用”,这是由于缓存的 RCW 对象未被垃圾回收。那么,程序员必须确保特定的 COM 对象对 Marshal.ReleaseComObject 的调用不再被使用。

要在 VS2010 团队版中解决该问题必须禁用 Marshal.ReleaseComObject。他们还为此编写了 VS2005 和 VS2008 的托管包的框架修订版,以便在加载 VS2010 的时候不再遇到 ReleaseComObject 的问题。在使用 VS 2010 出现问题的时候,你会看到这些修订版在 Microsoft.VisualStudio.Shell 和 Microsoft.VisualStudio.Shell.9.0. 中绑定 devenv.exe.config 文件,这也许会普遍出现在使用 COM Interop 对象的项目当中。

查看英文原文: Marshal.ReleaseComObject Is Considered Dangerous

2010-04-04 21:112729
用户头像

发布了 87 篇内容, 共 18.8 次阅读, 收获喜欢 1 次。

关注

评论

发布
暂无评论
发现更多内容

要想软件“一想之美”,UI测试少不了

华为云开发者联盟

软件 测试 华为云

volatile 关键字精讲

伯阳

Java volatile 后端 关键字 多线程与高并发

开始的开始-可能是最早提交的28天写作活动作品

石君

28天写作

如何使用Eclipse内存分析工具定位内存泄露

AI乔治

Java eclipse 架构

【CSS】CSS对大小写敏感吗?

德育处主任

28天写作

文档驱动开发模式在 AIMS 中的应用与实践

华为云开发者联盟

Web 代码 API 文档

Java中定时器Timer致命缺点(附学习方法)

叫练

学习 定时任务 多线程 定时器 技术学习

甲方日常 82

句子

随笔杂谈

俯瞰Dubbo全局,阅读源码前必须掌握这些!!

冰河

架构 分布式 微服务 dubbo 服务治理

LeetCode题解:111. 二叉树的最小深度,BFS,JavaScript,详细注释

Lee Chen

算法 大前端 LeetCode

还在手动写数据库文档吗?试试这个工具,划水干活儿两不误!

我爱娃哈哈😍

数据库 文档生成

杜绝标题党,好的标题是成功的99%

xcbeyond

方法论 28天写作 写作技巧

代码也能“杀”虫:此虫,真虫非Bug也

华为云开发者联盟

代码 华为云 modelarts

一次系统调用时间过长追踪完整教程案例

AI乔治

Java Linux 架构

不愧是Alibaba技术官:程序员必会的架构知识清单,如何让你技术上的提升面试时的丰收

Java架构之路

Java 程序员 架构 面试 编程语言

甲方日常 81

句子

随笔杂谈

如何使用Eclipse内存分析工具定位内存泄露

Java老k

Java 内存泄露

如果你听说过 Elastic Certified Engineer

escray

七日更 28天写作 死磕Elasticsearch 60天通过Elastic认证考试

Spark HistoryServer日志解析&清理异常

笨小康

大数据 spark hdfs

Hive的调优你都知道那些?

大数据老哥

大数据 hadoop hive

【Mysql-InnoDB系列】InnoDB架构

程序员架构进阶

MySQL 架构 innodb 28天写作

从七日更,到28天写作挑战,我无法拒绝的原因

梁龙先森

大前端 编程语言 28天写作

VUE项目性能优化实践——通过懒加载提升页面响应速度

葡萄城技术团队

Vue

边缘计算安全技术研究

华为云原生团队

云计算 大数据 云原生 边缘计算 华为云

ETL都没弄懂,谈什么大数据 ?我用一分钟给你整明白

智分析

ETL

新思科技网络安全研究中心发现Bouncy Castle中的漏洞

InfoQ_434670063458

新思科技 Bouncy Castle

CSS09 - 文本&背景属性

Mr.Cactus

html/css

云算力矿机租赁挖矿APP系统开发|云算力矿机租赁挖矿软件开发

系统开发

一个正确的编程思维

程序员吴师兄

28天写作

价值 - 价值的底色(一)

石云升

读书笔记 投资 28天写作 价值

数据中心“容灾”和“备份”的区别

Marshal.ReleaseComObject存安全隐患_.NET_Abel Avram_InfoQ精选文章