谢邀,这个事情有些人认为活该。我其实本来也是这么认为的,毕竟两边都是美国的事,互相批评也挺正常。
但是观察到涉事的人选之后,我个人有那么一点点不成熟的看法。
首先我用两个简单的事实说清楚:
他们的目标只是为了验证恶意代码是否能提交通过,而不是真的想搞破坏,所以当然会主动撤回。
也就是说,他们其实并没有造成实质上的伤害。
那么,为什么会有借题发挥的事情,导致了学校其它提交的正经代码通通都被撤回?
其实我也不太明白,但是看看这个教授的名字,以及这个学生的名字,我觉得有借机打压,或者被带节奏的可能性。
说到这里,我插播一下另外一件事。一部分人说,华为给Linux提交的代码少得可怜,与其声称的研发投入完全不相匹配。事实真的是这样吗?
据我的了解,并不是这样,华为提交的代码并不少。但是以华为的身份提交代码,接受度相对比较低。所以,华为有一部分代码是借助其它公司提交。这些代码确实也是华为的贡献,华为实际上的贡献比目前看到的更大。
那么,ban掉明尼苏达大学的Linux提交,这样的行为究竟是什么意思?
恶意破坏的代码,本来就不可能以学校官方身份提交,你ban掉官方身份的提交渠道,根本不能规避你所遇到的问题。
就算没有大学机构去研究Linux内核提交对于恶意代码的审核能力,难道就从来没有骇客做类似的事情?互联网上,你本来就不可能在没有完善的防御机制下生存,来自高校的学术研究类的攻击相对来说其实是最善意的一种(因为人家会主动撤回)。
实际上,Linux内核管理能持续运营这么多年,并不是吃白饭的。既然恶意代码使用了随机申请的公共邮箱作为提交身份,对付明尼苏达官方邮箱地址的提交是不相关联的。
明明没有必要,可他们还是用连坐的方式ban掉了整个明尼苏达大学,为什么?是为了给大学以压力,让整个明尼苏达大学谴责这几个科研工作者,结合这个导师的姓名,我觉得这个用意。。。
当然,我的想法仅仅只是个猜想,具体情况吗,当然大家也可以继续吃瓜,毕竟,这事情与我们并没有太直接的联系。
补充:
鉴于有很多人质疑,说他们以学校官方邮箱贡献的代码也是无用的,我放出这些被撤销的贡献,让大家看看,这190个贡献有没有可能全是无用的。
Greg Kroah-Hartman (190): Revert "net/rds: Avoid potential use after free in rds_send_remove_from_sock" Revert "media: st-delta: Fix reference count leak in delta_run_work" Revert "media: sti: Fix reference count leaks" Revert "media: exynos4-is: Fix several reference count leaks due to pm_runtime_get_sync" Revert "media: exynos4-is: Fix a reference count leak due to pm_runtime_get_sync" Revert "media: exynos4-is: Fix a reference count leak" Revert "media: ti-vpe: Fix a missing check and reference count leak" Revert "media: stm32-dcmi: Fix a reference count leak" Revert "media: s5p-mfc: Fix a reference count leak" Revert "media: camss: Fix a reference count leak." Revert "media: platform: fcp: Fix a reference count leak." Revert "media: rockchip/rga: Fix a reference count leak." Revert "media: rcar-vin: Fix a reference count leak." Revert "media: rcar-vin: Fix a reference count leak." Revert "firmware: Fix a reference count leak." Revert "drm/nouveau: fix reference count leak in nouveau_debugfs_strap_peek" Revert "drm/nouveau: fix reference count leak in nv50_disp_atomic_commit" Revert "drm/nouveau: fix multiple instances of reference count leaks" Revert "drm/nouveau/drm/noveau: fix reference count leak in nouveau_fbcon_open" Revert "PCI: Fix pci_create_slot() reference count leak" Revert "omapfb: fix multiple reference count leaks due to pm_runtime_get_sync" Revert "drm/radeon: Fix reference count leaks caused by pm_runtime_get_sync" Revert "drm/radeon: fix multiple reference count leak" Revert "drm/amdkfd: Fix reference count leaks." Revert "platform/chrome: cros_ec_ishtp: Fix a double-unlock issue" Revert "usb: dwc3: pci: Fix reference count leak in dwc3_pci_resume_work" Revert "ASoC: rockchip: Fix a reference count leak." Revert "RDMA/rvt: Fix potential memory leak caused by rvt_alloc_rq" Revert "EDAC: Fix reference count leaks" Revert "ASoC: tegra: Fix reference count leaks." Revert "test_objagg: Fix potential memory leak in error handling" Revert "ASoC: img-parallel-out: Fix a reference count leak" Revert "ASoC: img: Fix a reference count leak in img_i2s_in_set_fmt" Revert "efi/esrt: Fix reference count leak in esre_create_sysfs_entry." Revert "scsi: iscsi: Fix reference count leak in iscsi_boot_create_kobj" Revert "vfio/mdev: Fix reference count leak in add_mdev_supported_type" Revert "RDMA/core: Fix several reference count leaks." Revert "cpuidle: Fix three reference count leaks" Revert "iommu: Fix reference count leak in iommu_group_alloc." Revert "ACPI: CPPC: Fix reference count leak in acpi_cppc_processor_probe()" Revert "ACPI: sysfs: Fix reference count leak in acpi_sysfs_add_hotplug_profile()" Revert "ASoC: fix incomplete error-handling in img_i2s_in_probe." Revert "qlcnic: fix missing release in qlcnic_83xx_interrupt_test." Revert "RDMA/pvrdma: Fix missing pci disable in pvrdma_pci_probe()" Revert "usb: gadget: fix potential double-free in m66592_probe." Revert "net/mlx4_core: fix a memory leak bug." Revert "rxrpc: Fix a memory leak in rxkad_verify_response()" Revert "net: sun: fix missing release regions in cas_init_one()." Revert "agp/intel: Fix a memory leak on module initialisation failure" Revert "nfp: abm: fix a memory leak bug" Revert "power: supply: core: fix memory leak in HWMON error path" Revert "media: media/saa7146: fix incorrect assertion in saa7146_buffer_finish" Revert "ecryptfs: replace BUG_ON with error handling code" Revert "clk: samsung: Remove redundant check in samsung_cmu_register_one" Revert "fs: ocfs: remove unnecessary assertion in dlm_migrate_lockres" Revert "media: davinci/vpfe_capture.c: Avoid BUG_ON for register failure" Revert "media: saa7146: Avoid using BUG_ON as an assertion" Revert "media: cx231xx: replace BUG_ON with recovery code" Revert "RDMA/srpt: Remove unnecessary assertion in srpt_queue_response" Revert "staging: kpc2000: remove unnecessary assertions in kpc_dma_transfer" Revert "xen/grant-table: remove multiple BUG_ON on gnttab_interface" Revert "scsi: libfc: remove unnecessary assertion on ep variable" Revert "hdlcdrv: replace unnecessary assertion in hdlcdrv_register" Revert "nfc: s3fwrn5: replace the assertion with a WARN_ON" Revert "nfsd: remove unnecessary assertion in nfsd4_encode_replay" Revert "bpf: Remove unnecessary assertion on fp_old" Revert "net: caif: replace BUG_ON with recovery code" Revert "fore200e: Fix incorrect checks of NULL pointer dereference" Revert "mac80211: Remove redundant assertion" Revert "rfkill: Fix incorrect check to avoid NULL pointer dereference" Revert "pppoe: remove redundant BUG_ON() check in pppoe_pernet" Revert "net: atm: Reduce the severity of logging in unlink_clip_vcc" Revert "media: rcar_drif: fix a memory disclosure" Revert "drm/gma500: fix memory disclosures due to uninitialized bytes" Revert "gma/gma500: fix a memory disclosure bug due to uninitialized bytes" Revert "net: ixgbevf: fix a missing check of ixgbevf_write_msg_read_ack" Revert "rapidio: fix a NULL pointer dereference when create_workqueue() fails" Revert "ASoC: cs43130: fix a NULL pointer dereference" Revert "ASoC: rt5645: fix a NULL pointer dereference" Revert "ALSA: usx2y: fix a double free bug" Revert "tracing: Fix a memory leak by early error exit in trace_pid_write()" Revert "rsi: Fix NULL pointer dereference in kmalloc" Revert "net: cw1200: fix a NULL pointer dereference" Revert "net: ieee802154: fix missing checks for regmap_update_bits" Revert "audit: fix a memory leak bug" Revert "x86/PCI: Fix PCI IRQ routing table memory leak" Revert "udf: fix an uninitialized read bug and remove dead code" Revert "mmc_spi: add a status check for spi_sync_locked" Revert "PCI: endpoint: Fix a potential NULL pointer dereference" Revert "net/smc: fix a NULL pointer dereference" Revert "pinctrl: axp209: Fix NULL pointer dereference after allocation" Revert "power: charger-manager: fix a potential NULL pointer dereference" Revert "iio: hmc5843: fix potential NULL pointer dereferences" Revert "iio: adc: fix a potential NULL pointer dereference" Revert "rtlwifi: fix a potential NULL pointer dereference" Revert "net: mwifiex: fix a NULL pointer dereference" Revert "video: imsttfb: fix potential NULL pointer dereferences" Revert "video: hgafb: fix potential NULL pointer dereference" Revert "omapfb: Fix potential NULL pointer dereference in kmalloc" Revert "staging: greybus: audio_manager: fix a missing check of ida_simple_get" Revert "PCI: xilinx: Check for __get_free_pages() failure" Revert "media: video-mux: fix null pointer dereferences" Revert "thunderbolt: property: Fix a missing check of kzalloc" Revert "char: hpet: fix a missing check of ioremap" Revert "libnvdimm/btt: Fix a kmemdup failure check" Revert "tty: ipwireless: fix missing checks for ioremap" Revert "RDMA/i40iw: Handle workqueue allocation failure" Revert "usb: u132-hcd: fix potential NULL pointer dereference" Revert "usb: sierra: fix a missing check of device_create_file" Revert "scsi: qla4xxx: fix a potential NULL pointer dereference" Revert "gpio: aspeed: fix a potential NULL pointer dereference" Revert "libnvdimm/namespace: Fix a potential NULL pointer dereference" Revert "x86/hpet: Prevent potential NULL pointer dereference" Revert "staging: rtl8188eu: Fix potential NULL pointer dereference of kcalloc" Revert "thunderbolt: Fix a missing check of kmemdup" Revert "thunderbolt: property: Fix a NULL pointer dereference" Revert "media: si2165: fix a missing check of return value" Revert "scsi: ufs: fix a missing check of devm_reset_control_get" Revert "tty: mxs-auart: fix a potential NULL pointer dereference" Revert "tty: atmel_serial: fix a potential NULL pointer dereference" Revert "serial: mvebu-uart: Fix to avoid a potential NULL pointer dereference" Revert "HID: logitech: check the return value of create_singlethread_workqueue" Revert "netfilter: ip6t_srh: fix NULL pointer dereferences" Revert "spi : spi-topcliff-pch: Fix to handle empty DMA buffers" Revert "net: tipc: fix a missing check of nla_nest_start" Revert "net: openvswitch: fix a NULL pointer dereference" Revert "ALSA: sb8: add a check for request_region" Revert "net: strparser: fix a missing check for create_singlethread_workqueue" Revert "qlcnic: Avoid potential NULL pointer dereference" Revert "ALSA: usx2y: Fix potential NULL pointer dereference" Revert "net: 8390: fix potential NULL pointer dereferences" Revert "net: fujitsu: fix a potential NULL pointer dereference" Revert "net: qlogic: fix a potential NULL pointer dereference" Revert "md: Fix failed allocation of md_register_thread" Revert "net: rocker: fix a potential NULL pointer dereference" Revert "net: thunder: fix a potential NULL pointer dereference" Revert "net: lio_core: fix two NULL pointer dereferences" Revert "net: liquidio: fix a NULL pointer dereference" Revert "isdn: mISDNinfineon: fix potential NULL pointer dereference" Revert "isdn: mISDN: Fix potential NULL pointer dereference of kzalloc" Revert "libertas: add checks for the return value of sysfs_create_group" Revert "rtc: hym8563: fix a missing check of block data read" Revert "power: twl4030: fix a missing check of return value" Revert "misc/ics932s401: Add a missing check to i2c_smbus_read_word_data" Revert "leds: lp5523: fix a missing check of return value of lp55xx_read" Revert "media: dvb: Add check on sp8870_readreg" Revert "media: dvb: add return value check on Write16" Revert "media: mt312: fix a missing check of mt312 reset" Revert "media: lgdt3306a: fix a missing check of return value" Revert "media: gspca: mt9m111: Check write_bridge for timeout" Revert "media: gspca: Check the return value of write_bridge for timeout" Revert "media: usb: gspca: add a missed check for goto_low_power" Revert "media: usb: gspca: add a missed return-value check for do_command" Revert "ath6kl: return error code in ath6kl_wmi_set_roam_lrssi_cmd()" Revert "brcmfmac: add a check for the status of usb_register" Revert "serial: max310x: pass return value of spi_register_driver" Revert "Input: ad7879 - add check for read errors in interrupt" Revert "ALSA: sb: fix a missing check of snd_ctl_add" Revert "ALSA: gus: add a check of the status of snd_ctl_add" Revert "Staging: rts5208: Fix error handling on rtsx_send_cmd" Revert "staging: rts5208: Add a check for ms_read_extra_data" Revert "dmaengine: qcom_hidma: Check for driver register failure" Revert "dmaengine: mv_xor: Fix a missing check in mv_xor_channel_add" Revert "iio: ad9523: fix a missing check of return value" Revert "mfd: mc13xxx: Fix a missing check of a register-read failure" Revert "infiniband: bnxt_re: qplib: Check the return value of send_message" Revert "gdrom: fix a memory leak bug" Revert "net: marvell: fix a missing check of acpi_match_device" Revert "atl1e: checking the status of atl1e_write_phy_reg" Revert "net: dsa: bcm_sf2: Propagate error value from mdio_write" Revert "net: stmicro: fix a missing check of clk_prepare" Revert "net: (cpts) fix a missing check of clk_prepare" Revert "niu: fix missing checks of niu_pci_eeprom_read" Revert "net: chelsio: Add a missing check on cudg_get_buffer" Revert "ipv6/route: Add a missing check on proc_dointvec" Revert "net/net_namespace: Check the return value of register_pernet_subsys()" Revert "hwmon: (lm80) fix a missing check of bus read in lm80 probe" Revert "net: netxen: fix a missing check and an uninitialized use" Revert "drivers/regulator: fix a missing check of return value" Revert "net: socket: fix a missing-check bug" Revert "dm ioctl: harden copy_params()'s copy_from_user() from malicious users" Revert "ethtool: fix a missing-check bug" Revert "media: isif: fix a NULL pointer dereference bug" Revert "yam: fix a missing-check bug" Revert "net: cxgb3_main: fix a missing-check bug" Revert "virt: vbox: Only copy_from_user the request-header once" Revert "ALSA: control: fix a redundant-copy issue" Revert "scsi: 3w-xxxx: fix a missing-check bug" Revert "scsi: 3w-9xxx: fix a missing-check bug" Revert "ethtool: fix a potential missing-check bug"
简单说吧:也许你能从这190个贡献中找到那么两三处可能有问题的贡献,但绝大多数贡献,都是有意义的。
如果你想强调这个学校一贯提交无意义代码,那么请指出这 190 个贡献究竟有几个是真的没用的。
这下子这个哥们儿以后就不用浪费时间刷题了。
真特么够x的。
至于这位lu教授,以后招学生难度也会加大,谁也不喜欢带个debuff找工作的。
至于lu教授之前那个实验,不管你怎么洗他的学术意义,操作都是白嫖这个世界上最重要(没有之一)的开源项目的贡献者的时间来帮他写论文,而且还没有事先沟通。这种事基本就是人品败坏。这个比为了发论文打500次假的110来测试出警速度都要恶劣。
至于你想推销什么代码测试工具,这个世界上的开源项目成千上万,为啥刚好会选linux kernel呢?还不就是好博眼球嘛,对发论文容易嘛。这个世界上有很多的开源项目也足够活跃但是在安全性上没有那么敏感(最简单,比如hibernate和spring这种东西)。为啥偏偏是Linux kernel呢?何况你自己还不是一个kernel的常规贡献者?
最后说一下这个可笑的静态生成代码分析器的辩解,你有能耐就把这个的步骤录屏放到YouTube上,然后把tools开源掉。如果一个静态生成代码的tools就可以自动给kernel打补丁,这是人工智能的伟大突破了。
求死作死然后真死了,有什么委屈的。
没有维护过大型软件的可能不知道引入一个bug能有多可怕。
简单说吧,一个bug可能引起七八种不同的故障表现;逆着故障追查可能会找到十几种不同的“原因”——显然的,这些原因绝大多数是错的(甚至可能全都是错的)——错误修改了不是原因的原因,就可能在抑制一个错误现象的同时引入另外五六个奇怪的故障;为了修复这些故障,又造成了一堆新的bug……层层“转包”之后,可能整个系统就不再能够维护了。
你看,一旦“病从口入”、一旦被劣质开发者越改越糟,这套软件往往就可以放弃了——重新写一套说不定还便宜点。
因此,当你加入一家较为正规的公司、第一次修改bug时,那些老同事们往往就如临大敌,不得不一次次问你:你真的找到这个错误的root cause了吗?请证明你找到的是root cause……请证明除了root cause,其它错误不可能引起同样的故障……
总之,经过很多轮的“审问”,你的patch才会被评审者接受,才可以合入软件仓库、进入测试流程……
随着你合入代码次数越来越多、且一直没有引起bug(或者很少引起bug),对你的“审问”就会越来越轻松——这是因为代码评审也是非常非常消耗精力的事情:为了合入三行代码,评审者很可能不得不参考前后超过五百行代码,这才能搞懂逻辑、确认是否真的修到了root cause且没有引入别的问题。
因此,当你通过长时间的合作证明了自己的能力和工作态度之后,对你的警惕自然可以降低,这样既可以节约你的精力,也可以节省评审者的时间。
归根结底,开发是一项合作性工作,并不是对抗性的——后者实在太累了——合作模型比起对抗性模型,工作量减少百倍不止。
不管你是什么开发团队、什么工作模型,默认“求职者是来合作而不是来对抗的”是一切的基础;只有在这个基础上,各种防呆甚至防傻的设计才能派上用场——注意难度次序:防呆难防傻,防傻不防坏。
很多时候,我们只能防君子不防小人,只能靠事后的惩罚让小人不敢侵害。原因就是傻比呆更难防;而一个憋着坏的人,任何人都无能为力。
比如,评论区网友的主意:你完全可以掏高价雇一个操作系统专家,让他通过面试加入微软核心团队,专门为微软写bug。没有人能阻止你;甚至,只要他别太高调,也绝不会有人能发现他。
这是因为,哪怕对一个中等规模、更新不太频繁的软件,逐一审核也实在太难了。
而且,要审核到什么程度才够呢?
错误代码?
无意引入的bug?
有意植入的bug?
有意植入同时又尽量隐蔽起来的后门?
多个不同来源的patch组合起来才能激活的超隐蔽后门?
过去,这些靠自觉,靠后期的大量测试,也靠主动拉黑那些不诚信的提交。但这事开了一个极坏的头,借研究的名义往代码库丢垃圾,DDoS攻击审核者...
一旦开了先例,每个patch付出一百倍精力够不够?一千倍精力能确保发现精心隐藏的后门吗?
这还有办法做事吗?
因此,软件开发很多时候也需要靠“混个脸熟”。
有了足够的信任度,你提交代码就更容易被接受,双方都轻松。
换句话说:如果你真的一定要往Linux内核植入后门,那么你一定能做到。并没有可靠的办法预先识别出程序中隐蔽的错误。
但做到的前提是,你最好先持续贡献十年乃至二十年的优质代码、在社区取得较高威望;然后放弃这一切,搞个破坏。
再换句话说:软件开发领域,合作者之间的信任、交情作用极大,是一种类似于“熟人社会”的关系。
这种社会里,信任关系想要可靠,那么对“背叛者”的惩罚就必须重。
不重,每个人都会想借他人的信任牟利。
比如说,明尼苏达大学,它的代码为何容易被社区接受?
很简单,之前很多人的大量贡献为它赢得了信任。
基于这种信任,它的代码可能只需通过lint类工具检查、然后再被reviewer人工检查一遍就可以放心合入了——之后就是漫长的测试。
但现在,这些人滥用这种信任,故意提交包含bug的代码。这就把信任关系变成了对抗关系。
那么,如何处置呢?
如果轻轻放下,那么,下一次,另一所大学一个教授也往里面添加后门;然后被某个互联网大盗借此成功攻击了银行,怎么办?
人家辩解说自己是无意的,你拿不出证据,怎么办?
人家辩解说自己也不过是做测试而已,谁知道怎么那么巧就被利用了,怎么办?
很显然,这事绝不能善了。
你来对抗,那好,你就是敌人。
这是你自己选择的位置。
你凭什么获得我的信任?凭的是明尼苏达大学的邮箱。
那好,既然你这所大学站到了对抗立场,那么我当然就应该废弃你这整所大学提交的一切代码——直到你的大学赶你滚蛋、向我证明你们的非对抗性。
靠信任维持的系统里,只有对背叛者的惩罚足够严厉,才能确保不会有其它人借助信任提交对抗性代码。
就好像如果你真的雇佣了一个流氓专家给微软引入bug,那么可以预见,一旦败露,后果有二:
其一,这个专家今生再也别想在任何软件公司找到工作。没人需要一个容易被人收买的破坏者,更不可能让这种潜在的破坏者进入自己的核心团队。
第二,这个专家的雇佣者再也雇不到合格的技术人员。因为从他那里出来的人,整个业界都无法信任:万一你继续让他给我写bug呢。换句话说,被他雇过毁一生。
除非存在极其重大的利益关系,否则就不可能让任何内核级开发人员甘愿做出这么大的牺牲--毁掉自己的一生,历史上被当做人类之敌记上一笔然后遗臭万年,是个人就会掂量掂量。
也正是因为有这个反制捣乱分子的最后手段,我们才可以放心大胆的使用Windows、Linux以及五花八门的各种软件,哪怕几乎任何一款软件都出过低级错误。但起码我们可以安全的相信,这些低级错误是失误而不是故意放进去的bug。
这个逻辑的根本原因有如下几点:
1、的确没有办法100%的提前发现代码中暗藏的后门
2、的确有一些高手可以通过review找出代码中绝大多数的漏洞,但这种高手时薪一定高的吓人
3、如果任意三行代码都必须最高等级的reviewer前看五百行后看八百行……那还开个鬼源。让这位reviewer自己写不就完了。
4、考虑成本,社区自然只能借助信用等级来节约工作量
5、无法预检,可以借助信用等级免予严格审查;那么事后惩罚就必须迅速灵敏、且代价足够让任何人承受不起
这和惩治犯罪一样:既然我们没办法制定规则禁止杀人犯出生,那么就只能在他犯罪后严厉惩罚他。
这类东西如何研究?
简单,分别找月薪4000、8000、12000、16000、20000、40000美元的开发者,给他们一组代码,告诉他们代码的作用以及代码中可能有bug,然后统计不同级别的开发者人工发现了多少百分比的故障代码,完事。
当然,如果这样做——这也是他们这个研究的本质——那么最傻的人都能看出这个研究很没意义。
除了再一次证明人类hold不住极端复杂的问题(或者研究者自己水平很渣设计不出真正“微妙”的bug),没有任何意义。
或者说,作为一个社会学实验,这个实验很成功。
但如果作为一个计算机专业方面的实验,这个实验太惨了,至多算中小学课外活动级别。因为这是计算机行业从业者入行第一天就该明白的既定事实。
也正因为有意无意的在项目中引入一个甚至一堆bug本来就是无可避免之事,因此我们才不得不搞代码review、搞自动化测试、掏高价养测试团队、做专门的软件跟踪bug……
最惨的是,各路大神、业界传说级公司砸进去亿万资金研究了几十年之后,只得到了一个结论:能切实提高软件质量的唯一途径就是……从一开始就不要引入bug。
于是,现在最最成功的实践就是——测试驱动开发。
逼程序员写用例自测,甚至先写测试用例后写代码,软件质量才能提高。
这特么入行第一天的毛头小伙都懂的东西,需要你拿Linux kernel团队开涮吗?
这就是问题的本质:一群水论文的垃圾研究者滥用社区的信任,给社区、给所在学校造成了重大损失,如此而已。
就好像刑法学教授为了研究刑法,跑五角大楼门口趁警卫不注意用口香糖把几个警卫的口鼻糊上,观察他们会不会窒息,然后兴高采烈的发论文“口香糖真的能杀人哦,好酷哦”一样,你觉得这属于什么性质?
综上,求锤得锤,抱怨个鸡鸡。
这个新闻,我看到之后第一反应是:这个课题能不能通过田野实验(Field Experiment)来做?
现在这样肯定是不行的。假想一个黑客通过故意提交漏洞给Linux Kernel,如果被发现了就声称是科研,没有被发现就去利用,这样开源项目就会不胜其扰了。科研不是护身符,也不是免死金牌,也需要遵守一定的规则。
尤其是这个研究表面上看是计算机系的工程项目,其实是社会工程,是有可能造成潜在的危害的。
如果Linux Kernel是一个商业公司,这个做起来很容易。直接和和对方的管理层联系,说希望能配合做一个实验,也算是对员工进行出其不意的一次内部摸底测试。如果高层感兴趣,这事就算成了。到最后研究结果写成报告,给公司一份,然后另外就可以写成paper发表,公司获得了一点员工摸底绩效,自己获得了论文,可谓两全其美。很多经济学的田野实验也基本上就是这么做的。
但是问题是Linux是一个开源项目,它不属于任何一个人。Linus和其他的maintainer之间并不是严格的上下级关系,Linus是出于威望作为事实上的Linux Kernel项目经理,而并非是出于组织的正式任命。单独和Linus说,Linus首先未必就会同意这种研究;就算同意了,这样戏耍maintainer对Linus本人的威望也没什么好处。
如果不仅仅和Linus说,也预先的通知maintainer,那么maintainer很可能比平时更加的注意,那就起不到研究想要的效果了。这也叫做『实验室偏差』。
想来想去,唯一比较可行的,就是联系一群maintainer,然后征得他们的同意,说会随机的选一两个maintainer在一段时间内进行测验。这样虽然也可能有误差,但是只要这群maintainer足够多,时间长了,警惕性还会渐渐的回归平时的水平,这个实验就可以做了。
但是这同样有一个问题,联系一群maintainer,有的可能比较配合科研,有的可能出于程序员的尊严,认为这是对自己的侮辱,所以会拒绝。这就又造成了一个问题:那些同意的maintainer和拒绝的maintainer在水平上是不是有差距的?在同意的maintainer那里得来的数据结果和估计值,是否能够应用到拒绝的maintainer那里呢?这个『逆选择带来的内生性偏差』无解。
到目前为止,我想不出什么方法能够用现场试验的方式来做这项科研。但是这个课题也确实是有意义的——在开源软件项目中隐蔽的引入漏洞的可行性,这可能也是为什么有些研究只能用定性,无法用定量的方法研究的原因之一吧。
不少回答在说这项研究本身还是有其自身的意义的. 对不起, 我是真的不太理解这项研究的现实意义, 特别是对软件工程实践的现实意义是什么 (除了能帮 "研究者" 发几篇文章外).
在软件开发的过程中, 修复 bug 的同时有意或无意的引入了新的 bug 从来都是不可避免的事情, 无论是开源软件, 还是公司内部的项目开发, 这种情况司空见惯. 甚至修复一个危害很小的 bug 结果引入了一个更严重的 bug, 或者修复一个 bug 结果引入多个新 bug 都并不罕见. 这都是软件工程在实践中的常识, 也是任何一名代码审核人员所知的常识. 代码审核 (包括自动审核和人工审核) 只能减少这种可能性, 而不可能杜绝. 而且, 这在大多数情况下甚至都是无意的事情.
既然如此, 有意或无意的通过这种方式引入漏洞就是完全技术上可行的事情. 换句话说, "故意在提交的补丁中藏有恶意代码" 来隐秘的引入漏洞的可能性.. 它当然存在, 这种显而易见的事情, 真的需要一个助理教授带着一帮博士生去做 "实验" 证明 (还是在影响不知道多少人的 Linux Kernel 上实验) 吗?
这个事情的荒谬之处类似于, 他们在试图证明一个如下的论点: 如果我在地上挖一个坑 (如果我在修复问题的同时偷偷引入一个漏洞), 走路的人如果没有看见这个坑就会掉进坑里 (审核者如果没看出这个漏洞就会导致这个漏洞被合并).
然后, 他们真的在路上挖了一个坑, 然后看着行人掉了进去 ---- 当然, 他们又主动把那个人给拉了上来.
是的, 这个论点是正确的. 问题是这和废话有什么区别?
现实世界里的软件工程根本不可能避免这种问题, 无论是开源还是闭源. 所有的现代软件工程实践, 包括测试驱动 (TDD), 测试覆盖率要求, 结对编程, 代码审核, 持续集成等等等等, 都只能减少新 bug 或漏洞引入的可能性, 而不可能杜绝, 更不可能避免恶意开发者故意偷偷的植入漏洞. 作为研究者, 是否应该研究一些更有意义的问题, 一些对实际软件工程更有指导意义的问题, 而不是去证明 "偷偷引入漏洞的 '可能性'" 呢? 就算你证明了这一点, 它的价值何在呢? 哪个搞软件工程的人会不知道这个?
我害怕自己太断章取义了, 于是去大概看了一眼他们发的那篇文章[1]. 在这篇不包括注释长达 16 页的文章最后部分, 作者们对开源软件的开发者和维护者们都提出了一些建议.
对于开发者提出了两条建议:
(这部分我真的无力吐槽.. 凑字数吗?)
对于维护者提出了三条建议:
我理解搞科研在很多时候需要简化问题, 需要去研究真空中的球形鸡而不是现实中长着羽毛翅膀呼吸空气的珍珠鸡. 但是你不能在面对 "为什么鸡会被狼吃" 这个问题的时候, 研究半天真空中的球形鸡然后得出结论是因为球形鸡滚动的不够快所以才会被狼追上吃了, 最后提出的建议居然是珍珠鸡应该进化出两条腿来这样可以在发现狼来了的时候跑掉 ---- 虽然珍珠鸡确实会被狼吃掉, 但是珍珠鸡也确实已经有两条腿了, 即便有了两条腿, 狼来了的时候也还是跑不掉.
问: 请问需要怎样改进流程和规则, 才能保证开源社区合并的每一个修改都是安全的?
答: 做! 不! 到! (plunk)
问: 那闭源软件或内部软件呢? 总能有办法做到了吧?
答: 想得美! 都! 做! 不! 到!
andiry和量子位的回答都很明确的解释了这次的事件
我想说的是
这是一个很好的例子来说明什么叫做精致的利己主义者。
linux内核有多重要大家都知道,拿linux内核做实验发论文。
为了自己发论文,在审核方面打擦边球。
然后把整个学校拉下马。
整个事件收益的是谁,受害的是谁?
linux内核审核者是受害者,大学的声誉被害,同一所学校以前的贡献者被怀疑。
收益的只有这个教授和当事人学生,其他人都是受害者。
什么叫做精致的利己主义者,利用大家共同的利益或者名誉作为桥梁,把我的利益捞到手。至于大家共有的这些利益,以及声誉,我用完了,还有没有不重要。
这件事情,实际上和去年明尼苏达大学华人教授K.J Lu提交的一篇论文有关。
去年11月,K.J Lu教授带领的团队在向Linux内核提交补丁时,故意引入新的Bug,然后以此写论文。
在被警告过一次之后,最近竟然又有这个大学的学生提交明显无效的补丁。
于是,Linux内核的维护者Greg K-H,干脆直接把整个明尼苏达大学拉黑了。
要知道,Greg每天要审查几百个代码提交,忙的要死,中间还发现捣乱的,得是什么心情。
Greg表示,随便一个懂点C语言的人都能看出你这代码没丁点作用,别拿我们当试验对象。
你和你的团队已经公开承认故意提交bug来观察开源社区的反应,以此发表论文。现在你们又提交一系列明显错误的补丁,你叫我怎么想?
Greg放下狠话,未来任何来自http://umn.edu邮箱的提交都应被默认拒绝,还在邮件中用拟声词“嘭”表示拍桌子。
不仅如此,Greg一口气把来自这个学校邮箱的历史提交都撤销了,后面再挨个审查。
此事被Greg挂出,整个开源社区立即炸开了锅。Twitter、Reddit、Hacker News都在疯狂盖楼中。
究竟发生了什么?要从去年11月的这篇论文说起。
先看看这篇论文的标题:论通过伪君子式代码提交 (Hypocrite Commits)在开源软件中隐蔽地引入漏洞的可行性。
作者是Lu教授和他的学生Q.S Wu,他们的研究方向是操作系统、程序分析、编译器的安全问题。
Lu教授去年11月把这篇论文的摘要发在了Twitter上,引起了大家的困惑。
随后摘要被删了,只留下一个解释。
Lu教授的说法是,他们先找到一个真实的Bug A,写一个补丁A,这个补丁中却悄悄带一个Bug B。再写一个修复Bug B的补丁B一起提交,换句话说是用了两个步骤修复Bug A。
Lu教授还声称,他们将此事告知了内核管理者,让他们要么同时接受两个补丁,要么都不接受。
并且没有Linux用户因此受到伤害,最终结果是他们提交了一系列补丁修复了3个真实Bug(中间引入的新Bug都被后续补丁修复了)。
后来看到的吃瓜群众表示,你这把帖删了就留个解释,让人更迷惑了。
于是,该研究团队在12月写了一篇完整声明来澄清这件事。
声明中说到,论文的目的是提高开源软件修补过程的安全性,已被IEEE S&P 2021接受。
该团队在为Linux内核修复1000多个bug的过程中观察到了补丁过程存在一些问题。
论文验证了在提交补丁中引入新的Bug,并被开源社区接受的可能性。想呼吁大家重视这个问题、改善补丁的流程,比如开发自动测试和验证补丁有效性的工具。
所有引入Bug的补丁都只停留在邮件列表交流中,没有被采用或合并到任何Linux分支中,这一点得到了社区维护者的明确确认。
总之是为了提高开源软件安全性,没有恶意。由于没有解释清楚造成了许多争议,向大家道歉。
这种研究不可避免地浪费了社区维护者宝贵的时间,为了弥补,团队把补丁的代码改动限制在5行,并努力找出并修复了3个真实的bug。
声明中还举了之前的例子,该团队在2013年证明苹果公司的应用审查过程存在缺陷,随后苹果公司加固了系统。因此该团队相信本次研究最终也能提高Linux内核的安全性。
最关键的是,这项研究已经得到了明尼苏达大学伦理审查委员会(IRB)的豁免(Exempt)。
IRB认为,研究对象不是人类行为,不属于人类研究(Human Research)。
研究过程中没有收集任何个人信息。
研究目的是揭示过程中存在的问题,而不是指责任何开源社区维护者。
但这,怎么就让整个明尼苏达大学被Linux社区拉黑了呢?
时间来到今年4月。
4月6号,明尼苏达大学一个名为Aditya Pakki的在读博士生,给Linux内核提交了一个小补丁。
这个补丁看起来很简单,似乎也能提高代码质量,起初曾获得了几个社区成员的批准。
然而,4月9日,谷歌首席软件工程师、社区成员之一Eric Dumazet很快发现不对,并指出了代码存在的问题。
4月19日,Linux内核社区的贡献者之一Al Viro在看过代码后,非常生气,表示这个补丁的提交者“不是对代码一窍不通的话,就是故意的。”
之所以会做出这样的判断,是因为这名提交代码的博士生Aditya Pakki,恰好也在明尼苏达大学K.J Lu教授的小组中。
而K.J Lu教授带领的团队,正是之前给Linux内核社区提交过“垃圾代码”、来进行“分析开源软件漏洞”研究的团队。
这事一出,社区成员Leon Romanovsky发现,这位博士还提交了3个类似的补丁。
他表示这四个补丁均带有严重的安全漏洞,其中好些已经进入了稳定分支。
现在,这些补丁正在被移除。
对此,Aditya Pakki在4月21号回应此事,表示研究人员的态度明显是“先入为主”:
希望您能停止这样近乎疯狂的指控,这近乎于诽谤。我们并不是Linux内核专家,在发送这些补丁时,也希望得到反馈……既然你们如此不待见,我不会再发送任何补丁了,而且,你们这种态度对新人和非专业人士很不友好。
这番言论惹怒了Linux内核管理员Greg。
他表示,自己将会禁止明尼苏达大学对Linux内核做出贡献,并会取消这一研究小组此前所有的贡献,因为这些提交“显然都是恶意的行为”。
Greg在社交媒体上表示:“这样做是浪费开源社区的时间,Linux内核开发者们不喜欢被试验。”
那么,为什么要拉黑整个明尼苏达大学呢?
社区认为,明尼苏达大学竟然会让这种研究获得IRB Exempt,证明学校并不在乎开源社区、甚至可能是故意的。
现在,明尼苏达大学计算机科学与工程系官方已出面调查此事:
我们立即暂停了这项研究,目前正在调查这项研究所用的方法、以及研究的审批过程,以采取适当补救措施,防止将来发生其他问题。调查结果将尽快反馈给社区。
具体来说,将会重新调查这一研究获得IRB的过程,是否具有争议。
目前,K.J Lu教授已经针对此事进行回应:
抱歉这件事引起了极大的关注度,上次有关“分析开源软件漏洞”的研究,已在2020年11月份结束。这次提交的错误代码,来自一个新项目,并非我们有意为之。
针对这件事本身,高级Linux内核开发、谷歌工程师Ted t’so认为,之所以这件事情爆发这么大热度,最关键的问题在于,Lu教授和他的团队并未对自己此前的研究表示愧疚:
更糟糕的是,明尼苏达大学的IRB机构认为,Lu教授的研究不属于人体试验,因此不受控制。这样的话,禁止全校对Linux内核社区做贡献,可能是唯一的选择。
据ZDNet报道,不少Linux社区的开发者和管理员,都持有这样的看法。
针对教授研究的内容本身,Red Hat的科技策略分析师Jered Floyd则认为,关于“分析开源软件漏洞”的这项研究,确实“不太道德”:
这已经不仅仅是“被试验”了。就像是你自称“安全研究员”,但却去汽车维修店里剪断了所有汽车的刹车线,看看有多少人会遇上撞车事故。
针对大学的机制,也有网友表示,部分大学的IRB审查机制,还应该进一步完善:
有的学校审查机制真的很严格,有的却根本不太管这些事情。
当然,也有网友认为,Linux也应该采取更安全的方式进行代码贡献:
在这件事情中,双方都应该汲取教训。
争议论文:
https://github.com/QiushiWu/QiushiWu.github.io/blob/main/papers/OpenSourceInsecurity.pdf
对论文的声明:
https://www-users.cs.umn.edu/~kjlu/papers/clarifications-hc.pdf
参考链接:
[1]https://cse.umn.edu/cs/statement-cse-linux-kernel-research-april-21-2021
[2]https://www.zdnet.com/article/greg-kroah-hartman-bans-university-of-minnesota-from-linux-development-for-deliberately-buggy-patches/
[3]https://news.ycombinator.com/item?id=26887670
[4]https://lore.kernel.org/linux-nfs/YH%2FfM%2FTsbmcZzwnX@kroah.com/
—完—
@量子位 · 追踪AI技术和产品新动态
深有感触的朋友,欢迎赞同、关注、分享三连վ'ᴗ' ի ❤
很多人还真搞不懂Linux内核在现在的整个计算机世界中的重要性,它已经真的是大而不能倒的存在了。
明尼苏达大学的伦理审查人员估计没有计算机出身的,甚至可能只有一小部分人用过桌面版Linux,没有人意识到这东西出了问题时的严重性。
你未经同意,去通过攻击别人商业公司的生产代码库来做研究发文章,出了问题就是妥妥的刑事犯罪,不出问题也可能是刑事犯罪。但是像开源社区这样在法律层面比较软的柿子,不知道还有没有其他人捏过呢?
从现有的信息看来,UMN牵扯到此事中的有三人,导师Kangjie Lu, 学生Qiushi Wu,Aditya Pakki。
Kangjie Lu的实验室共提交过三类kernel patch:
Experiment overview. In this experiment, we leverage
program-analysis techniques to prepare three minor hypocrite
commits that introduce UAF bugs in the Linux kernel. The
three cases represent three different kinds of hypocrite commits:
(1) a coding-improvement change that simply prints an error
message, (2) a patch for fixing a memory-leak bug, and (3) a
patch for fixing a refcount bug. We submit the three patches
using a random Gmail account to the Linux community and
seek their feedback—whether the patches look good to them.
他们的具体做法是先使用 random gmail 伪装成无害的 committer,提交 patch ;然后等 maintainer ACK 了,再发一封邮件去撤回:
e.g., an email reply indicating “looks good”, we immediately notify the
maintainers of the introduced UAF and request them to not
go ahead to apply the patch. At the same time, we point out
the correct fixing of the bug and provide our correct patch.
In all the three cases, maintainers explicitly acknowledged
and confirmed to not move forward with the incorrect patches.
All the UAF-introducing patches stayed only in the email
exchanges, without even becoming a Git commit in Linux
branches.
按他们的说法,这三个patch没有真正进入过Linux kernel。但是这也是单方面的说法,因为无法查证:提交时用的并不是UMN邮箱,而是随机的 gmail 邮箱,估计整个 thread 里面都不会出现UMN邮箱地址。如果他们要想证明自己,那就需要把那三个patch的所有邮件提交记录都发出来,证实他们及时发送了提醒邮件以及maintainer及时NACK了这些恶意patch。
3. 引爆本次事件,由Aditya Pakki使用真名和UMN邮箱提交的patch。这些patch有没有引入恶意bug呢?根据Aditya所说,是没有的,或者说不是故意的,只是他写的一个很烂的静态分析工具分析出来的。但是根据这封邮件所说,Aditya确实提交了包含恶意安全漏洞的patch,并且已经被接受:
They introduce kernel bugs on purpose. Yesterday, I took a look on 4
accepted patches from Aditya and 3 of them added various severity security
"holes".
假设maintainer说的是真的,这事可以有两种解释:要么Aditya的analysis tool太烂了,生成了有安全漏洞的patch,而Aditya未经确认就提交了这些patch;要么Aditya说了谎,他有意的提交恶意patch,并且也没有发送任何提醒邮件给maintainer让他们拒绝。Aditya认为是前者,而GregKH和其他maintainer认为是后者,因为这些patch的模式看起来不像是由工具生成的。这事的真相只有Aditya,也许还有他的导师Kangjie Lu知道。
我认为Kangjie Lu现在应该做四件事:
Linux kernel作为一个全球性质的开源项目,开发者与维护者之间既不认识,也没有利益上的往来,可以说是完全的陌生人。双方的合作完全建立在信任的基础上:维护者相信开发者的动机是改善Linux kernel的质量,而开发者需要证明自己不会辜负这种信任。这种信任是需要小心的去维护的。如果没有了这种信任,那么kernel的开发成本将高昂到不可想象:维护者必须假定每个提交都可能带有恶意,并且进行安全上的审查,而真正的工作将被这些安全审查挤到角落里。对于Linux kernel这样一个如此庞大,提交如此之多,maintainer又人手不够的项目,这样的做法是不现实的,现阶段也没有什么好的改进手段。这也是为什么maintainer对Oakland paper嗤之以鼻的原因:他们认为Kangjie Lu的项目在未经他们同意的情况下耗费他们的时间,结果只是得出了一个他们早就知道,类似于1+1=2的结论。Oakland paper的实验是否真正引入了恶意bug并不是重点:这个实验本身极大地削弱了,或者说完全摧毁了kernel community对Kangjie Lu实验室乃至UMN的信任。而这次Aditya Pakki的火上浇油行为,彻底让事情落到无法收拾的地步。
顺便一提:
从道理来说,早减晚增本身是没啥毛病的,毕竟只是个选项,丰俭由人。
大家怕的是某些人通过这些选项,再加点私货。而且这个说法和推迟退休一起出来,由不得大家多想。
按照目前的舆论情况,如果你敢允许早退减拿,估计只要不在体制内的人就统统早退了,反正也没啥规定领了社保就不能接着打工,对吧?甚至还可以把原来交给社保的那块放自己口袋。
所以,让你早退减拿是不可能的,忽悠大家晚退多拿的可能性比较大。