博客

PyPy 计划去掉 GIL

http://morepypy.blogspot.com/2011/06/global-interpreter-lock-or-how-to-kill.html
强烈推荐去原文阅读底下的讨论

翻译:马少兵/刘晓佳

在 EuroPython 会议上,Armin Rigo,也就是我本人,已经提过,PyPy 计划删除已经臭名昭著的全局解释器锁,那个妨碍 CPython 多线程并发能力的东东。

Jython 很久以前已经去除了 GIL。它非常小心地给所有 mutable 内置类型加锁,从而达到目的;由于依赖的底层 Java 平台可以较有效的完成实现,这种情况下效率比 CPython 里通过类似的机制达到 GIL-less 要快。另外,“非常小心地”,我的意思是非常非常小心地;例如‘dict1.update(dict2)’,需要同时锁住dict1和dict2,但一个粗糙的实现,也许会导致另一个线程执行‘dict1.update(dict2)’时进入死锁。

PyPy,CPython 以及 IronPython 都依赖 GIL。现在我们正在考虑一种不同于 Jython 这种加锁的机制,而是用 Software Transactional Memory 来去掉 GIL。STM 是计算机科学的一个最新发展,给出了一种不同于锁机制的很好的解决方案。下面通过一个简短的例子说明

假设你想通过pop方法从list1中得到值,并且利用append将该值附加给list2,函数如下:

def f(list1, list2):
x = list1.pop()
list2.append(x)

f 并不是线程安全的(甚至在有 GIL 的情况下也是如此)。假设你在thread1中调用f(l1,l2),在thread2中调用f(l2,l1)。你期望线程之间互相之间是没有影响(x将从一个list移动到另外一个,然后返回),但最后结果也许是两个列表的数据发生了交换,这个取决于并发时候的时间顺序。

通过一个全局锁可以防止该错误:

def f(list1, list2):
global_lock.acquire()
x = list1.pop()
list2.append(x)
global_lock.release()

另外一种更好的方法就是将相关的list进行加锁:

def f(list1, list2):
acquire_all_locks(list1.lock, list2.lock)
x = list1.pop()
list2.append(x)
release_all_locks(list1.lock, list2.lock)

第二种解决方案就是 Jython 的模型,而第一种是以Cpython为模型的。的确我们可以看出,在 CPython解释器中,我们获得GIL,执行一个字节码(或者执行100个字节码)以后,然后释放该锁;然后重复上述过程

第三种方案是STM:

def f(list1, list2):
while True:
t = transaction()
x = list1.pop(t)
list2.append(t, x)
if t.commit():
break

在这种解决方案下,我们首先需要创建一个事务对象,然后在所有的读写list操作中使用它。上面我们介绍了几种不同的模型,下面我们主要对STM做详细的介绍。在一个事务处理期间,我们不需要改变全局内存,相反使用一个局部线程的事务对象,存储它到一个可以进行读写操作的地方。在这个事务结束前,我们利用“commit”方法提交它。提交的过程可能由于其他的提交此时也在进行而失败,在这种情况下,事务将中止,且必须重新开始。

正如前两个方案分别是CPython和Jython模型, STM方案看起来像是PyPy未来将采用的模型。在这种模型中,解释器会启动一项事务,操作字节码,然后关闭事务,反复这样下去。这与在CPython使用GIL非常类似。特别是,这意味着它给程序员做出和GIL模式一样的保证。唯一的区别是,只要代码不会互相干扰,就能够真正并行运行多个线程。(当然如果你需要的不仅仅是GIL而是多线程程序中的锁,即使有了STM你还是需要获得锁。如果你希望用类似 STM 的机制来避免使用锁的话,也许可以用额外的内建模块将 STM 暴露给Python程序,不过那就是另一个问题了)

为什么不把这种思想应用到CPython中呢?因为这样做的话,我们可能会改变一切。你也许已经注意到了,在上面的例子中,我们不再调用list1.pop()函数,改为调用list1.pop(t);这种方式说明为了实现事务性的完成任务,所有方法的实现都需要改变。这意味着为了避免改变全局内存,必须用 transcation object 记录改变。如果我们的解释器像CPython一样用C写,那么我们需要显式的在每个地方写。相反,如果我们如PyPy那样用高层语言写,我们可以加入这种行为,把它作为解释规则的一部分,然后在需要的地方自动应用。而且,还可以提供一个解释期选项:你可以得到GIL版本“pypy”,或者STM版本。STM 由于增加了额外记录可能会变得更慢。(有多慢?我无法提供线索,但可以猜一猜,也许会慢2-5倍。如果你有足够的CPU内核,只要扩展性够出色,那不是问题。)

最后需要注意:由于STM的研究是最近的事(始于2003年),现在并不确定它的几个变种之中哪个更好。就我目前所了解的,“A Comprehensive Strategy for Contention Management in Software Transactional Memory”[PDF] 看起来是最美好的一种可能,在各种情况下都还不错。

那么什么时候能实现呢?我无法确定。现在仍旧处在创意阶段,不过我想会实现的。需要花多久来写呢?也没有线索,不过我们认为得几个月而不是几天。我打算在9月1日欧洲之星当前的赞助到期后,我就开始全职做这件事情。目前我们打算通过 crowdfunding 的模式融资支持我的全职工作。可能很快就有一篇相关的博客发表,看起来这会是 crowdfunding 的一个很好的案例——我相信至少有数千人愿意花10欧元来去掉GIL。下面就等着我们的消息吧

Topic: 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

关于 node 的几个消息

1. 0.6 稳定版本将在2个月后发布
2. 下周,0.5.1 将发布,届时应该会有一个 node.exe 供 win32 用户直接使用

3. 0.5.0 目前在 RHEL5 上编译还有些问题,主要是缺省指定了对 glibc2.7 的依赖,需要这个patch:http://groups.google.com/group/nodejs/attach/2d64ca4f8e220782/0001-Detect-availability-of-newish-linux-syscalls-by-kern.patch?part=2

Topic: 技术

让静态分析更容易些

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
订阅 RSS - 博客 | BT的花