手把手教你如何给『Linux』打补丁

手把手教你如何给『Linux』打补丁

前言

我们在参与某些开源项目的过程当中,经常会遇到漏洞之类的问题,需要我们打补丁解决。尤其是 Linux 源码,源码代码量较多,在修改完内核并发布新内核的时候,基本采用补丁的方式进行发布,而不是将整个内核打包发布

我们使用补丁发布有很多好处

补丁体积很小,方便成员获取补丁方便保存,本地可以保存多个版本内核使用方便快捷,直接将补丁放到源码对应目录,然后执行相应命令即可

注:博主本人并没有给 linux 提过补丁,本文仅为学习提交补丁的记录,希望对大家有帮助,勿喷

如果了解这方面的佬,也欢迎评论区交流

diff / patch

生成补丁

我们以经典的 linux 0.11 版本源码为例,假如说我们当前目录下有两个源码文件夹,未经修改的源码文件夹为 linux-0.11,以及修改完毕的补丁源码 linux-0.11-new

注:linux 0.11 是早期的 Linux 内核版本,发布于 1991 年,相当古老,仅供学习使用,但是工程上已经没有使用价值,最新版内核可以到下方的源码库寻找

linux 源码库:torvalds/linux: Linux kernel source tree (github.com)

linux 0.11 源码库:karottc/linux-0.11: the source code of linux-0.11 for study linux kernel (github.com)

我们可以拉取两份 linux 0.11 源码,其中一份保持原样,另外一份做出相应修改,并且重命名文件夹为 linux-0.11-new

注:我这里拉取源码时使用参数 --exclude=.git 排除 .git 文件夹,防止后续打补丁干扰。如果 git 版本过低,没有该功能,可以先克隆,再删除文件夹

scss

复制代码

git clone --exclude=.git git@github.com:karottc/linux-0.11.git

或者是

bash

复制代码

git clone git@github.com:karottc/linux-0.11.git

git clone git@github.com:karottc/linux-0.11.git ./linux-0.11-new

rm -rf linux-0.11/.git

rm -rf linux-0.11-new/.git

然后使用下面的 diff 命令,输出原始源码和修改之后的源码的文件区别,并重定向输出到 linux.patch 补丁文件中

arduino

复制代码

sudo diff -uprN linux-0.11/ linux-0.11-new/ > linux.patch

注:.patch 为约定俗称的补丁文件扩展名,尽量遵守规范,除此之外名字可以随便起

参数解释:

-u: 生成统一格式的差异输出,通常用于生成补丁文件。-p: 在差异输出中显示更多的上下文信息,以方便阅读。-r: 对目录进行递归比较,而不仅仅比较单个文件。-N: 当比较的文件是空文件时,也显示差异信息。

使用补丁

我们可以直接在当前目录下执行如下打补丁命令

复制代码

patch -p0 < linux.patch

注:-p 参数代表忽略哪级文件路径,0 标识去掉全路径,1 标识去掉第一层路径

或者是进入未经修改的 linux 源码根目录下执行如下打补丁命令

bash

复制代码

patch -p1 < ../linux.patch

注:这里的重定向符号大家注意不要写反,我开始就写反了,然后执行命令后系统就会卡死,不会报错,但是也不会终止

我这里简单作为示例,仅修改了 README.md 文件

举例解释 -p 参数,比如说 patch 文件片段如下

sql

复制代码

--- old/modules/pcitable Mon Sep 27 11:03:56 1999

+++ new/modules/pcitable Tue Dec 19 20:05:41 2000

如果使用参数 -p0,那就表示从当前目录找一个叫做 old 的文件夹,再在它下面寻找 modules/pcitable 文件来执行 patch 操作

而如果使用参数 -p1,那就表示忽略第一层目录(即不管 old),从当前目录寻找 modules 的文件夹,再在它下面找 pcitable

最后我们可能出现冲突,通常是因为原始文件已经被修改过,这时我们只需要手动解决这些冲突,然后重新执行补丁即可

注:但是建议最好不要手动修改原版代码,不然后续改比较麻烦

撤销补丁

我们可以执行如下命令撤销补丁

复制代码

patch -Rp0 < linux.patch

或者是进入未修改源码根目录,然后执行如下命令

bash

复制代码

patch -Rp1 < ../linux.patch

单文件补丁

上面是对于整个文件夹打补丁,下面将会讲解如何对单个文件打补丁

使用单独文件依次打补丁,可以更加有效的验证补丁正确性,方便后续进行功能测试

比如说我们当前目录有原文件 a.c ,修改之后的文件 b.c,我们可以使用如下命令生成补丁文件

css

复制代码

diff -u a.c b.c > test.patch

bash

复制代码

# 使用补丁

patch a.c < test.patch

# 撤销补丁

patch -RE < test.patch

quilt

简介

当我们在开发自己项目的过程中,可能会只制作大量补丁,管理这些数量庞大的补丁会非常耗费时间

所以 linux 内核开发者 Andrew Morton 开发出 quilt 补丁管理工具,以帮助我们更好的管理补丁

官方相关文档

