电脑系统为Ubuntu,用有线接入南大的校园网,发现每次开机之后都只有ipv4地址而没有ipv6地址。

  • 同设备Windows无此问题,排除硬件和学校网络的问题。
  • 换了另外一个电脑(也是Ubuntu),问题一样,排除配置错误和偶然问题。

不过,只需要每次开机后关-开一下网络,就会获取到ipv6地址,因此用了一年的笨办法,在crontab中配置开机60秒后自动service network-manager restart

最近发现这个问题原来是因为学校网络的DHCP地址分配速度太慢,导致系统开机向DHCP申请分配地址时,等了很久才只获得了ipv4地址,于是Ubuntu决定不再等了,反正没有ipv6有不是不能用(放屁,众所周知校园网ipv6不需要登陆账号就能直接用)。

新的解决方法说来也简单,只需要告诉Ubuntu别只等到ipv4就认为大功告成,没ipv6就继续等待和重试。

具体步骤如下:

  1. 获取当前连接的UUID

    nmcli connection show

    输出如下

    NAME        UUID                                  TYPE      DEVICE 
    有线连接 1  df43dd98-4443-3f03-9893-f1cd2b39d2a6  ethernet  enp3s0

    可能不止一个,根据名字记住所需要配置的连接的UUID。

  2. 禁止在未获取ipv6地址之前就结束网络连接尝试

    sudo nmcli connection modify <连接的UUID> ipv6.may-fail no
    sudo nmcli connection modify <连接的UUID> ipv4.may-fail no

    原理上,只需要配置ipv6.may-fail就足够,不管我不想试了,反正这样能用。

此后,每次开机系统会等待稍长一些时间才会进入网络已连接的状态,不过就已经直接具有ipv6地址了。

1. 系统与内核的关系

计算机科学语境中,内核即操作系统,kernel = OS,它直接与硬件交互、管理各种资源、调度其他进程。

日常语境中,操作系统是内核加上其他一些工具套件(如Windows的文件浏览器、控制面板、IE)组成的集合kernel ⊂ OS

虽然从用户的角度,那些“系统自带”的套件和普通的用户软件在信任程度、控制权限以及重要性方面都有很大差别,但是从内核的角度来说,这些套件其实和普通的程序其实是平等的,都只是内核调度之下的普通用户态程序。

阅读全文 »

下文中的Python指的是在官方cpython解释器上实现的Python 3.8

1. 一切皆对象

Python之中一切皆对象,更具体些说一切都是指向对象的指针(虽然Python本身并无指针的概念)。

这一点Python远比Java更为激进,Java虽然也有“一切皆对象”的口号,但是至少intdouble等基础类型就不是以对象的形式存在,且对象的方法作为对象的子组件自然也不是对象。但是在Python中则连最基本的整数值是以对象,对象中的方法本身也是另一个对象。可以说是名副其实地做到了一切皆是对象。

2. 连类型也是对象

C++明确区分了类型和对象,前者是一个理念中存在的形式,后者是绑定了特定存储空间的一个内容。

Java中对类型虽然也是都是java.lang.Class类的对象,但是除了反射等少数使用场景,类型和对象之间通常也是泾渭分明的。

而到了Python中,二者却已经到了难分难解的地步了。类型可以像普通对象一样建立、修改、销毁,唯一不同的只是可以产生对象。因此Python中将能产生对象的对象(亦即类型)称为类型对象(定语类型表示其特征,中心语对象表示一切皆对象的本质),其他的对象(寻常所言对象)称为实例对象。

阅读全文 »

下文中的Python指的是在官方cpython解释器上实现的Python 3.8

1. Python也有编译器

一般的观点中常将编程语言分为编译执行解释执行两类,C/C++是最典型的编译执行,而Python被视为最典型的解释执行。

典型以Java为例,二者并非泾渭分明,

graph LR
source(*.java) --javac--> bytecode(*.class)
bytecode --java--> result(程序输出)
  • 第一步中,编译器javac把源文件编译成字节码文件,这一步像是编译型语言,只不过输出不是CPU指令,而是虚拟机指令(所谓跨平台的原因再此)。
  • 第二部中,解释器java(或者说虚拟机JVM)负责执行字节码,产生实际程序效果。

Python其实也和Java一样,存在编译字节码和对字节码进行解释执行两步。只不过,Java的编译部分通常在开发者机器上完成,解释部分在用户机器上运行;而Python中这两步统统运行在用户机器上,编译发生在解释执行的前一刻(即Just In Time编译),编译器嵌入在解释器内部,对开发者和用户透明。通常唯一让使用者察觉到Python字节码存在的现象便是__pycache__文件夹,这个文件夹中缓存了被import的模块的字节码,以便加快执行速度。

阅读全文 »

