如何制作公司免费网站,免费在线网站,遵义在线论坛,旅游网站开发书籍一、背景 2023年8月份#xff0c;面对即将到来的“大运会”、“亚运会”#xff0c;今年的例行安全护网阶段也将迎来新的挑战和时刻#xff0c;为此相关部门发布了国家级实战攻防演练已进入紧急「备战」时刻#xff01;这里我们主要说一下Linux OS层面的漏洞处理#xff0…一、背景 2023年8月份面对即将到来的“大运会”、“亚运会”今年的例行安全护网阶段也将迎来新的挑战和时刻为此相关部门发布了国家级实战攻防演练已进入紧急「备战」时刻这里我们主要说一下Linux OS层面的漏洞处理涉及到升级系统内核特此记录以备参考追溯。
Linux内核源码目录被默认放置在“/usr/src/linux”目录中。此目录通常被称为“Linux源代码树”。该目录包含了Linux内核源代码的所有文件包括子目录和文件。此目录下的所有文件都是以文本格式存储并以C语言的形式编写。其中内核源代码目录说明1、arch目录包含了此核心源代码所支持的硬件体系结构相关的核心代码2、include目录包括了核心的大多数include文件3、init目录包含核心启动代码4、mm目录包含所有的内存管理代码5、drivers目录包含系统中所有的设备驱动6、Ipc目录包含核心的进程间通讯代码。 自2.6.0版本发布后Linux内核以A.B.C.D的方式命名。A和B的变化可以说无关紧要C是内核的真实版本每一个版本的变化都会带来新的特性。例如内部API的变化等等改动的数量常常上万。D是安全补丁和bug修复。如果你是Linux的初学者或用户只需了解stable即可它代表稳定版的内核更新。mainline指当前的官方内核由Linus Torvalds进行更新维护由开发者们贡献的代码主要是合并到mainline当中。linux-next和snapshot都是代码提交周期结束之前生成的快照用于给Linux代码贡献者们做测试使用。目前stable版本的更新周期为六到十周下一个稳定版本的rc基本上每周都会更新。新版本的内核分两种一种是Full Source版本完整的内核版本。比较大一般是tar.gz或者.bz2文件。另一种是patch文件即补丁文件。patch文件一般只有及时K到几百K但是对于特定的版本来说你要找到自己对应的版本才能使用。
相关资源Linux内核官网内核Livepatchbuild a trimmed Linux kernel
二、相关高危漏洞
2.1、curl 身份认证绕过漏洞
漏洞编码CVE-2023-27535 漏洞描述curl在7.13.0-7.88.1版本中存在身份认证绕过漏洞。libcurl将重用之前所创建的FTP连接即使一个或多个参数被更改可能会使有效用户变得不一样从而导致使用错误的凭据进行第二次传输。 漏洞影响范围curl 7.13.0 - 7.88.1 翻翻措施请使用此产品的用户尽快更新至安全版本https://github.com/curl/curl/releases或者回退至小于 7.13.0 版本
2.2、Linux kernel 本地提权漏洞CVE-2021-33909
漏洞编码CVE-2021-33909 漏洞描述Linux kernel 存在输入验证错误漏洞该漏洞源于一个越界写入缺陷。 漏洞影响范围Linux kernel 3.16 / 5.13.3 修复措施目前厂商已发布升级补丁以修复漏洞补丁获取链接https://cdn.kernel.org/pub/linux/kernel/v5.x/ChangeLog-5.13.4
注意事项漏洞补丁还是需要重新编译内核如果是联网的情况下直接使用yum update命令即可这条命令会安装系统中已知的最新安全补丁但不会安装新的软件包另外对于一个大规模的补丁安装还可以使用脚本的方式将所有的补丁文件集中到脚本中这样可以实现大规模的补丁安装。如果没有联网或者有特殊的情况也可以使用diff 和patch命令来打补丁具体参看下文。
2.3、Linux kernel缓冲区溢出漏洞CNVD-2023-51380
漏洞编码CNVD-2023-51380 漏洞描述Linux kernel存在缓冲区溢出漏洞该漏洞源于帧缓冲区控制台(fbcon) 中存在一个缺陷当向fbcon_set_font提供大于32的font-width和font-height时未能适当的检查攻击者可利用该漏洞导致未定义的行为和拒绝服务。 漏洞影响范围Linux Linux kernel 6.2 修复措施厂商已发布了漏洞修复程序请及时关注更新 https://github.com/torvalds/linux/commit/2b09d5d364986f724f17001ccfe4126b9b43a0be
2.4、Linux Polkit本地权限提升漏洞CVE-2021-4034
漏洞编码CVE-2021-4034 漏洞描述polkit 的 pkexec 存在本地权限提升漏洞已获得普通权限的攻击者可通过此漏洞获取root权限。 漏洞影响范围由于 polkit 为系统预装工具目前主流Linux版本均受影响。 修复措施参考漏洞影响范围及时升级至最新安全版本。
2.5、Linux内核权限提升漏洞(CVE-2020-14386)
漏洞编码CVE-2020-14386 漏洞描述Linux发行版存在一个权限提升漏洞(CVE-2020-14386), 该漏洞出现在 net/packet/af_packet.c中在处理AF_PACKET时存在整数溢出导致可以进行越界写来实现权限提升本地攻击者通过向受影响的主机发送特制的请求内容利用此漏洞 从非特权用户提升到root用户权限只有启用了CAP_NET_RAW功能的本地用户才能触发此问题。
漏洞影响范围Ubuntu 18.04及后续版本Centos 8/RHEL 8Debian 9/10Red Hat Enterprise Linux 7及centos7不受影响
修复措施1升级内核至安全版本或应用修复补丁内核下载地址 https://github.com/torvalds/linux/releases 2关闭CAP_NET_RAW功能进行防护如果默认情况下禁用CAP_NET_RAW功能对于Red Hat Enterprise Linux是如此则只有特权用户才能触发此错误。缓解措施是为常规用户和可执行文件禁用CAP_NET_RAW功能。在Red Hat Enterprise Linux 8上还可以通过利用非特权用户命名空间来获得CAP_NET_RAW功能。缓解措施是通过将user.max_user_namespace设置为0来禁用无特权用户命名空间
echo user.max_user_namespaces0 /etc/sysctl.d/userns.conf
sysctl -p /etc/sysctl.d/userns.confOpenShift Container Platform 4.5和4.4可以通过从提供给pod的默认cri-o功能中删除“CAP_NET_RAW”来缓解这种情况注意这可能会阻止“ping”在非特权pod中工作。此修复程序尚未针对OpenShift 4.3或更低版本进行验证
apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfig
metadata:labels:machineconfiguration.openshift.io/role: workername: 50-reset-crio-capabilities
spec:config:ignition:version: 2.2.0storage:files:- contents:source: data:text/plain;charsetutf-8;base64,W2NyaW8ucnVudGltZV0KZGVmYXVsdF9jYXBhYmlsaXRpZXMgPSBbCiAgICAiQ0hPV04iLAogICAgIkRBQ19PVkVSUklERSIsCiAgICAiRlNFVElEIiwKICAgICJGT1dORVIiLAogICAgIlNFVEdJRCIsCiAgICAiU0VUVUlEIiwKICAgICJTRVRQQ0FQIiwKICAgICJORVRfQklORF9TRVJWSUNFIiwKICAgICJTWVNfQ0hST09UIiwKICAgICJLSUxMIiwKXQofilesystem: rootmode: 0644path: /etc/crio/crio.conf.d/reset-crio-capabilities.conf对于单个可执行程序getcap 命令和 setcap 命令分别用来查看和设置程序文件的 capabilities 属性执行如下关闭
# 查看程序的 cap 权限
getcap /bin/ping //默认输出如下/bin/ping cap_net_admin,cap_net_rawp# 删除 cap_net_raw 权限setcap cap_net_raw-ep /bin/ping# 检查getcap /bin/ping //输出应如下/bin/ping #也可以检查执行文件是否设置了SUID即-s权限如果有普通用户就可以执行这些命令了
chmod 755 /bin/ping #在移除 SUID 权限后普通用户在执行 ping 命令时碰到了 ping: socket: Operation not permitted 错误
#恢复
setcap cap_net_admin,cap_net_rawep /bin/ping
#移除,命令中的 ep 分别表示 Effective 和 Permitted 集合 号表示把指定的 capabilities 添加到这些集合中- 号表示从集合中移除(对于 Effective 来说是设置或者清除位)。
setcap cap_net_admin,cap_net_raw-ep /bin/ping相关链接redhat漏洞描述、Linux capabilities、Linux/容器的权限(Capabilities)控制模型
2.6、Linux Kernel 权限提升 漏洞CVE-2023-1829
漏洞编码CVE-2023-1829 漏洞描述Linux 内核流量控制索引过滤器 (tcindex) 中存在释放后使用漏洞由于tcindex_delete 函数在某些情况下不能正确停用过滤器同时删除底层结构可能会导致双重释放结构本地低权限用户可利用该漏洞将其权限提升为 root。 漏洞影响范围2.6.12-rc2 Linux Kernel版本 6.3 修复措施目前该漏洞已经修复受影响用户可将Linux内核更新到以下版本 Linux Kernel 4.14.308 Linux Kernel 4.19.276 Linux Kernel 5.4.235 Linux Kernel 5.10.173 Linux Kernel 5.15.100 Linux Kernel 6.1.18 Linux Kernel 6.2.5 Linux Kernel 6.3
2.7、Linux Kernel权限提升漏洞CVE-2023-0386
漏洞编码CVE-2023-0386 漏洞描述在 Linux 内核中发现了一个缺陷在 Linux 内核的 OverlayFS 子系统中发现了未经授权访问具有功能的 setuid 文件的执行即用户如何将一个有能力的文件从一个 nosuid 挂载复制到另一个挂载。这个 uid 映射错误允许本地用户提升他们在系统上的权限。 漏洞影响范围linux kernel v2.6.12-rc2 to v6.2-rc6 修复措施目前该漏洞已经修复https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id4f11ada10d0ad3fd53e2bd67806351de63a4f9c3 下载地址https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/refs/打补丁fs/overlayfs/copy_up.c
2.8、Linux Kernel 权限提升漏洞CVE-2023-32233
漏洞编码CVE-2023-32233 漏洞描述Linux内核Netfilter nf_tables中存在一个UAF漏洞成功利用该漏洞可实现本地提权。 漏洞影响范围v5.1-rc1 Linux Kernel 6.3.1 修复措施目前该漏洞已经修复参考链接https://github.com/torvalds/linux/commit/c1592a89942e9678f7d9c8030efa777c0d57edab打补丁include/net/netfilter/nf_tables.h和net/netfilter/nf_tables_api.c 、net/netfilter/nft_dynset.c、net/netfilter/nft_lookup.c、net/netfilter/nft_objref.c合计5个补丁包
现场验证对比补丁文件和Linux 6.4.7对应内核文件相关漏洞内容已覆盖即已修复其中内核中对应补丁文件内容如下
#补丁中内容
void nf_tables_activate_set(const struct nft_ctx *ctx, struct nft_set *set) { if (nft_set_is_anonymous(set)) nft_clear(ctx-net, set);set-use; }
EXPORT_SYMBOL_GPL(nf_tables_activate_set);
#内核转给你对应文件
nf_tables_activate_set(const struct nft_ctx *ctx, struct nft_set *set) { if (nft_set_is_anonymous(set)) { if (set-flags (NFT_SET_MAP | NFT_SET_OBJECT)) nft_map_activate(ctx, set); nft_clear(ctx-net, set); } nft_use_inc_restore(set-use); } EXPORT_SYMBOL_GPL(nf_tables_activate_set);说明如下 第一段段代码是一个C语言函数名为nf_tables_activate_set它接受两个参数const struct nft_ctx *ctx和struct nft_set *set。 函数的作用是激活一个nft_setnft_set是一个nftables的数据结构并将其引用计数加1。代码逻辑如下 首先通过调用nft_set_is_anonymous(set)函数判断nft_set是否是匿名的。 如果nft_set是匿名的则调用nft_clear(ctx-net, set)函数来清除nft_set的内容。 然后将nft_set的引用计数加1通过set-use操作实现。 最后通过EXPORT_SYMBOL_GPL(nf_tables_activate_set)将该函数导出为一个可供其他模块使用的符号。 第二段代码是一个C语言函数nf_tables_activate_set它接受两个参数const struct nft_ctx *ctx和struct nft_set *set。 函数的作用是激活一个nft_setnft_set是nftables的数据结构并增加其引用计数。代码逻辑如下 首先通过调用nft_set_is_anonymous(set)函数判断nft_set是否是匿名的。 如果nft_set是匿名的则继续执行下面的代码块。 在代码块中首先通过检查set-flags中的标志位来判断nft_set的类型是否为NFT_SET_MAP或NFT_SET_OBJECT。如果是则调用nft_map_activate(ctx, set)函数来激活nft_set。 接着调用nft_clear(ctx-net, set)函数来清除nft_set的内容。 最后调用nft_use_inc_restore(set-use)函数来增加nft_set的引用计数。 函数的最后一行通过EXPORT_SYMBOL_GPL(nf_tables_activate_set)将该函数导出为一个可供其他模块使用的符号。 #补丁文件
if (nft_set_is_anonymous(set)) nft_deactivate_next(ctx-net, set);
……
#内核文件
if (nft_set_is_anonymous(set)) { if (set-flags (NFT_SET_MAP | NFT_SET_OBJECT)) nft_map_activate(ctx, set);
……说明如下 第一段代码是一个条件语句判断nft_set是否是匿名的。如果nft_set是匿名的则调用nft_deactivate_next(ctx-net, set)函数来停用nft_set的下一个元素。具体的逻辑如下 首先通过调用nft_set_is_anonymous(set)函数判断nft_set是否是匿名的。 如果nft_set是匿名的则执行下面的代码块。 在代码块中调用nft_deactivate_next(ctx-net, set)函数来停用nft_set的下一个元素。 第二段代码是一个条件语句的嵌套。首先判断nft_set是否是匿名的如果是则继续执行内部的代码块。 在内部的代码块中首先通过检查set-flags中的标志位来判断nft_set的类型是否为NFT_SET_MAP或NFT_SET_OBJECT。如果是则调用nft_map_activate(ctx, set)函数来激活nft_set。具体的逻辑如下 首先通过调用nft_set_is_anonymous(set)函数判断nft_set是否是匿名的。如果nft_set是匿名的则执行下面的代码块。 在代码块中首先通过检查set-flags中的标志位来判断nft_set的类型是否为NFT_SET_MAP或NFT_SET_OBJECT。 如果nft_set的类型是NFT_SET_MAP或NFT_SET_OBJECT则调用nft_map_activate(ctx, set)函数来激活nft_set。 综上执行升级linux 6.8.7即可。
三、Linux OS打补丁 3.1、补丁修补过程
关于内核打补丁因linux内核源码较多在修改完内核并发布新内核的时候一般同步采用补丁的方式进行发布而不是整个内核打包发布。
1生成补丁
Linux中我们可以使用Patch命令给代码打补丁用于修复BUG、漏洞等问题帮助用户更新和修复Linux 内核中存在的一些安全漏洞而补丁⽂件是使用diff命令⽣成的 diff命令它的功能就是逐⾏⽐较两个⽂件的不同然后输出⽐较的结果输出到补丁文件。还可以使用Diffstat命令比较属性⽣成补丁⽂件的命令使⽤格式如下
语法格式 diff 【选项】 源文件(夹) 目的文件(夹) #就是要给源文件(夹)打个补丁使之变成目的文件(夹)术语所谓“升级”。 diff -uNr oldfile newfile patch_file.patch参数解析 -u以统⼀格式创建补丁⽂件这种格式⽐缺省格式更紧凑些-N确保补丁⽂件将正确地处理已经创建和删除⽂件的情况-r递归会将两个不同版本源代码⽬录中的所有对应⽂件全部都进⾏⼀次⽐较包括⼦⽬录⽂件oldfile源⽂件⽬录未进⾏修改的newfile以oldfile为基础根据需求对⾥⾯的⽂件内容修改之后结果patch_file.patch补丁文件⼀般以.patch为后缀。注解补丁命令的功能就是逐个⽐较源⽂件夹和⽬标⽂件夹的所有⽂件将差异信息记录到patch_file.patch中。下面对补丁文件内容进行讲解
※ 补丁头部分 1、--- test1.txt 表示源文件被修改的文件2、 test2.txt 表示目的文件※ 块部分 表示一个块的开始 3、 -13 表示源文件从第1行开始一共有3行有差异4、 13 表示目的文件从第1行开始一共有3行有差异※ 正文 5、-zzzzzxxccv 表示被修改的文件要删除这一行6、bbbbbbbbgd表示被修改的文件要增加这一行※ 比如如下补丁说明 2打补丁
往往补丁文件是通过官方发布的我们直接通过patch命令将发布的Patch文件中的内容补丁到自己的代码中即可即完成代码的升级。打补丁patch命令的使⽤格式如下这⾥只介绍对源⽂件夹进⾏打补丁操作
patch -pN xxx.patch
#去除补丁恢复旧版本
patch -RE -p0 xxx.patch
#内核打补丁
gunzip ../setup-dir/ patch-2.4.21-rmk1.gz #发布的补丁文件都是使用gzip压缩的
cd linux-2.4.21 #进入你的内核源代码目录
patch –p1 ../../setup-dir/patch-2.4.21-rmk1 #打补丁参数解析 pN打补丁时要忽略掉第N层⽬录。 -R说明在补丁文件中的“新”文件和“旧”文件要调换过来了(实际上相当于给新版本打补丁让它变成老版本) -E表如果发现了空文件就删除它 例子 如果补丁文件包含路径名称/net/packet/af_packet.c那么 -p 0 使用完整路径名因此一般建议使用diff命令制作patch时一定不要使用绝对路径否则在打patch时就需要从根目录开始数当前处于哪一级了 -p 1 除去前导斜杠留下 net/packet/af_packet.c。 -p 3 除去前导斜杠和前l两个目录留下 af_packet.c。 示例在用上图中的说明,通过执行diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c 输出如下
--- a/net/packet/af_packet.cb/net/packet/af_packet.c-2170,7 2170,8 static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,int skb_len skb-len;unsigned int snaplen, res;unsigned long status TP_STATUS_USER;
- unsigned short macoff, netoff, hdrlen;unsigned short macoff, hdrlen;unsigned int netoff;struct sk_buff *copy_skb NULL;struct timespec64 ts;__u32 ts_status;-2239,6 2240,10 static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,}macoff netoff - maclen;}if (netoff USHRT_MAX) {atomic_inc(po-tp_drops);goto drop_n_restore;}if (po-tp_version TPACKET_V2) {if (macoff snaplen po-rx_ring.frame_size) {if (po-copy_thresh 说明补丁头是分别由---/开头的两行用来表示要打补丁的文件。---开头表示旧文件开头表示新文件。一个补丁文件中可能包含以—/开头的很多节每一节用来打一个补丁。所以在一个补丁文件中可以包含好多个补丁。 如果使用参数-p0那就表示从当前目录找一个叫做a的文件夹在它下面寻找net/packet/下的af_packet.c文件来执行patch操作。 如果使用参数-p1那就表示忽略第一层目录(即不管a)从当前目录寻找net/packet/的文件夹在它下面找af_packet.c。这样的前提是当前目录必须为a所在的目录。而diff补丁文件则可以在任意位置只要指明了diff补丁文件的路径就可以了。当然可以用相对路径也可 以用绝对路径。 3linux内核安装与编译、打补丁
#下载内核
wget https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/snapshot/linux-6.5-rc3.tar.gz
#不用最新的也可以去如下网站下载内核
https://mirrors.edge.kernel.org/pub/linux/kernel/v6.x/
https://mirrors.aliyun.com/linux-kernel/
wget https://mirrors.edge.kernel.org/pub/linux/kernel/v6.x/linux-6.4.6.tar.gz
wget https://mirrors.edge.kernel.org/pub/linux/kernel/v6.x/patch-6.4.6.xz
#全部补丁
wget https://mirrors.edge.kernel.org/pub/linux/kernel/v6.x/patch-6.4.xz
#内核3.10.x补丁30-Jun-2013 22:51发布的可修复之前暴漏的漏洞
wget https://mirrors.edge.kernel.org/pub/linux/kernel/v3.x/patch-3.10.gz
#国内镜像网站最新版内核2023-07-27 15:08
wget https://mirrors.aliyun.com/linux-kernel/v6.x/linux-6.4.7.tar.gz
wget https://mirrors.aliyun.com/linux-kernel/v6.x/patch-6.4.7.xz
//或
wget https://mirrors.edge.kernel.org/pub/linux/kernel/v6.x/linux-6.4.6.tar.gz
wget https://mirrors.edge.kernel.org/pub/linux/kernel/v6.x/patch-6.4.6.xz
#将新内核和补丁包放到如下目录
mv linux-6.4.7.tar.gz patch-6.4.7.xz /usr/src/kernels/
#检查漏洞对应的补丁包文件本次主要涉及如下
对比https://github.com/torvalds/linux/commit/c1592a89942e9678f7d9c8030efa777c0d57edab下的nf_tables.h、nf_tables_api.c、nft_dynset.c、nft_lookup.c、nft_objref.c这5个补丁包v6.5-rc3 中更新的如果6.4.6或6.4.7对应文件的内容没有更新相关内容或补丁报里对应文件没有相关内容就进行替换尝试编译
还有一个文件https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?idacf69c946233259ab4d64f8869d4037a198c7f06中的af_packet.c#进到目录
cd /usr/src/kernels
yum install epel-release -y
yum install xz -y #一般cenos7已安装
#解压
tar -zxvf linux-6.5-rc3.tar.gz
tar -xvf linux-6.4.6.tar.gz -C /usr/src/kernels/
xz -d patch-6.4.6.xz
cp patch-6.4.6.patch /usr/src/kernels/linux-6.4.6//配置内核同make olddefconfig
cp -v /boot/config-$(uname -r) /usr/src/kernels/linux-6.4.6/.config #现场centos7.5显示/boot/config-3.10.0-862.el7.x86_64类似如下#
# Automatically generated file; DO NOT EDIT.
# Linux/x86_64 3.10.0-862.el7.x86_64 Kernel Configuration
#
CONFIG_64BITy
CONFIG_X86_64y
CONFIG_X86y
CONFIG_INSTRUCTION_DECODERy
CONFIG_OUTPUT_FORMATelf64-x86-64
CONFIG_ARCH_DEFCONFIGarch/x86/configs/x86_64_defconfig
CONFIG_LOCKDEP_SUPPORTy
CONFIG_STACKTRACE_SUPPORTy
CONFIG_HAVE_LATENCYTOP_SUPPORTy
……
//打补丁的话直接跳转到打补丁那一步//内核6.5.3 配置linux内核特性和模块,未使用可跳过看内核打补丁
cd linux-6.5-rc3
#安装配置编译工具
yum install build-essential libncurses-dev bison flex libssl-dev libelf-dev
make mrproper #每次配置并重新编译内核前需要先执行“make mrproper”命令清理源代码树包括过去曾经配置的内核配置文件“.config”都将被清除。即进行新的编译工作时将原来老的配置文件给删除到以免影响新的内核编译。相当于Remove all generated files config various backup filesmake menuconfig //用它生成的内核配置文件决定将内核的各个功能系统编译进内核还是编译为模块还是不编译#编译
make dep #生成内核功能间的依赖关系为编译内核做好准备。如果内核从未编译过此步可跳过
make clean #remove most generated files but keep the config and enough build support to build external modules如果内核从未编译过此步可跳过
make -j24 #make -j $(nproc --all) 生成内核模块、bzImage、System.map等文件如果-j后不跟任何数字则不限制处理器并行编译的任务数
make bzImage #可选项bzImage命令会生成一个启动映像文件bzImage
make modules -j24
make modules_install -j24 #编译成功后系统会在/lib/modules目录下生成一个新内核版本的子目录里面存放着新内核的所有可加载模块(即将编译好的modules也就是所生成的驱动文件放到/lib/modules/目录中去
make install -j24 #将所生成的驱动文件放到/boot/目录中去增加
#cp .config /boot/config-6.4.0
#cp System.map /boot/System.map-6.4.0
#cp /arch/i386/boot/bzImage /boot/vmlinuz-6.4.0#升级
update-initramfs -c -k 6.5-rc3 #或
mkinitramfs #敲入命令生成内核版本相对应的img 文件
#mkinitramfs 6.4.0 –o /boot/initrd.img-6.4.0 #至此升级内核所需的所有文件config、System.map、vmlinuz、initrd.img 都已全部完成
update-grub #更新启动文件grub.cfg将6.4.0添加至系统启动选项中
#完成后重启
reboot//打补丁
cd /usr/src/kernels/linux-6.4.6
patch -p1 ../xx.patch #据现场实际来#配置内核安装依赖
yum install ncurses-devel
make mrproper #相当于Remove all generated files config various backup files会检查有无不正确的.o文件和依赖关系如果是下载的完整的源程序包即第一次进行编译那么本步可以省略
make olddefconfig #将当前系统存在的.config 文件拷贝至新内核源码目录采用已有的.config文件的参数作为默认参数同时升级依赖属性新属性设置为默认值不再提醒。说明见下文
make menuconfig //先 load加载本地的 .config
General setup
Preemption Model (Voluntary Kernel Preemption (Desktop)) --- //内核抢占模式
(X) Preemptible Kernel (Low-Latency Desktop) //抢占式低延时,或者
(*)Fully Preemptible Kernel (Real-Time) //完全抢占内核
#保存退出。
//打完后重新编译安装内核
nproc #确定内核核数比如是24个
make -j24
make modules -j24
make modules_install -j24
make install -j24
#验证
ls -lh /boot //查看是否有新增的内核版本#确认当前启动的内核配置
cat /boot/grub2/grub.cfg |grep menuentry //查看所有可用内核
grub2-mkconfig -o /boot/grub2/grub.cfg //重新生成 gurb 配置
grub2-set-default CentOS Linux (3.10.0-862.el7.x86_64) 7 (Core) //设置默认启动的内核
grub2-editenv list //查看内核修改结果,类似如下
saved_entryCentOS Linux (3.10.0-862.el7.x86_64) 7 (Core)
tuned-adm profile latency-performance //系统设置为低延迟的性能模式//其他方式更新grub配置有的系统没有如下这个命令可跳过
update-initramfs -c -k 5.4.87
update grub##重启生效
reboot Linux内核升级及编译按照部分更多参看Linux系统升级及内核版本升级
四、附录
4.1、内核编译文件说明
1.config文件
被用来使用make menuconfig 生成的内核配置文件决定将内核的各个功能系统编译进内核还是编译为模块还是不编译。
2vmlinuz 和 vmlinux
vmlinuz是可引导的、压缩的内核“vm”代表“Virtual Memory”。Linux 支持虚拟内存不像老的操作系统比如DOS有640KB内存的限制Linux能够使用硬盘空间作为虚拟内存因此得名“vm”。vmlinuz是可执行的Linux内核vmlinuz的建立有两种方式一是编译内核时通过“make zImage”创建zImage适用于小内核的情况它的存在是为了向后的兼容性二是内核编译时通过命令make bzImage创建bzImage是压缩的内核映像注意的是bzImage不是用bzip2压缩的bzImage中的bz容易引起误解bz表示“big zImage”bzImage中的b是“big”意思。 zImagevmlinuz和bzImagevmlinuz都是用gzip压缩的。它们不仅是一个压缩文件而且在这两个文件的开头部分内嵌有gzip解压缩代码所以你不能用gunzip 或 gzip –dc解包vmlinuz。 内核文件中包含一个微型的gzip用于解压缩内核并引导它。两者的不同之处在于老的zImage解压缩内核到低端内存第一个640KbzImage解压缩内核到高端内存1M以上。如果内核比较小那么可以采用zImage 或bzImage之一两种方式引导的系统运行时是相同的。大的内核采用bzImage不能采用zImage。 vmlinux是未压缩的内核vmlinuz是vmlinux的压缩文件。
3initrd.img initrd是“initial ramdisk”的简写。initrd一般被用来临时引导硬件到实际内核vmlinuz能够接管并继续引导的状态。比如initrd- 2.4.7-10.img主要是用于加载ext3等文件系统及scsi设备的驱动。如果你使用的是scsi硬盘而内核vmlinuz中并没有这个 scsi硬件的驱动那么在装入scsi模块之前内核不能加载根文件系统但scsi模块存储在根文件系统的/lib/modules下。为了解决这个问题可以引导一个能够读实际内核的initrd内核并用initrd修正scsi引导问题initrd-2.4.7-10.img是用gzip压缩的文件。initrd映象文件是使用mkinitrd创建的mkinitrd实用程序能够创建initrd映象文件这个命令是RedHat专有的其它Linux发行版或许有相应的命令。更多请看帮助man mkinitrd
4System.map System.map是一个特定内核的内核符号表由“nm vmlinux”产生并且不相关的符号被滤出。下面几行来自/usr/src/linux-2.4/Makefile
nm vmlinux | grep -v (compiled)|(.o$$)|( [aUw] )|(..ng$$)|(LASH[RL]DI) | sort System.map在进行程序设计时会命名一些变量名或函数名之类的符号。Linux内核是一个很复杂的代码块有许许多多的全局符号 Linux内核不使用符号名而是通过变量或函数的地址来识别变量或函数名比如不是使用size_t BytesRead这样的符号而是像c0343f20这样引用这个变量。 对于使用计算机的人来说更喜欢使用那些像size_t BytesRead这样的名字而不喜欢像c0343f20这样的名字。内核主要是用c写的所以编译器/连接器允许我们编码时使用符号名而内核运行时使用地址。 然而在有的情况下我们需要知道符号的地址或者需要知道地址对应的符号这由符号表来完成符号表是所有符号连同它们的地址的列表。
Linux 符号表使用到2个文件 /proc/ksyms 、System.map 。/proc/ksyms是一个“proc file”在内核引导时创建。实际上它并不真正的是一个文件它只不过是内核数据的表示却给人们是一个磁盘文件的假象这从它的文件大小是0可以看 出来。然而System.map是存在于你的文件系统上的实际文件。当你编译一个新内核时各个符号名的地址要发生变化你的老的System.map 具有的是错误的符号信息每次内核编译时产生一个新的System.map你应当用新的System.map来取代老的System.map。
虽然内核本身并不真正使用System.map但其它程序比如klogd lsof和ps等软件需要一个正确的System.map。如果你使用错误的或没有System.mapklogd的输出将是不可靠的这对于排除程序故障会带来困难。没有System.map你可能会面临一些令人烦恼的提示信息。 另外少数驱动需要System.map来解析符号没有为你当前运行的特定内核创建的System.map它们就不能正常工作。
Linux的内核日志守护进程klogd为了执行名称-地址解析klogd需要使用System.map。System.map应当放在使用它的软件能够找到它的地方。执行man klogd可知如果没有将System.map作为一个变量的位置给klogd那么它将按照下面的顺序在三个地方查System.map/boot/System.map、/System.map、/usr/src/linux/System.map System.map也有版本信息klogd能够智能地查找正确的映象map文件。
4.2、make menuconfig过程
当我们在执行make menuconfig这个命令时系统到底帮我们做了哪些工作呢这里面一共涉及到了以下几个文件 1.Linux内核根目录下的scripts文件夹scripts文件夹存放的是跟make menuconfig配置界面的图形绘制相关的文件我们作为使用者无需关心这个文件夹的内容 2.arch/$ARCH/Kconfig文件、各层目录下的Kconfig文件 3.Linux内核根目录下的makefile文件、各层目录下的makefile文件 4.Linux内核根目录下的的.config文件、arch/$ARCH/configs/下的文件 5.Linux内核根目录下的 include/generated/autoconf.h文件 当我们执行make menuconfig命令出现如下配置界面以前系统帮我们做了以下工作 首先系统会读取arch/$ARCH/目录下的Kconfig文件生成整个配置界面选项Kconfig是整个linux配置机制的核心那么ARCH环境变量的值等于多少呢它是由linux内核根目录下的makefile文件决定的在makefile下有此环境变量的定义 SUBARCH : $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \-e s/arm.*/arm/ -e s/sa110/arm/ \-e s/s390x/s390/ -e s/parisc64/parisc/ \-e s/ppc.*/powerpc/ -e s/mips.*/mips/ \-e s/sh[234].*/sh/ )..........export KBUILD_BUILDHOST : $(SUBARCH)ARCH ? $(SUBARCH)CROSS_COMPILE ?比如是通过 make ARCHarm menuconfig命令来生成的配置界面系统就会读取arm/arm/kconfig文件生成配置选项。
其次它的一些默认配置选项存放在arch/$ARCH/configs/目录下对于arm来说就是arch/arm/configs文件夹此文件夹中有许多选项系统会读取哪个呢内核默认会读取linux内核根目录下.config文件作为内核的默认选项。我们可以选择直接修改.config文件然后执行make menuconfig命令读取新的选项。但是一般并不这样做在menuconfig配置界面中我们可通过空格、esc、回车选择某些选项选中或者不选中最后保存退出的时候Linux内核会把新的选项更新到.config中此时我们可以把.config重命名为其它文件保存起来当执行make distclean时系统会把.config文件删除以后我们再配置内核时就不需要再去arch/arm/configs下考取相应的文件了省去了重新配置的麻烦直接将保存的.config文件复制为.config文件load即可。
通过过以上两步我们就可以正确的读取、配置我们需要的界面了那么他们如何跟makefile文件建立编译关系呢当你保存make menuconfig选项时系统会除了会自动更新.config外还会将所有的选项以宏的形式保存在Linux内核根目录下的 include/generated/autoconf.h文件下。内核中的源代码就都会这些.h文件根据宏的定义情况进行条件编译。当我们需要对一个文件整体选择是否编译时还需要修改对应的makefile文件例如 我们选择是否要编译s3c2410_ts.c这个文件时makefile会根据CONFIG_TOUCHSCREEN_S3C2410来决定是编译此文件此宏是在Kconfig文件中定义当我们配置完成后会出现在.config及autconf中至此我们就完成了整个linux内核的编译过程。最后我们会发现整个linux内核配置过程中留给用户的接口其实只有各层Kconfig、makefile文件以及对应的源文件。
比如我们如果想要给内核增加一个功能并且通过make menuconfig控制其声称过程首先需要做的工作是修改对应目录下的Kconfig文件按照Kconfig语法增加对应的选项其次执行make menuconfig选择编译进内核或者不编译进内核或者编译为模块.config文件和autoconf.h文件会自动生成最后修改对应目录下的makefile文件完成编译选项的添加最后的最后执行make命令进行编译。
4.3、config和Makefile文件
Linux内核源码树的每个目录下都有两个文档Kconfig和Makefile。分布到各目录的Kconfig构成了一个分布式的内核配置数据库每个Kconfig分别描述了所属目录源文档相关的内核配置菜单。在执行内核配置make menuconfig时从Kconfig中读出菜单用户选择后保存到**.config的内核配置文档**中。在内核编译时由Makefile调用这 个.config就知道了用户的选择。这个内容说明Kconfig就是对应着内核的每级配置菜单。
假如要想添加新的驱动到内核的源码中要修改Kconfig,这样就能够选择这个驱动假如想使这个驱动被编译则要修改Makefile。添加新的驱动时需要修改的文档有两种如果添加的只是文件则只需修改当前层Kconfig和Makefile文件如果添加的是目录则需修改当前层和目录下 的共一对Kconfig和MakefileKconfig和Makefile。要想知道怎么修改这两种文档就要知道两种文档的语法结构Kconfig的语法参见参考文献《【linux-2.6.31】kbuild》。 Makefile 文件包含 5 部分:
内核文件说明Makefile顶层的 Makefile.config内核配置文件arch/$(ARCH)/Makefile体系结构 Makefilescripts/Makefile.*适用于所有 kbuild Makefile 的通用规则等kbuild Makefiles大约有 500 个这样的文件
顶层 Makefile 读取内核配置产生的.config 文件顶层 Makefile 构建两个主要的目标:vmlinux(内核映像)和 modules(所有模块文件)。它通过递归访问内核源码树下的子目录来构建这些目标。访问哪些子目录取决于内核配置。顶层 Makefile 包含一个体系结构 Makefile,由 arch/$(ARCH)/Makefile 指定。体系结构 Makefile 文件为顶层 Makefile 提供了特定体系结构的信息。每个子目录各有一个 kbuild文件和Makefile 文件来执行从上层传递下来的命令。kbuild和Makefile文件利用.config 文件中的信息来构造由 kbuild 构建内建或者模块对象使用的各种文件列表。scripts/Makefile.*包含所有的定义/规则,等等。这些信息用于使用 kbuild和 Makefile 文件来构建内核。
注不分摘自http://blog.chinaunix.net/uid-26497520-id-3593098.html#0
4.3、linux内核打补丁场景参考
1使 2.6.23.11 升级到 2.6.23.12. 我应该先把 2.6.23.11 回退成 2.6.23 然后再打 2.6.23.12 的补丁 bzcat …/patch-2.6.23.11.bz2|patch -p1 -R #回退到 2.6.23 bzcat …/patch-2.6.23.12.bz2|patch -p1 #打到 2.6.23.12 22.6.22.9 先要降级到 2.6.22 然后升级到 2.6.23. 再升级到 2.6.23.9 bzcat …/patch-2.6.22.9.bz2|patch -p1 -R #使用 R 命令意思是取消补丁。这样我们就把 22.9 降到 22 zcat …/patch-2.6.23.gz|patch -p1 #这样就升级到了 2.6.23 zcat …/patch-2.6.23.11.bz2|patch -p1 # 这样就升级到了 2.6.23.11 这是现在 stable 的最新版 4.4、make defconfig、 make menuconfig、 make savedefconfig、 make olddefconfig 、make localmodconfig 区别
1 make defconfig 首先通过make xxx_defconfig生成最开始的.config相当于把 XXX_defconfig 文件复制为 .config 文件其中 defconfig 是最小的 config 项kernel编译会根据 .config 文件去编译驱动情况加载过该指令后后面的 make menuconfig 就会基于现在的 .config 去配置 config
2make menuconfig make menuconfig 图像界面基于ncurses库的作用类似于 make config 后者是文本类型的对话就是基于界面去配置 config 文件make config 的作用是加载 “ .config ” 作为默认的配置配置它就是相当于用图形化界面配置 .config 文件
3make savedefconfig 执行 make saveconfig 作用是通过执行.config 生成最小的 defconfig 文件
4make olddefconfig 通过make oldconfig将刚增加的config项的.config做依赖检查重新生成新的.config文件且新生成的.config和以前的不同是将旧的.config重命名为.config.old文件。可通过执行diffconfig .config.old .config 对比一下新老内核配置的区别 5make localmodconfig 通make localmodconfig 会执行 lsmod 命令查看当前系统中加载了哪些模块 (Modules) 并最后将原来的 .config 中不需要的模块去掉仅保留前面 lsmod 出来的这些模块从而简化了内核的配置过程多用于快速测试场景中 。缺点该方法仅能使编译出的内核支持当前内核已经加载的模块当前一直未使用的模块就不会被编译到后续的内核中优点编译内核小编译快。
make config Plain text interface.
make menuconfig Text based color menus, radiolists dialogs.
make nconfig Enhanced text based color menus.
make xconfig Qt based configuration tool.
make gconfig GTK based configuration tool.
make oldconfig Default all questions based on the contents ofyour existing ./.config file and asking aboutnew config symbols.
make olddefconfigLike above, but sets new symbols to their defaultvalues without prompting.
make defconfig Create a ./.config file by using the defaultsymbol values from either arch/$ARCH/defconfigor arch/$ARCH/configs/${PLATFORM}_defconfig,depending on the architecture.
make ${PLATFORM}_defconfigCreate a ./.config file by using the defaultsymbol values fromarch/$ARCH/configs/${PLATFORM}_defconfig.Use make help to get a list of all availableplatforms of your architecture.
make allyesconfigCreate a ./.config file by setting symbolvalues to y as much as possible.
make allmodconfigCreate a ./.config file by setting symbolvalues to m as much as possible.
make allnoconfig Create a ./.config file by setting symbolvalues to n as much as possible.
make randconfig Create a ./.config file by setting symbolvalues to random values.
make localmodconfig Create a config based on current config andloaded modules (lsmod). Disables any moduleoption that is not needed for the loaded modules.To create a localmodconfig for another machine,store the lsmod of that machine into a fileand pass it in as a LSMOD parameter.Also, you can preserve modules in certain foldersor kconfig files by specifying their paths inparameter LMC_KEEP.target$ lsmod /tmp/mylsmodtarget$ scp /tmp/mylsmod host:/tmphost$ make LSMOD/tmp/mylsmod \LMC_KEEPdrivers/usb:drivers/gpu:fs \localmodconfigThe above also works when cross compiling.make localyesconfig Similar to localmodconfig, except it will convertall module options to built in (y) options. You canalso preserve modules by LMC_KEEP.
make kvmconfig Enable additional options for kvm guest kernel support.
make xenconfig Enable additional options for xen dom0 guest kernelsupport.
make tinyconfig Configure the tiniest possible kernel.