sohulinux

Sanitizing log file output

By Jake Edge
June 29, 2011
http://lwn.net/Articles/449460/

翻译:朱翊然/李凯

正确的处理好用户控制的数据是计算机安全基本原则之一。多种内核日志消息允许用户通过“%s”格式将自己控制的内容放入消息中,这可能被攻击者用在字符串中插入控制字符的方式来混淆管理员。所以 Vasiliy Kulikov提出了一个可以转义特定字符的补丁。关于究竟应该转义哪些字符引发了争议,这背后更大的问题是在安全领域存在已久的问题:白名单还是黑名单。

问题来源于这样一种想法:管理员经常用类似tail和more这样的工具在TTY上查看日志文件,如果用户可以在日志文件中插入控制字符(特别是转义序列),他们可能会导致重要信息被忽略或者其他类型的混乱。在最坏的情况下,转义序列可能会利用终端模拟程序的一些漏洞去执行代码或者引起其他的不正常行为。在该补丁中,Kulikov给出一下例子:“控制字符可以通过tty愚弄查看日志的管理员,比如用^[1A去消除上一个日志行”,对于被过滤的字符,该补丁简单的用“#xx”来替换它们,xx是字符的十六进制值。

在一定程度上,这是相当小的问题,但是我们并不完全了解什么情况下需要使用控制字符。争论中提到的两个很常见的例子就是文件名以及USB产品ID字符串。补丁的第一个版本做的工作显然太过分了,它除了控制字符,把所有 0x7e 以上的字符都转义了,这样Uincode以及其他非ASCII字符都将被转义。但是在抱怨这件事情后,Kulikov的第二个版本仅仅转义了控制字符(小于0x20),但是不包括换行和制表符。

Ingo Molnar 觉得这样并不好,他认为与其把这些已知的字符(newline/tab)列入白名单,还不如把有潜在危害的字符列入黑名单:

另外,我认为这将是更好的方法:排除少数有危害的控制字符(例如退行和控制台转义),而不是试图包括那些有用的字符。

[...]这也是内核开发的一个准则:我们处理已知有害的东西,其他的放任不管。

但是为了创建白名单,不同终端模拟器上不同控制字符的影响必须仔细的确定,而白名单的方法可以简单的形成一张很大的网络。 Kulikov 指出,找出哪些字符有问题不简单:

你能不阅读之前的讨论而立即回答那些控制字符是有害的吗,哪些字符是有时有害的(在一些 tty上),哪些又总是安全的以及原因(甚至回答为什么它总是有害的)?我对tty不精通,我必须去阅读console_codes(4)或者类似的文档去回答这个问题,大多数的内核工程师或许也不得不去读这些文档。

类似 Molnar 和 Kulikov 的分歧在安全领域已经存在很多年了。至今也没有分出到底谁的观点更好。安全领域的绝大多数方面都涉及到了白名单和黑名单之间的平衡点。一般而言,基于用户提供的数据(例如在web应用中),达成了这么个共识,即把好的输入列为白名单,而不是试图去排斥那些“bad”输入。至少在这方面,Molnar并不认为白名单是一个好机制

黑名单是明确的:它禁止显示一些特定的字符,因为那些字符是危险的。

白名单在另一方面白名单却走了一条错路,它把“举证责任”给了有用的好家伙,这实际上起了反作用

Kulikov并不同意之前的分析,这一点都不奇怪:“如何应对那些还未知的危险字符”。当然这里有一个问题,虽然把已知的好的字符列入白名单更加安全,但是如果在用户提供的字符串中的其他受控制的字符中有合法的用途的话,白名单制就不够灵活了。

在这个特殊的案例中,任何一个解决方案都不错,因为并没有什么好的理由去包含这些字符,但是 Molnar 可能是对的,ASCII中并没有什么隐藏的危险 。有一个疑问就是这种改变是否有必要。管理员可能会错过重要的信息,或被精心制作的输入欺骗(Willy Tarreau 提供了有趣的例子,是有关第二种情况的),这种担心让这个补丁诞生。 Linus Torvalds不相信这是一个真正需要解决的问题:

我的确认为应该在用户进程那里做过滤——人们不应该用 cat 查看 dmesg。如果他们这样做了,他们真的是咎由自取。

就我所知,我们也没有在控制台层面上做任何转义序列处理,所以控制字符也不会搞乱控制台。

最危险的字符是看起来没有过滤的那个:我们最先想到的字符应该是’\n’,而且当你在字符串中插入一个新行后再尽力使其余的字符串看起来非常不爽的时候,那么你也许会引发一些混乱的日志消息。

鉴于Torvalds的怀疑论,这个补丁似乎并不能适用于任何地方,即使像Molnar倡导的那样把它变为一种黑名单的方法。这个是,或者应该是相当不引人注意的,但是关于黑名单VS白名单的问题,将来我们也许会再次听到。这里有大量的例子是关于科学技术应用在安全(和其它)上下文的。这经常会归结到一个更安全(通常是指白名单)或者更实用(黑名单)的选择上来。其实,这种情况并没有什么不同的,而且其它的情况也肯定会突然发生的。

Topic: sohulinux

谁是我们的用户?

By Jonathan Corbet
June 29, 2011
Who is that code for?

翻译:林业/史玉良

我们究竟努力在创造什么?自由软件开发工程在这个问题上投入了大量的思考和精力。同样,一些项目也在努力向外界表述清楚他们的目标所在。但可以说几乎没有什么项目思考过他们的用户究竟是谁这个问题。然而,一个项目认识其开发目标群体的维度会深深影响该项目所创造出的代码以及项目本身发布的方式。最近,一些备受瞩目的项目成为公众广泛而苛刻批评的目标;其实这些项目真正的问题在于他们对谁是目标用户这个问题很困惑,尤其是当他们发现他们投入了很多兴趣的项目并没有被用户接受时,他们觉得很失落。

最近,有几个相当明显的例子。Firefox5的发布引起了大风暴, Firefox4迅速被抛弃,而在不久的将来,随着Firefox 6的发布,同样的事情将会再次上演。对个人桌面用户来说,这样的发布计划可能刚刚能接受,这也取决于有多少扩展会被破坏(笔者担心这次升级会破坏浏览器中的Firemacs,还有因此也导致Emacs按键绑定的破坏)。相反,如果你正在公司网络环境里,在这个环境里,所有软件必须经过一个扩大的批准流程才能部署,那么缺乏对前几个的 major release 的支持会带来很大的麻烦,对于采用这种政策的企业来说,Firefox是越来越不适合的;因此,在这一点上涌现出许多抱怨,也就不足为奇了。

Firefox开发者的回应很清楚:Firefox项目并不是以企业用户为目标用户群。Firefox之所以取得成功是因为个人用户的使用,而不是其雇主的使用,所以发布的计划是继续面向这些个人用户的。这个观点在项目当前正在考虑的草拟声明中就可以看出:

互联网的下一代革新将会与浏览器紧密相关,浏览器将致力于关注个人用户和开发者的兴趣,提供足以和专有系统竞争的惊奇体验;而且,在用户控制和解放开发者方面更优于那些专用平台。

讨好公司信息技术管理者们并没真正包含在这个计划里。也许有人会反驳,这个策略将加强IE在公司环境中的地位,然而,这就是Firefox开发者们所做出的选择。

近来,另一个备受瞩目的关于目标用户的误解存在于GNOME项目,特别是GNOME3的发布。毫无疑问,一些用户对于GNOME3和GNOME Shell带来的改变感到很失望,尽管在这个群体有多大的问题上还存有异议。GNOME开发者Bastien Nocera最近明确指出,至少其中的一些人并不是GNOME项目的目标受众。

因为我们并不是在为那些喜欢选择自己的终端模拟器的人设计桌面。

GNOME项目已经对其用户团体做了很多的其它决定,这些决定迎合了之前讲到的观点。在这种情况下,许多受到影响的用户都感受到了,他们不过是GNOME项目过去所关注的而已。如果GNOME曾经真正以那些关心自己终端模拟器的用户为目标受众,那么现在,它在其他地方找到了更加绿意盎然的草地,并把那些用户丢在脑后。这些用户已经向公众表达出他们的感受:这种时候,能够做到的最好的事几乎可以肯定就是祝愿GNOME面向它的目标用户能取得成功,而如果GNOME不再是一个合适的工作环境,那么转移到其它环境上就是了。

用户的观点影响代码组织方式的例子在社区中有很多。比如 PostgreSQL,这是一个确实把“企业级”用户作为目标用户的项目。PostgreSQL的开发者们还设想他们的用户会很关心他们的数据。这个项目的产品有一个很保守的,密集审核的补丁合并政策以及一个为期五年的支持政策。2006年底发布的 PostgreSQL 8.2将会继续被支持直到今年年底。新功能需要等待更长的时间,但是功能的快速开发通常并不是数据库管理系统用户的迫切需求。

然而 OpenBSD 有着完全不同的看法,他们只勉强承认在他们的开发社区之外存在着一个用户群体。不久之前,OpenBSD的leader Theo de Raadt把他们的观点说得很清楚

“我们为自己而开发了OpenBSD,并不是为了你们,不是为了用户们。如果用户们最终很喜欢我们设计的系统,那很好。这可能是由于有些用户和我们有着相同的需求。但是,他们要倒霉了,因为我们是为自己而做的。”

虽然当用户忘记了自己的定位时这可能会导致误解,但对于这个特定的项目,这个立场是对的。

其他的例子比比皆是。Git和Mercurial是相似的工具但他们的用户却有着不同的意见.貌似这个差别对于windows用户来说能更加明显的感觉到。Fedora和Red Hat企业版Linux有着相同的始祖和大量相同的代码,但是他们却是为不同人群开发的。在内核2.6.x版本的时代之前,内核社区(大多数)的开发都是直接针对终端用户的;这种观点直接导致了奇/偶的开发过程。现在的内核主要是为发行版而开发的,关注的是频繁的稳定版本发行以及迅速的添加各种功能。Puleaudio和JACK的目标用户不同,依此类推。

没有一个工程可以适合所有人的需求提供所有的一切;所有的这种尝试都失败了。对用户群的清晰认识对一个工程的实施大有帮助,可以吸引志同道合的开发者并增加工程的发行量。因此工程开发需要明确目标用户群,并能够明确的传达这一设想。如果一个工程没有明确特定用户的需求之间的优先级,那么最好在用户投入大量时间到这个软件上之前了解到这个。反过来说,用户也应当注意:正如我们不会去用一个视频编辑器去做代码高亮一样,我们不应该指责一个为特定用户群而开发的工程不能满足其他一些的需求。我们是一个庞大而丰富的社区;如果一个工程不能满足一些特定的需求,那么很可能有其他的一些软件是专门用于解决这些需求的。

Topic: sohulinux

Acoustid 算法大致流程整理-王鑫

原文:http://oxygene.sk/lukas/2011/01/how-does-chromaprint-work/

  1. 图片在此算法中扮演了一个很重要的角色,当人们“看到”音频时,它通常都是形如下面的波形图:
  2. 但是这种图对分析起来没有什么太大用,更有效的一种表现形式是声谱图,它描述了特定频率的强度随着时间的变化:

    可以通过把原始视频切割为许多重叠的帧并在其上应用傅立叶变换(或者快速傅立叶变换)来得到这种图片。许多声纹识别算法都是利用这种图片来工作的,有的是比较频率和时间的不同,有的则是寻找波峰。

  3. Chromaprint则更近一步将频率转换为音符来处理。Chromaprint只关心音符,而不关注八度音,因此结果就是12音域,每个音符对应一个音域。这种信息被称为“Chroma特征”(其实就是一个12维的特征向量)。再经过一些过滤和标准化,最终会得到下面这种样式的图片:
  4. 既然有了音频的表现形式,那么比较这类图片并计算其相似度也不是太困难的事了,但是如果我们想在数据库中搜索它们,我们则需要压缩它们,也就是需要一个更为紧凑的形式。Chromaprint的方式是在Pairwise Boosted Audio Fingerprint这篇论文中提到的方法上修改的。
  5. 然后你可以想象你拥有一个16×12像素的滑动窗口从左到右来滑过整个图片,每次只滑动一个像素,这样就得到了许多子图。针对每一个子图应用预定义好的16个过滤器来捕获滑过的音符和时间的强度的差别。过滤器就是计算子图的灰度图的特定区域的和,然后比较两个和。有6中不同的区域

    通过使用上面这种类似于掩码的图片,把它置于子图任何一个位置,然后计算黑色和白色区域的和,再同另一个和相减,结果是一个单精度实数。每个过滤器都有3个系数,最终结果会是一个0到3之间的整型数。每个过滤器的系数都是通过机器学习算法在音频文件的训练集上训练得到的。

  6. 现在我们有16个过滤器,每个过滤器都可以把结果编码为2位。我们把这些结果组合在一起,得到一个32位的整型数字。
  7. 如果对所有滑动窗口滑过的子图都应用上述办法,我们就得到了整个音频的声纹了。识别声纹最简单的办法就是针对声纹计算位错误率。

实验结果:

Heaven FLAC
  
  

Heaven 32kbps MP3
  
  

Differences between Heaven FLAC and Heaven 32kbps MP3
  
  

Under The Ice FLAC
  
  

Under The Ice 32kbps MP3
  
  

Differences between Under The Ice FLAC and Under The Ice 32kbps MP3
  
  

Differences between Heaven FLAC and Under The Ice FLAC

由上面可以看出,针对同一首歌的FLAC和MP3差别很小,而不同首歌之间差别很大,结果还是挺好的。

Topic: sohulinux

Echoprint: 开源的声纹识别

Echoprint: Open acoustic fingerprinting
June 29, 2011
This article was contributed by Nathan Willis

翻译:王鑫/曾怀东

移动智能业务极大推动了声纹识别技术的发展。你可能已经看过这样的电视广告场景:用户拿起电话录制了一段几秒的附近播放的音频,然后程序计算出这段音轨的声纹并利用声纹去远端的数据库查询艺术家和音轨的名字。在以前该领域一直被专属软件占据,但是在上周一个新的开源的项目——Echoprint诞生了。

Fingerprints on the databases

尽管名字类似,声纹识别技术和用来检测文件改动的基于hash的数字指纹识别技术差别很大。hash函数对单独比特的变化很敏感,声纹函数则必须努力得分析音频,分析的方法要独立于音频编码方式,比特率乃至静态或环境噪声。声纹关注于从音轨中提取可感知的信息,例如节奏,平均频谱以及周期性的音调模式。声纹识别技术主要用于从未知音频片段中获取可能的音轨信息,不过也可以用来查找相类似的音乐(依靠相关算法的调整)

声纹识别服务市场主要被专有软件垄断,其中比较著名的有 Shazam, SoundHound, 以及 Gracenote。许多自由软件组织的人都知道Gracenote,原因是十年前发生那场争端,Gracenote的母公司突然限制了对CDDB(一个由用户建立的唱片识别数据库)的使用。很多人都由于政策的更改而感到被背叛,因为CDDB的数据都是由用户在播放或翻录CD时自愿提交的,但是用户们却不能使用或是享有CDDB带来的好处。这个数据库是因特网众包的早期例子,很多人发现自己无法访问这个数据库,自己努力的成果被公然掠夺了。

转眼到了2011年,相比较专有软件,大多数开源应用使用"open content"的服务。例如由遵循501(c)(3)条款的非盈利的MetaBrainz 基金会运营的MusicBrainz。在过去的几年中,MusicBrainz通过MusicIP(后更名为AmpliFIND)提供的闭源MusicDNS服务来支持声纹识别。

尽管 MusicBrainz同AmpliFIND在该服务上签订了永久性合同,人们仍认为这并非一个好选择,因为 MusicBrainz的社会契约要求服务保持100%免费(译者注:依赖闭源服务无法保障这一点)。最近,很多开源声纹识别项目开始渐成气候,例如Lukáš Lalinský的 Acoustid ,MusicBrainz 也开始寻求开源和开放的内容来取代MusicDNS。同时,声纹识别技术团队 Echo Nest 确定自己最佳的策略是将全部产品做成开源并尝试商业化声纹服务,而不是试图和这些资深对手玩贴身肉搏式的交锋。

Echo Nest和 MusicBrainz在一些项目有过合作,例如 Rosetta Stone —一个用于在不同音乐服务ID数据库间匹配艺术家和音轨ID的工具—所以决定推动Echoprint这一开放项目并把它和 MusicBrainz进行整合对双方来说都是很好的选择。而且这也没有损害到 AmpliFIND,因为 AmpliFIND已经将自己所有的知识产权包括 MusicDNS和portable unique identifier (PUID)数据库转让给了 Gracenote。

The Echoprint release

Echoprint系统由三部分组成。 Codegen指纹生成器将音频文件(或者音频样本)作为输入,基于Echo Nest Musical Fingerprint (ENMFP)算法产生声纹。Echoprint服务器维护一个声纹和音轨信息的索引数据库,并且支持远程访问和添加新的声纹及音轨。 Echoprint数据库本身维护对外公开的音轨和声纹信息。数据库里有整段音轨的声纹代码,但是同大多数声纹识别技术类似,有部分片段即可进行比对。 Echo Nest声明 Echoprint可以提供至少20s时长片段的声纹精确匹配。

在实际使用中,应用程序会对音频(捕获的或是从文件中获取的)进行抽样,然后使用Codegen库计算声纹,最后在Echoprint服务器中检索匹配项。服务器以JSON格式返回所有匹配的音轨记录。另外,如果没有符合要求的匹配,应用程序会向服务器数据库提交该声纹信息和一些通过其他手段获得的音轨元数据。

Codegen的代码,服务器以及各种工具(包括一个iPhone app的实例)都存储在GitHub上了。 Codegen应用和共享库在MIT许可下有效,而服务器(基于Apache SolrTokyo Tyrant)则遵循Apache License 2.0许可。

公共的Echoprint数据库则是遵循其一个特定的条款来授权,这个条款被称为“Echoprint数据库许可(Echoprint Database License)”。它允许商业和非商业的应用,并且要求任何下载了数据和加入其中的人都要把额外数据贡献给Echo Nest。这个条款看起来不如知识共享式的“Share Alike”公平,因为它要求给Echo Nest提供数据。这个许可的导言看起来是说所有的贡献都会同公众一起分享,但是Echo Nest可没有承担分享数据的义务。第一版用在线音乐厂商7Digital所拥有的数字音乐和MusicBrainz所提供的元数据生成了将近1300w的声纹,并以其作为“种子库”。

在这个协议中还有其它令人烦恼的条款,包括要求任何访问此数据的应用程序都要使用Echoprint的“powered by”logo。此外,这个协议中也没有明确说明将来Echo Nest如何修改或者终止这份协议。对于那些曾经在CDDB灾难中受到伤害的人,这份协议会使他们犹豫,因为它对于Echoprint数据库会不会发生同样的事情这点压根没有提及。

目前,Echo Nest没有将其算法细节以一种方便阅读的形式公之于众。当然,Codegen的源码是提供了,但是大家还在期望详细解释其过程的白皮书能够在不久的将来被放出。不幸的是,当前的法律文书没有明确解释涉及到软件的专利许可(MIT许可过于简单了),而这有可能涉及到一些开发者。声纹识别是一个专利领域,并且确实有一些调查揭示了几个以Echo Nest和其创始人Brian Whitman以及Tristan Jehan名义的相关专利申请。从好的一面看,所有专属的声纹识别服务也有专利问题

当前Echo Nest自己的“song/identity”服务器是唯一的已开始运行的Echoprint数据库,尽管任何应用程序作者都可以以测试为目的建立自己的服务器。Codegen的命令行程序可以被任何现代Linux系统所构建,仅需几个重要的依赖,分别是TagLib,Boost和FFmpeg。这个程序以文件为参数(其后跟可选的参数,开始时间,持续时间,均以秒为单位)生成一个声纹。其输出是一个JSON对象,其中包括了文件的ID3标签信息和一个经过base64编码后的声纹。这个输出可以用cURL或者类似的工具直接发送到Echo Nest的服务器,在Codegen的README文件中有说明。

Play or Pause

MusicBrainz的Robert Kaye称此项目计划在可预见的未来(或者直到“人们纠缠我去解决它”)保持对PUID和MusicBrainz数据库中的MusicDNS的支持。这个项目正在运行一个使用Echoprint替代MusicDNS的测试服务器,但是并没有一个何时开始支持Echoprint的明确时间表。

Kaye还称,他期望在Echoprint产品被大范围采用前能够做更多的调整,但是他注意到“临界物质(critical mass)”是最重要的因素——即对客户应用以及一个相当大的可靠声纹数据库的支持。在7Digital的帮助下预装载1300万首歌曲听起来很多,但是对比一下,Shazam宣称其已经可以鉴定超过十亿首了。

考虑到使用MusicBrainz的开源音频项目的数量,可以毫不夸张地说,Echoprint已经有了一个成功的开始。它是首个以“立即可用”的姿态杀入市场的完全开源的音乐声纹系统,因此很可能产生大量的音乐识别的开源移动应用。没有了许可费的负担,技术可以在独立的音乐识别应用程序,开源或闭源之间传播。

然而,Kaye强调MusicBrainz的后MusicDNS的迁移意味着使这个项目的声纹识别算法变得不可知。Acoustid仍然处在十分活跃的开发领域中,这里有篇文档叙述了该算法的细节,而且不需要改变MusicBrainz数据库的格式就可以支持它。

这两个声纹识别技术是重叠抑或是互补,还是竞争的关系,这也许最终将由用户来评判。Echoprint是如此的新生态,我们很难预测它最终会发展成什么样。MusicBrainz的支持自然是一个很大的优势,但是在应用程序作者大规模采取这个技术之前可能更需要的则是更好的技术文档以及对模糊的法律问题的说明。但是,它无疑填补了开源移动软件中的巨大空白。如果这个众包技术能很好运行并创建出一个声纹数据库,该开放方案将很可能在如此之多的相似的专属供应中拥有一片商机。

Topic: sohulinux

让静态分析更容易些

Making static analysis easier
By Jonathan Corbet
June 22, 2011

翻译:林业

有件事几年来已经很清楚了,那就是静态分析工具有极大的提高我们所编写软件的质量的潜力,计算机有条件分析源代码并且寻找那些可以标示漏洞的 patterns。“Stanford Checker”(后来被 Coverity 商业化了)已经在许多免费软件代码库中找到了大量的缺陷。但就是在免费软件社区之内,我们自己开发的工具相对缺乏并且比较原始,不过,这种情况或许已经要结束了,我们已经开始看到若干可能成为静态分析工具集基础的开发框架了。

一些关键的变动已经出现在编译器套件中。编译器目前已对代码执行了详细的分析来生成优化的2进制码;如果利用那些分析来做其它的事情是很自然的。其中的一些已经出现在编译器本身之内;GCC和LLVM可以生成一个比以往更广泛的警告集。这些警告是一个好的开始,但是还有更多的事可以去做,特别是让一个项目可以生成自己专有的项目检查分析工具。因为无论什么大小规模的项目都趋向于拥有自己本身的而与其他不同的不变量和规则。

几年来FSF一直反对将分析模块通过插件机制添加到GCC,因为害怕插件机制会允许私有模块的产生。经过几年时间的考虑,因为对专有模块处理的担忧,FSF改写了运行时模块的许可证例外部分;到这时,GCC才有了对插件模块的支持。虽然这个特性的作用现在还相对较小,但却是一个情况即将改变的标志。

Mozilla项目是一个对插件机制较早的使用者,它创造了两个模块(Dehydra and Treehydra)来让开发者编写用Javascript写出的分析代码。这些工具已经展示出了其在Mozilla之内的作用,但是这方面的开发似乎停止了。其邮件列表处于垂死状态并且其软件看起来也似乎好久没有更新了。

一个替代的选择是GCC MELT。这个项目提供了一个相当广泛的插件地址以允许使用类Lisp语言来编写分析代码,这份代码被转换成C语言,然后编译出一个可被编译器调用的插件。MELT有很好的文档;以及许多关于其应用教程的幻灯片。

MELT看起来似乎是一个能胜任的系统,但是看起来似乎并没有太多为其而写的模块。人们并不希望必须看很多文档后才能理解该系统。基本提示是以如下开头的:“首先你要理解 GCC的主要内部表现(notably Tree & Gimple & Gimple/SSA)。”MELT作者Basile Starynkevitch的130页关于MELT的讲解幻灯片的前85页全都是介绍GCC材料。换一种说法,使用MELT需要对GCC有深入的理解;其并不是一个行外人士可以快速上手的系统,可以使用的简单示例的缺乏也同样是没什么帮助。

最近,David Malcolm宣布了一个新的框架的发布,该框架允许产生一些与编译器共同运行的Python脚本插件。他的原始目标就是要创造一些帮助 Python 项目(CPython)开发的工具。其代码中最重要的检查部分就是在努力确保对象的引用计数被正确的管理。但是他认为自己的工具对其它的一些项目甚至是对GCC本身的新特性设计也是有潜在作用的。

第一眼看上去,David的gcc-python-plugin机制承受着和MELT一样的困难 - 最初的学习曲线是不合理的。它同样是一个很年轻且不完整的项目;David自己也承认,只推出了他急需的功能性的部分。分析代码看起来很接近了,可是,在编译器中直接运行脚本的机制确实比MELT的compile-from-Lisp要自然些。相比MELT,这可能会吸引更多的用户和开发人员吧。

或许它只是因为小编本人使用 Python 比在Lisp中更加熟练,所以偶自然而然的觉得基于Python是一个更好的解决方案。

无论如何,有一个结论是很清楚的:目前为GCC编写静态分析插件太难了;甚至是有才华的开发者在接触到这个问题时也需要花费很多的时间去理解编译器,才可能在这个领域取得一些成就。上面描述的这些努力是在正确方向上的一个很大的进步。很明显,现在的努力是需要在其上构建许多支持代码的基础。很难说我们什么时候才能到达那个分析代码大量涌出的临界点,现在离那个时候还很遥远。

不过,并不是所有的活动都在围绕着GCC,一个利用LLVM编译器的有趣的静态分析工具已经随着 clang 被构建出来了。关于这个工具的文档几乎没有,但是看起来它在某些方面还是很强大的,比如检测某些内存泄漏问题,间接的空指针引用,闲置价值的计算等等。一些为这个工具增加一个插件特性的补丁包也已经被贴出,但是看起来似乎它们目前也并没有走的更远。

在5月的时候,John Smith在一些开源项目中运行了 clang 想要看看会得到什么样的结果。这些结果已经被贴到了网上,它们显示了一些可被找到的潜在的问题以及检查器所产生的漂亮的HTML输出。其中一些警告明显是无效的——一个经常伴随着静态分析工具的问题——但是另外的一些看起来很值得去研究。总而言之,clang 静态分析工具看起来就像这里提到的其他工具一样,在发展过程中还处于一个相对较早的阶段,虽然所有东西都在快速运行着,但是这个工具是值得关注的。

事实上,一般而言,在静态分析领域,以下这些事情是真的:缺乏一个好的分析工具有点奇怪——考虑到我们有那么多的开发人员,有的人可能认为只需要很少人就能搞出一个静态分析工具。相比较于已经存在很多的版本控制系统,我更希望开发者去开发更好的分析工具。但是自由软件开发的天性就是人们工作在那些使他们感兴趣的问题上。随着我们静态分析工具的基础越来越好,可以期待越来越多的开发人员将会找到他们感兴趣的基础,并且乐于在其之上进行构建。而整个开发社区也会从这些结果中受益。

Topic: sohulinux

One more hop for Kermit

http://lwn.net/Articles/448636/
By Jonathan Corbet
June 22, 2011

翻译:马少兵

在过去最美好的时代,我做 VMS 系统管理员的时候,那时 ARPAnet 还是一个很小、龟速的网络,而且接入点及其有限。当一些牛人基于UUCP连接建立了USENET,Unix系统还没有被广泛使用。但已经开始出现了个人电脑,电子公告板系统也开始被建立,我们中的一些幸运儿还能够买得起1200波特的调制解调器。在那些日子里所使用的调制解调器工具是一个叫做 kermit 的小程序,并且下载是完全免费的。俺已经不记得最后一次使用调制解调器是哪个时候,但是我仍然会很有兴趣去看到,已经30多年的工程即将通过最后的过渡,和其他的一样,最终走向自由软件。

那个年代的许多系统,尤其是没有任何政府预算支持的,其“网络接口”是串口。通过该接口,我们可以连接到计算机工作,也是它让我们在那个时代获得了最早的远程服务。任何通过RS232联网的用户首先需要在计算机的RS232接口和modem的RS232接口之间交换串行数据。尽管Unix系统通过一个叫“cu”的工具来达到这个目的,但是人们还是倾向于用kermit来代替。

Kermit最早起源于美国哥伦比亚大学,是把它作为多种不同网络环境下的计算机通信的方法。相比”cu”,kermit具有容易安装到软盘、设置和使用的特点。仅仅只需要弄清有多少数据位、多少停止位、多少校验位(RS232是最流行的标准)、以及适合与调制解调器上的ATD命令相对应的类型是什么等。Kermit甚至可以对不同处理字符集之间进行转换;也可以直接同 EBCDIC主机通信。

在一个很短的时间内,Kermit开发了一些适合文件传输的功能。该协议是相当有效率的,而且它的设计还包括用于处理串口通信中偶尔出现的控制字符,将8位数据转为7位数据等。该协议的健壮性意味着,它可“工作于”任何两种类型结构的机器之间。所以在前互联网时代,Kermit成为了最流行的文件传输协议,是不足为奇的。

尽管哥伦比亚大学以源代码方式发布了Kermit的多个版本;包括从 BBS 下载,DECUS磁带等,但是从来不是自由软件。造成这样问题的主要原因是,当kermit首次发布和使用的时候,自由软件许可证还没有出现。虽然哥伦比亚大学已经考虑将代码发布到一个公共的领域,但是这种决定看起来并不是最好的。

因为我们想使得Kermit软件能够被公开共享,而不是仅仅发布到一个公共领域,虽然这看起来是矛盾的。我们觉得通过拥有版权,可以防止企业独占该软件,以及所带来的将该软件成为一种商业产品而出售的情况。因为在我们面前已经发生了一系列这样的事件,由于一些大学将自己的代码发布至公共领域,结果被公司重写,最终使得公司占据了该代码的版权。

Kermit许可证会随着时间变化而改变,但是“你可以使用在非商业化的程序中”的情况是保持不变的。Kermit许可证的最终版本允许,可以将该代码绑定在免费的操作系统之中,但是禁止在没有允许的情况下修改源代码。因此事实是,尽管Kermit许可证和Linux操作系统一样允许分发,但是由于它不是一个真正的免费软件,而导致大量的发行版最终躲避使用它。

除了免费的操作系统以外,任何人想要发布商业化与Kermit有关的系统,必须向哥伦比亚大学购买许可证($3-10/each)。

在过去,Kermit已经取得了引人注目的成绩。但是随之而来的互联网已经取代它的位置。现在利用手机,都可以运行ssh协议。RS232逐渐退出了历史舞台。内核的开发者仍然在某些情况下用串口进行调试,但是我估计,大部分的LWN读者从未考虑过什么是 null modem cable. Kermit的用户肯定会逐渐萎缩,对那些需要的人来说,仍然会被使用和购买

可能在三月份,哥伦比亚大学宣布不再支持Kermit项目的维护了。其中一个可能性是由于商业许可证的销售额减少,导致没有足够的日常管理费来维持目前的工作。在2011.7.31号以后,哥伦比亚大学将不再开发任何的代码加入到Kermit系统中,也不再提供系统支持和维护服务。已经运行了30年得工程即将结束。

哥伦比亚大学计划在Kermit系统结束以前还要做一件事情,那就是将该软件放置于BSD许可证下。C-Kermit9.0版本就携带该许可证信息;6月15号,首个测试版已经发布。9.0版本将支持FORCE-3包协议(“使用在恶劣环境下”),改进了相应的脚本、修复了很多地方的bug等。因此9.0版本的发布,大概会选取一个距离7月31号截止日期之前的某一天,不仅仅有新的功能。而且将会首次免费发布。

由于这种变化的结果,Kermit将会很快出现在你的发行版的仓库中;对于大多数的Linux用户,这一点关注度可能很小。但是对于我们中的大多数,有时候通过串口连接是唯一和系统进行通信的方式。虽然Kermit系统远不是我们唯一的选择,但它相当不错。我们很欢迎Kermit能够加入开源软件社区。

Topic: sohulinux

一个Crypt_Blowfish加密中存在的漏洞

A hole in crypt_blowfish
By Jake Edge
June 22, 2011

翻译:史玉良

最近在crypt_blowfish密码散列库中发现了一个长期以来一直存在的bug。由于crypt_blowfish加密算法已经存在多年(据称该bug可以追溯到1998或1997年!),并已广泛应用于其他安装包(例如PHP)和一些Linux发行版中;从该事件可以看到,一个广泛应用的底层库若出现bug时可能会引发相当大的麻烦。该bug对于安全性的影响不大,因为它只影响到一些不常用于做口令的字符。但对于那些存储了由该库函数而产生的散列密码的部分人来说,这个bug就会有些头疼。

密码散列技术是一个用于鉴权机制(例如登陆一个系统或网络应用)的标准技术。明文密码并不需要存储,而由明文密码派生出来的密文需要存储。SHA-1Blowfish cipher是比较有代表性的用于该目的的单向加密散列技术。当用户输入密码时,调用相同的Hash函数,并将生成的密文与已经存储的密文做比对。这个想法是,即使攻击者侵入了密码数据库,他们也需要破解那里存储的密码散列值才行。正如其名称所示,crypt_blowfish是在Blowfish算法的基础上实现的密码散列技术。

这个bug本身很简单,其修复方法在C程序员看来是显而易见的。在面向对象的程序设计系统中,需要把 BF_std.c: BF_std_set_key()中的
tmp |= *ptr;
改为:

tmp |= (unsigned char)*ptr;

基本上来说这是一个符号扩展的bug。对于那些不是C程序员的黑客,可能需要一点解释。当存储在*ptr中的值高位被置为1时,它将被视为一个负数。因此,在该值与tmp(一个无符号整型)做或运算之前,它会被提升到4字节并做符号扩展。例如一个byte值0x80会变成0xffffff80。正如人们所预料的那样,之后的或运算将会产生一个错误结果。

这个问题实际上是由John the Ripper(JtR)口令破译软件程序发现的。作为创建测试套件的一部分, "magnum"(万能)尝试去破解由一个库(并非crypt_blowfish)的散列函数产生的包含有单个非ASCII字符(£或0xa3)的口令。由于JtR和crypt_blowfish 共用相同的Blowfish加密算法实现,同时使用时测试会通过,但是算法其它的实现将产生正确的散列,从而会不匹配JtR所产生的散列。

JtR和crypt_blowfish的开发者Alexander Peslyak(同时也是Solar的设计者)分析了这个bug产生的影响并发现,一些口令组合通过散列运算会产生差异很小的相同值(例如"ab£" 产生的值为"£"),这将会使得口令破译变得简单。进一步的分析显示,在最高位被置1的字符前出现的一些字符在计算散列值时会被有效的忽略。这意味着一个比用户给出的密码更简单的密码也会被视为有效——这是对用户口令作用的一个重大削弱。

应该指出的是,Solar的设计者关于这个问题的细节说明及其产生的影响即将公布。他的CVE(通用漏洞披露)要求相当详尽,并且他为这个错误承担所有的责任。其他发现projects中存在安全漏洞的程序员也应该按照他的先例来处理类似情况。

JtR并没有什么实际问题,由于它可以更新算法,所以它可以正确破解高比特位设置为1的密码。此外,它可以继续使用老的算法来破解由于hash函数错误生成的密码。但是使用crypt_blowfish的应用就不可同日而语了。高位被置位可能相当少见——至少对于那些只服务ASCII用户的网站是这样,但是目前还没有简单的方法来判别存储的散列值是否有效。

对可能存在错误的密码散列值(包括现行的Openwall Linux (Owl), SUSE和 ALT Linux上的用crypt_blowfish算法产生散列值存储的密码数据库)的管理员来说,最安全的解决方案就是使现有的所有密码失效而后要求用户重新设置密码。这简直是逻辑噩梦。不过,这取决于如何简单、安全并且不需要通过现有密码鉴权就能使用户可以设置新密码。要求用户登陆以后改变现有密码是一种替代方案,不过这可能会给攻击者可乘之机。它同时为所有未登陆的用户保留原有密码不变。

攻击者利用这一漏洞登陆一个网站的风险相当小,但却是存在。如果一个网站的登陆过程容易受到暴力攻击,那么这个bug会使这个攻击变得容易,至少对于特定的密码类型是这样的。另一方面,如果密码数据库已经暴露出来,并且一些密码没有被破解(至少对于没有使用JtR程序的攻击者),这个信息可以给他们提供破译那些密码的方法。最终的分析结论是,这是一个可以被利用的,但并不会让管理员们陷入恐慌的漏洞。

令人惊讶的是这个bug在广泛被使用的库中存在了超过了13年!到目前为止,没有人用这种方式测试它,至少没有公开。这应该给那些使用固定版本软件(包括免费的和专有的)一些警示。自由软件(crypt_blowfish已经被置于公共领域,这可能在法律上有点模糊,但是这与自由软件的理念是一致的)有更多,更容易的机会来检查和测试代码,不过,只有实实在在的测试才是有效的。

毫无疑问,bugs依旧潜伏于我们每天所依赖的各种面向安全的库中,因此,定期地、系统地测试这些类库(还有那些没有用于安全用途的代码)可以帮助我们查出bugs。虽然超过10年才发现了这一bug,但值得指出的是,在此期间它可能已经被其他人发现。攻击者显然也在做自己的测试工作,不过他们的测试结果通常不会公布出来。可能和这里讨论的情况不一样,不过应该始终认识到,公开披露一个漏洞和它被发现之间是没有必然联系的(可能在被公开之前已经有人发现了)。

Topic: sohulinux

新的连续内存分配器

A reworked contiguous memory allocator
By Jonathan Corbet
June 14, 2011

翻译:王鑫/李潇

关于分配大块儿连续物理内存的问题经常在 LWN 讨论。虚拟内存,由其性质决定了它总会将页面分散到整个系统;内核长时间运行后,可供分配的页面极少会出现一个挨一个的情况。多年来,内核开发者们处理这个问题的方式就是尽可能地避免对大范围连续内存分配的依赖。内核代码很少会试图分配超过两个的连续物理页面。

近来,关于大范围连续内存分配的需求越来越多。需求之一是超大页面数,尤其是transparent huge pages feature。另一个则是老树开新花了:硬件不能执行分散/收集DMA。任何只能对连续物理内存区域做DMA的设备(缺少I/O内存管理单元)都要求一个物理上连续的缓冲区来协同工作。这个要求通常是相对低端(stupid)的硬件的一个标志;你可以祈求这样的硬件随着时间越来越少。而我们所关注的是获得一定的能力的同时仍然保留着连续DMA要求的那些设备。比如,视频采集引擎,它能够采集完全高清的数据,然后在其上进行一系列的转换,但是它仍然会需要一个连续的缓冲区用来保存结果。高清视频的出现加剧了这个问题,那些物理连续的缓冲区现在比原来需要分配得更多,而且更难被分配了。

大概一年前,LWN 就开始关注解决这个问题的连续内存分配补丁。这个补丁集遵循着在启动时保留一大块内存的神圣而又庄严的传统,而这个的唯一目的就是为了满足大范围的分配需求。多年以来,这个技术一直被“bigphysarea”补丁所使用,或者简单地在启动内核时使用一个mem=的参数,用来留下一段未使用的物理内存。Android pmem driver也是从保留区域中分配大块内存的。这个方法当然有效,将近20年的经验足以证明它。保留内存的不利之处则在于它对其他任何想使用它的东西都是无效的;如果设备没用使用这块内存,它就简单地被闲置起来。这种内存的浪费在内核开发者和用户之间变得越来越不得心。

基于上述及更多的原因,CMA补丁从未被加入进去。尽管问题并没有被解决而且也没有开发者在其上工作,最新版的CMA补丁集看起来十分不同,虽然仍然有些问题需要解决,但是看起来本补丁集有较大的机会加入到主线中。

这个CMA分配器仍然能够同保留内存区域的方式一起工作,但那很明显不是想要的操作模式。相反,新的CMA试图维护当需要时能够创建连续大块内存的内存区域。为了那个目的,CMA依靠“migration type”机制被深度构建进内存管理代码中。

在每一个区段内,成块的页面被标记为被那些可移动的或可回收的页面使用。可移动的页面主要是那些缓存页或者匿名内存页,它们通过页表和page cache radix tree来访问。这些页的内容可以随着页表和树的更新而相应地被移动到其它地方。可回收页,则是在需要时返回给内核;它们像inode cache一样保存数据结构。不可移动页通常是那些内核拥有直接指针的页面,比如,通过kmalloc()申请的内存不能在不破坏任何东西的情况下被移动。

内存管理子系统试图将可活动页面保持在一起。如果要通过移动页面来获得掉一整块空闲内存,一个单独的固定页面就可破坏整个过程。通过将可活动页面分组,内核希望能不用遇到这个障碍就释放更多的页面,内存压缩代码目前就是依靠这些可活动页面才能工作。

CMA通过增加一个新的“CMA”迁移类型来延伸这个机制;它很像”可活动“类型,但有几点不一样。“CMA”类型比较棘手,内核不能改变被标志为CMA的页面的迁移类型。内存分配器不会从CMA区域分配固定页面,对于其他任何用途,只有当没有其他选择的时候才会分配CMA页面。如果一切顺利的话,被标志为CMA用途的内存区域只会包含可活动页面,并且有数量可观的空闲页面。

换句话说,被标志为CMA用途的内存对系统其余地方保持可用,只有一条限制,那就是它只包含可活动页面。当驱动需要一片连续的内存时,CMA分配器就在它的一个特定范围挤出足够的页面创建一个适当大小的连续缓冲区。如果在这里面的页面真正是可活动,分配器就提供驱动所需要的缓冲区。当缓冲区不再需要的时候,内存也可以被用作其他用途。

有人可能好奇为什么需要这样的机制,因为内存压缩机制就已经能够给transparent huge page创建大片物理上连续的块。那样的代码是可用的:我自己的 Linux 系统,在写这篇文章前,有大约25%被分配为大页面。这个问题的答案就是DMA缓冲区相对大页面有一些不同的要求。DMA缓冲区可能更大,例如,transparent huge page几乎在所有架构里都是2MB大小,而DMA缓冲区能有10M或者更多。如果底层的硬件足够“奇怪”的话,可能有必要将DMA缓冲区放在特定内存范围内,而CMA开发者 Marek Szyprowski看起来似乎就有这种“奇怪”硬件的需求。最终,2MB的大页面必须也有2MB的对齐,而对DMA缓冲区的对齐要求就宽松的多。CMA分配器能取得被请求数量的内存而不用过度担心严格的对齐要求。

CMA补丁集为建立内存区域和创建特定范围的“上下文”提供了一个函数集。有简单的cm_alloc()和cm_free()函数来获取和释放缓冲区。虽然如此,但预期设备驱动将不会直接调用CMA,相反,对CMA的意识将被固定在DMA支持函数里。当驱动调用函数如dma_alloc_coherent()时,CMA将自动被使用来满足要求。在大多数情况下,它应该能“正常工作”。

另外一个CMA的关注点是关于特定区域是如何设置的。目前的补丁期望在系统的board file里面做一些特殊的调用。这是一个很ARM式的方法。接下来的目的是去掉board file,这样就会发现其他东西。正如 Arnd Bergmann所指出的那样,将该信息移到设备树也不是一个选择。这其实是一个策略决策。Arnd正努力争取一些能在大部分系统工作的合理默认设置,其它一些少数系统将在后续被加进来。

最终的结果可能是,patch set至少得经过一个迭代才能进入主线。但CMA满足了以前从未遇到过的一个需求。这部分代码有潜在的可能性能够在减小对其余系统的影响的同时,让分配物理地址连续的内存变得更加可靠。看起来它似乎值得拥有。

Topic: sohulinux
订阅 RSS - sohulinux | BT的花