当前位置:  开发笔记 > 后端 > 正文

您是否使用TR 24731'安全'功能?

如何解决《您是否使用TR24731'安全'功能?》经验,为你挑选了5个好方法。

ISO C委员会(ISO/IEC JTC1/SC21/WG14)已发布TR 24731-1,正在研究TR 24731-2:

TR 24731-1:C库的扩展第一部分:边界检查接口

WG14正在研究更安全的C库函数.该TR旨在通过添加具有缓冲区长度的额外参数来修改现有程序.最新草案见N1225号文件.理由是在N1173号文件中.这将成为技术报告类型2.

TR 24731-2:C库的扩展 - 第二部分:动态分配功能

WG14正在研究更安全的C库函数.该TR面向使用动态分配而不是缓冲区长度的额外参数的新程序.最新草案见N1337号文件.这将成为技术报告类型2.

问题

您是否使用支持TR24731-1功能的库或编译器?

如果是这样,哪个编译器或库以及哪个平台?

您是否因修复代码以使用这些功能而发现任何错误?

哪些功能提供最大价值?

有没有提供任何价值或负值?

你打算将来使用这个图书馆吗?

您是否正在跟踪TR24731-2的工作?

Robert Gambl.. 65

自从它们诞生之初(当它是一个TR)时,我一直是这些TR的声音批评者,并且永远不会在我的任何软件中使用它们.它们掩盖症状而不是解决原因,我认为,如果有的话,它们会对软件设计产生负面影响,因为它们提供了错误的安全感,而不是促进可以更有效地实现相同目标的现有实践.我并不孤单,事实上我并不知道在委员会之外开发这些TR的一个主要支持者.

我使用glibc并因此知道我将不得不处理这些废话,因为glibc的主要维护者Ulrich Drepper 谈到了这个主题:

建议的安全(r)ISO C库无法完全解决问题.......提议让程序员的生活更加艰难并不会有所帮助.但这正是提出的建议.......他们都需要做更多的工作或者只是愚蠢的.

他接着详细介绍了一些拟议函数的问题,并在其他地方表示glibc永远不会支持这一点.

奥斯汀集团(负责维护POSIX)对TR提供了非常严格的审查,他们的评论和委员会的回复在这里提供.奥斯汀集团的审查工作非常好,详细说明了TR的许多问题,所以我不会在这里详细介绍个别细节.

所以底线是:我没有使用支持或支持这个的实现,我不打算永远使用这些功能,我看不到TR中的正面价值.我个人认为,TR仍然以任何形式存在的唯一原因是因为它受到了微软的推动,最近证明尽管标准委员会仍有广泛的反对意见,但它已经证明能够让事情陷入困境.如果这些功能被标准化,我认为它们不会被广泛使用,因为该提案已经存在了几年,并且未能获得任何真正的社区支持.



1> Robert Gambl..:

自从它们诞生之初(当它是一个TR)时,我一直是这些TR的声音批评者,并且永远不会在我的任何软件中使用它们.它们掩盖症状而不是解决原因,我认为,如果有的话,它们会对软件设计产生负面影响,因为它们提供了错误的安全感,而不是促进可以更有效地实现相同目标的现有实践.我并不孤单,事实上我并不知道在委员会之外开发这些TR的一个主要支持者.

我使用glibc并因此知道我将不得不处理这些废话,因为glibc的主要维护者Ulrich Drepper 谈到了这个主题:

建议的安全(r)ISO C库无法完全解决问题.......提议让程序员的生活更加艰难并不会有所帮助.但这正是提出的建议.......他们都需要做更多的工作或者只是愚蠢的.

他接着详细介绍了一些拟议函数的问题,并在其他地方表示glibc永远不会支持这一点.

奥斯汀集团(负责维护POSIX)对TR提供了非常严格的审查,他们的评论和委员会的回复在这里提供.奥斯汀集团的审查工作非常好,详细说明了TR的许多问题,所以我不会在这里详细介绍个别细节.