河西 关中 山西 河北 辽东 山东 川蜀 江南 事件 西晋 280年,晋灭吴,三国结束 成汉 301年,李特起兵 304年,刘渊起兵 前凉 汉赵 慕容鲜卑 汉赵 东晋 311年,永嘉之乱
316年,司马睿即位
后赵 319年,刘曜改汉为赵,石勒自立 后赵 前燕 329年,后赵石勒灭前赵
337年,慕容皝自称为燕王
346年,桓温灭成汉 冉魏 段齐 349年,石虎死
350年,秦齐自立,冉魏诛羯
前秦 351年,冉魏灭后赵
352年,慕容儁灭冉魏称帝
355年,前燕取段齐
376年,前秦苻坚统一北方 后凉 西秦 西燕 383年,淝水之战,前秦分崩 后秦 后燕 394年,后秦灭前秦,后燕灭西燕 北凉 南凉 北魏 南燕 397年,后凉动荡
同年,北魏夺燕冀州地
398年,慕容德自立南燕
西凉 400年,李暠立北凉,后秦灭西秦 北燕 谯蜀 403年,后凉降于后秦
405年,谯纵自立于蜀
407年,赫连勃勃建胡夏
409年,西秦复国,冯跋立北燕
西秦 胡夏 410年,刘裕灭南燕
413年,朱龄石灭谯蜀
414年,西秦灭南凉
417年,刘裕灭后秦而返
北魏 420年,刘裕篡晋
421年,北凉灭西凉
439年,北魏统一北方
阅读全文 »

AFL(american fuzzy lop)最初由Michał Zalewski开发,和libFuzzer等一样是基于覆盖引导(Coverage-guided)的模糊测试工具,它通过记录输入样本的代码覆盖率,从而调整输入样本以提高覆盖率,增加发现漏洞的概率。其工作流程大致如下:

  1. 从源码编译程序时进行插桩,以记录代码覆盖率(Code Coverage)
  2. 选择一些输入文件,作为初始测试集加入输入队列(queue)
  3. 将队列中的文件按一定的策略进行“突变”
  4. 如果经过变异文件更新了覆盖范围,则将其保留添加到队列中
  5. 上述过程会一直循环进行,期间触发了crash的文件会被记录下来

AFL流程

阅读全文 »

被测程序在启用libFuzzer并编译链接后,即成为了一个可接受用户参数的命令行程序,直接执行程序便是启动测试。

1. 命令统一格式

一般格式:

./fuzzer -flag1=val1 -flag2=val2 ... dir1 dir2 ...

flags代表各个控制测试过程的选项参数,可以提供零到任意个,但必须是严格的-flag=value形式,并不是很符合unix命令行习惯:

  • 选项前导用单横线,即使选项是一个词而非单个字符
  • 选项必须要提供对应的值,即使只是一个开关选项如-help,必须要写作-help=1,且选项与值中间只能用等号,不能用空格。

dirs表示语料库目录,它们的内容都会被读取作为初始语料库,但测试过程中生成的新输入只会被保存到第一个目录下。

阅读全文 »

官方文档地址

根据官方定义:libFuzzer is in-process, coverage-guided, evolutionary fuzzing engine.

其本身是llvm项目的一部分,和clang是亲兄弟,二者项目源码分别可见于https://github.com/llvm/llvm-project/tree/master/compiler-rt/lib/fuzzerhttps://github.com/llvm/llvm-project/tree/master/clang,就在同一个仓库里面。

现在稍微新的版本的clang都已经内置libFuzzer了,所以Linux下直接apt install clang就安装完事了。

1. Fuzz Target

libFuzzer要求实现一个fuzz target作为被测对象的接口。

官方文档中的代码示例如下:

// fuzz_target.cc
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
DoSomethingInterestingWithMyAPI(Data, Size);
return 0; // Non-zero return values are reserved for future use.
}

给的是个C++的源码,但实际上却通过extern "C"指定采用C风格的编译约定。所以实际上fuzz target的C语言原型如下:

int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);

名称参数返回值类型都不能动,并且注意参数中传来的字节数组Data是通过底层const修饰了的,也就是不允许修改其中数据。

fuzzer target(即LLVMFuzzerTestOneInput函数)目的是作为被测对象与libFuzzer库之间的一个中转接口,其作用在于接受libFuzzer提供的输入数据Data字节串,(可能还需要进行数据格式转换,)然后传递给实际的被测函数(如上述示例中的DoSomethingInterestingWithMyAPI)。

阅读全文 »

数据引用:bilibili AV5711740视频结束部分

纪年:

显示选项:

点击操作:

年份 事由 {{position}}
{{'前' + -record['西元'] + '年'}} {{record['纪年']}} {{'(共' + (records[index + 1]['西元'] - record['西元']) + '年)'}} {{record['事由']}} {{record['将佐'][position]}}