quilt-doc.dvi (shakthimaan.com)Linux Kernel Configuration - Managing Your Patches With quilt (linuxtopia.org)quilt man | Linux Command Library

本章将会简单讲解 quilt 使用流程,更多详细信息可以查看上方官方文档

使用

只要我们在源代码树里使用了 quilt 命令,quilt 就会在源代码树的根目录建立两个特殊目录:patches 和.pc

patches 文件夹下为管理的补丁文件

.pc 文件夹下保存着其内部工作状态

可以使用如下命令安装

arduino

复制代码

sudo apt-get install quilt

新建补丁文件

arduino

复制代码

quilt new xxx.patch

补丁文件关联修改文件,关联后即可对文件进行修改,如要关联多个文件,重复添加然后修改即可

csharp

复制代码

quilt add file

查看补丁是否正确

复制代码

quilt diff

保存补丁,之后补丁文件会保存在 patches

复制代码

quilt refresh

git

git 提供了两种补丁方案

git diff 生成的 .diff 文件git format-patch 生成的 .patch 文件

git diff 生成的文件不含有 commit 信息,可以指定文件生成 diff,也可以指定单个 commit, 多个 commit 生成

git format-patch 生成的 .patch 文件 含有 commmit 信息,一个 commit 对应一个 patch 文件

注:本章将会简单讲解 git 补丁流程,如果您需要更详细的文档说明,博主会将在每小章开头附上 git 官网文档链接,供您参考

git diff

官方文档:Git - git-diff Documentation (git-scm.com)

制作补丁命令如下

bash

复制代码

# 单独文件补丁

git diff Test.java > test.patch

# 所有文件补丁

git diff > test.patch

指定 commit id 制作补丁

bash

复制代码

git diff [commit sha1 id] [commit sha1 id]> test.patch

git format-patch

官方文档:Git - git-format-patch Documentation (git-scm.com)

制作当前分支超前于指定分支提交的补丁

注:命令示例即为制作超前于 master 分支的补丁

lua

复制代码

git format-patch -M master

制作某次提交以后的补丁

python

复制代码

git format-patch [commit id]

某两次提交之间补丁

python

复制代码

git format-patch [commit sha1 id]..[commit sha1 id]

应用补丁

检查补丁文件

bash

复制代码

git apply --stat xxx.patch

检查能否应用成功

css

复制代码

git apply --check xxx.patch

使用补丁

css

复制代码

git am --signoff < xxx.patch

但是可能会出现我们上面提到的冲突,导致使用补丁失败,出现如下错误

vbnet

复制代码

$ git am PATCH

Applying: PACTH DESCRIPTION

error: patch failed: file.c:137

error: file.c: patch does not apply

error: patch failed: Makefile:24

error: libavfilter/Makefile: patch does not apply

Patch failed at 0001 PATCH DESCRIPTION

When you have resolved this problem run "git am --resolved".

If you would prefer to skip this patch, instead run "git am --skip".

To restore the original branch and stop patching run "git am --abort".

解决冲突

使用下面命令自动合并不冲突代码,保留冲突部分

执行后会生成后缀为 .rej 的文件,保存没有合并进去的部分的内容,可以参考这个进行冲突解决

解决完冲突后删除后缀为 .rej 的文件,然后提交代码到源码库即可

​最后

为了帮助大家更好的学习网络安全,小编给大家准备了一份网络安全入门/进阶学习资料,里面的内容都是适合零基础小白的笔记和资料,不懂编程也能听懂、看懂,所有资料共282G,朋友们如果有需要全套网络安全入门+进阶学习资源包,可以点击免费领取(如遇扫码问题,可以在评论区留言领取哦)~

😝有需要的小伙伴,可以点击下方链接免费领取或者V扫描下方二维码免费领取🆓

👉CSDN大礼包🎁:全网最全《网络安全入门&进阶学习资源包》免费分享(安全链接,放心点击)👈

1️⃣零基础入门

① 学习路线

对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。

② 路线对应学习视频

同时每个成长路线对应的板块都有配套的视频提供:

因篇幅有限,仅展示部分资料

2️⃣视频配套资料&国内外网安书籍、文档

① 文档和书籍资料

② 黑客技术

因篇幅有限,仅展示部分资料

👉CSDN大礼包🎁:全网最全《网络安全入门&进阶学习资源包》免费分享(安全链接,放心点击)👈

3️⃣网络安全源码合集+工具包

4️⃣网络安全面试题

5️⃣汇总

所有资料 ⚡️ ,朋友们如果有需要全套 《网络安全入门+进阶学习资源包》,扫码获取~

👉CSDN大礼包🎁:全网最全《网络安全入门&进阶学习资源包》免费分享(安全链接,放心点击)👈

风雨相关

密室逃脱24末日危机攻略大全 通关图文攻略
365bet娱乐场官网注册

密室逃脱24末日危机攻略大全 通关图文攻略

🌀 07-17 💧 阅读 3604
三星字库坏了换字库多少钱?三星换字库教程
bt365体育官网育

三星字库坏了换字库多少钱?三星换字库教程

🌀 07-25 💧 阅读 6648