所以底线是:我没有使用支持或支持这个的实现,我不打算永远使用这些功能,我看不到TR中的正面价值.我个人认为,TR仍然以任何形式存在的唯一原因是因为它受到了微软的推动,最近证明尽管标准委员会仍有广泛的反对意见,但它已经证明能够让事情陷入困境.如果这些功能被标准化,我认为它们不会被广泛使用,因为该提案已经存在了几年,并且未能获得任何真正的社区支持.


@Pavel,我引用Drepper作为glibc*的权威*.尽管你可能与他有任何个人问题,但他是glibc的主要维护者,并且几乎决定了glibc中将包含哪些内容,哪些内容不会包括在内.我根本没有利用我对TR的观点,你的评论似乎是基于对一个人的强烈个人敌意,如果这使你无法看到更大的情况,那就是你应该工作的错上.
引用Ulrich Drepper的观点作为任何形式的权威都是一种很好的方式,可以当场击落你的论点,无论其他任何赎回情况如何.
^^^使用知道如何正确编程的程序员会停止所有这些...
+1.那些不知道自己在做什么的人应该使用VB,而不是C :-)
对于胜利:[多个libupnp缓冲区溢出](http://www.kb.cert.org/vuls/id/922681).那些你不喜欢的更安全的功能会阻止它们中的大多数.兜售糟糕建议的好工作:)
我在一家大公司(> 60,000名员工,主要是工程师)工作,现在使用这个库是所有新代码的标准要求.我同意它为不知情的人提供了一种虚假的安全感,但是一点额外的安全性比没有更好.

2> Jonathan Lef..:

直接回答问题

我喜欢罗伯特的答案,但我也对我提出的问题有一些看法.

您是否使用支持TR24731-1功能的库或编译器?

不,我没有.

如果是这样,哪个编译器或库以及哪个平台?

我相信这些功能是由MS Visual Studio(例如MS VC++ 2008 Edition)提供的,并且有警告鼓励您使用它们.

您是否因修复代码以使用这些功能而发现任何错误?

还没.而且我不希望在我的代码中发现许多内容.我使用的其他一些代码 - 也许吧.但我还没有被说服.

哪些功能提供最大价值?

我喜欢printf_s()系列函数不接受' %n'格式说明符的事实.

有没有提供任何价值或负值?

这些tmpfile_s()tmpnam_s()功能令人非常失望.他们真的需要工作更像mkstemp()是创建文件并打开它以确保没有TOCTOU(检查时间,使用时间)漏洞.就目前而言,这两者提供的价值非常小.

我也认为这strerrorlen_s()提供的价值非常小.

你打算将来使用这个图书馆吗?

我有两种想法.我开始研究一个库,该库可以在标准C库上实现TR 24731的功能,但是由于证明它正常工作所需的单元测试数量而被抓住了.我不确定是否继续这样做.我有一些代码,我想移植到Windows(主要是出于在所有平台上提供支持的反常愿望 - 它已经在Unix衍生品上工作了几十年).不幸的是,为了让它在没有来自MSVC编译器的警告的情况下进行编译,我必须使用完全可靠(当仔细使用时)标准C库函数来防止MSVC对我产生干扰.这并不开胃.很糟糕的是,我必须处理在这段时间内发展起来的大部分二十年的系统; 不得不处理某人的乐趣想法(让人们在不需要时采用TR 24731)很烦人.这就是我开始进行库开发的原因 - 允许我在Unix和Windows上使用相同的接口.但我不确定我会从这里做些什么.

您是否正在跟踪TR24731-2的工作?

在收集问题数据之前我去标准网站之前我没有跟踪它.这些asprintf()vasprintf()功能可能很有价值; 我会用那些.我不确定内存流I/O功能.在strdup()C级标准化将是向前迈出的一大步.对于我来说,这似乎比第1部分(边界检查)接口更少争议.

总的来说,我不相信第1部分"Bounds-Checking Interfaces".第2部分"动态分配函数"草案中的材料更好.

如果由我决定,我会稍微沿着第1部分的方向移动,但我还修改了C99标准C库中的接口,它返回char *到字符串的开头(例如strcpy()strcat()),而不是返回指向开头的指针,它们将返回指向新字符串末尾的空字节的指针.这会使一些常见的习语(例如重复地将字符串连接到另一个字符串的末尾)更有效,因为它会使得避免重复使用的代码所呈现的二次行为变得微不足道strcat().替换将确保输出字符串的空终止,如TR24731版本.我并不完全反对检查接口的概念,也不反对异常处理函数.这是一项棘手的业务.


Microsoft的实现与标准规范不同

更新(2011-05-08)

另见这个问题.遗憾的是,对于TR24731函数的有用性而言,有些函数的定义在Microsoft实现和标准之间有所不同,使得它们对我来说毫无用处.我的答案引用了vsnprintf_s().

例如,TR 24731-1表示接口vsnprintf_s()是:

#define __STDC_WANT_LIB_EXT1__ 1
#include 
#include 
int vsnprintf_s(char * restrict s, rsize_t n,
                const char * restrict format, va_list arg);

不幸的是,MSDN说接口vsnprintf_s()是:

int vsnprintf_s(
   char *buffer,
   size_t sizeOfBuffer,
   size_t count,
   const char *format,
   va_list argptr 
);

参数

buffer - 输出的存储位置.

sizeOfBuffer - 输出缓冲区的大小.

count - 要写入的最大字符数(不包括终止空值)或_TRUNCATE.

格式 - 格式规范.

argptr - 指向参数列表的指针.

请注意,这不仅仅是类型映射的问题:固定参数的数量是不同的,因此是不可调和的.我也不清楚(也可能是标准委员会)对'sizeOfBuffer'和'count'都有什么好处; 它看起来像两次相同的信息(或者,至少,代码通常用两个参数的相同值写入).

同样,也存在问题scanf_s()及其亲属. Microsoft表示缓冲区长度参数的类型是unsigned(明确说明'size参数是类型unsigned,而不是size_t').相反,在附件K中,size参数是类型rsize_t,它是size_t(rsize_t的另一个名称size_t,但是RSIZE_MAX小于SIZE_MAX)的限制变体.因此,scanf_s()对于Microsoft C和Standard C ,代码调用必须以不同方式编写.

最初,我计划使用'安全'函数来获取一些代码,以便在Windows和Unix上干净地编译,而无需编写条件代码.由于微软和ISO功能并不总是相同,因此失败了,现在是时候放弃了.


vsnprintf()Visual Studio 2015 中Microsoft的变化

在Visual Studio 2015文档中vsnprintf(),它指出界面已更改:

从Visual Studio 2015和Windows 10中的UCRT开始,vsnprintf不再完全相同_vsnprintf.该vsnprintf功能符合C99标准; _vnsprintf保留以实现向后兼容性.

但是,Microsoft的界面vsnprintf_s()并没有改变.


Microsoft和附件K之间差异的其他示例

C11标准变体localtime_s()在ISO/IEC 9899:2011附录K.3.8.2.4中定义为:

struct tm *localtime_s(const time_t * restrict timer,
                       struct tm * restrict result);

localtime_s()定义为的MSDN变体相比:

errno_t localtime_s(struct tm* _tm, const time_t *time);

和POSIX变体localtime_r()定义为:

struct tm *localtime_r(const time_t *restrict timer,
                       struct tm *restrict result);

C11标准和POSIX功能与名称不同.Microsoft功能在界面上有所不同,即使它与C11标准共享一个名称.

差异另一个例子是微软的strtok_s()和附录K的strtok_s():

char *strtok_s(char *strToken, const char *strDelimit, char **context); 

VS:

char *strtok_s(char * restrict s1, rsize_t * restrict s1max, const char * restrict s2, char ** restrict ptr);

请注意,Microsoft变体有3个参数,而附件K变量有4个.这意味着Microsoft的参数列表strtok_s()与POSIX兼容strtok_r()- 因此,如果更改函数名称(例如通过宏),对这些参数的调用可以有效地互换 - 但是标准C(附件K)版本与额外参数不同.

问题Mac和Linux上的不同声明qsort_r()有一个答案,也是qsort_s()由Microsoft qsort_s()定义并由TR24731-1定义 - 再次,接口是不同的.


ISO/IEC 9899:2011 - C11标准

C11标准(2010年12月草案 ;您可以从ANSI网上商店获得30美元的最终标准,ISO/IEC 9899:2011的PDF副本)确实具有TR24731-1作为其中的可选部分标准.它们在附录K(边界检查接口)中定义,它是"规范的"而不是"信息性的",但它是可选的.

C11标准中没有TR24731-2功能 - 这很难过,因为vasprintf()功能及其相关功能可能非常有用.

快速摘要:

C11含有TR24731-1

C11不含TR24731-2


建议将附件K从C11的继任者中删除

Deduplicator在对另一个问题的评论中指出,在ISO C标准委员会(ISO/IEC JTC1/SC22/WG14)之前有一个提案

附件K的 N1967 现场经验 - 界限检查接口

它包含对附件K函数的一些现有实现的引用 - 它们都没有广泛使用(但如果您感兴趣,可以通过文档找到它们).

该文件以建议结束:

因此,我们建议将附件K从C标准的下一版本中删除,或者弃用然后删除.

我支持这个建议.


我也想这么想,但是他们有一个已安装的基础并且不会破坏向后兼容性,所以在实践中它继续意味着MS不会支持比C89(C90)更现代的C标准 - 遗憾的是.
好吧,如果MS与标准相悖,那么MS将需要改变,而不是标准......

3> cmaster..:

好了,现在一台用于 TR24731-2:

是的,我已经使用过asprintf()/ vasprintf()自从我在glibc中看到它们之后,是的,我是他们的坚强拥护者.

为什么?因为它们能够一次又一次地提供我需要的功能:一种功能强大,灵活,安全且(相对)易于使用的方式,可将任何文本格式化为新分配的字符串.

我也非常赞成memstreams:喜欢memstream,asprintf()(不是open_memstream()!!!)为你分配一个足够大的缓冲区并让你进行fmemopen()打印,所以你的打印功能完全不知道它们是否打印成字符串或者文件,你可以简单地忘记问题,你需要多少空间.



4> 小智..:

您是否使用支持TR24731-1功能的库或编译器?如果是这样,哪个编译器或库以及哪个平台?

是的,Visual Studio 2005和2008(显然是针对Win32开发).

您是否因修复代码以使用这些功能而发现任何错误?

....我编写了自己的安全功能库(我们经常使用的只有15个),可以在多个平台上使用 - Linux,Windows,VxWorks,INtime,RTX和uItron.创建安全功能的原因是:

由于不正确使用标准C函数,我们遇到了大量错误.

我对TR函数传递或返回的信息不满意,或者在某些情况下,他们的POSIX替代品.

编写函数后,发现了更多错误.所以,是的,使用这些功能是有价值的.

哪些功能提供最大价值?

更安全的vsnprintf,strncpy,strncat版本.

有没有提供任何价值或负值?

fopen_s和类似的功能对我个人来说几乎没有什么价值.如果fopen返回NULL,我很好.您应该始终检查函数的返回值.如果有人忽略了fopen的返回值,那么是什么让他们检查fopen_s的返回值?我知道fopen_s将返回更具体的错误信息,这些信息在某些情况下很有用.但是对于我正在做的事情,这并不重要.

你打算将来使用这个图书馆吗?

我们现在正在使用它 - 在我们自己的"安全"库中.

您是否正在跟踪TR24731-2的工作?

没有.



5> user3080602..:

不,这些功能绝对无用,除了鼓励编写代码以外它没有任何用途,所以它只能在Windows上编译.

snprintf非常安全(正确实现时),因此snprintf_s毫无意义.如果缓冲区溢出(通过清除连接到字符串),strcat_s将销毁数据.还有许多其他完全无知事情如何运作的例子.

真正有用的功能是BSD strlcpy和strlcat.但微软和Drepper都因为自己的私利原因拒绝了这些,以及各地C程序员的烦恼.


感谢您的投入.我不确定'完全无知'是否合适,但我同意新功能并不总是像它本来可以那样改进.
推荐阅读
放ch养奶牛
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有