抓虫:loongarch64架构selinux强防开启程序执行报错execmod
现象
loongarch64架构下强防开启后,许多命令无法执行,如strace、gdb、login、bash等。审计日志提示信息如下,策略中缺少execmod权限,但是x86下是正常的。
type=AVC msg=audit(1724230742.418:5244): avc: denied { execmod } for pid=216722 comm="strace" path="/usr/bin/strace" dev="dm-0" ino=203113917 scontext=sysadm_u:sysadm_r:sysadm_t:s0-s15:c0.c1023:iU tcontext=system_u:object_r:bin_t:s0:iU tclass=file permissive=1
type=AVC msg=audit(1724230736.674:5241): avc: denied { execmod } for pid=216720 comm="bash" path="/usr/bin/bash" dev="dm-0" ino=201573115 scontext=sysadm_u:sysadm_r:sysadm_t:s0-s15:c0.c1023:iU tcontext=system_u:object_r:shell_exec_t:s0:iU tclass=file permissive=0
type=AVC msg=audit(1724230742.410:5243): avc: denied { execmod } for pid=216722 comm="bash" path="/usr/bin/bash" dev="dm-0" ino=201573115 scontext=sysadm_u:sysadm_r:sysadm_t:s0-s15:c0.c1023:iU tcontext=system_u:object_r:shell_exec_t:s0:iU tclass=file permissive=1
type=AVC msg=audit(1724230742.418:5244): avc: denied { execmod } for pid=216722 comm="strace" path="/usr/bin/strace" dev="dm-0" ino=203113917 scontext=sysadm_u:sysadm_r:sysadm_t:s0-s15:c0.c1023:iU tcontext=system_u:object_r:bin_t:s0:iU tclass=file permissive=1
type=AVC msg=audit(1724230861.842:5246): avc: denied { execmod } for pid=216740 comm="bash" path="/usr/bin/bash" dev="dm-0" ino=201573115 scontext=system_u:system_r:system_cronjob_t:s0-s15:c0.c1023:iU tcontext=system_u:object_r:shell_exec_t:s0:iU tclass=file permissive=0
type=AVC msg=audit(1724230935.703:5248): avc: denied { execmod } for pid=216745 comm="which" path="/usr/bin/which" dev="dm-0" ino=201858961 scontext=sysadm_u:sysadm_r:sysadm_t:s0-s15:c0.c1023:iU tcontext=system_u:object_r:bin_t:s0:iU tclass=file permissive=1
type=AVC msg=audit(1724230935.715:5249): avc: denied { execmod } for pid=216755 comm="egrep" path="/usr/bin/bash" dev="dm-0" ino=201573115 scontext=sysadm_u:sysadm_r:sysadm_t:s0-s15:c0.c1023:iU tcontext=system_u:object_r:shell_exec_t:s0:iU tclass=file permissive=1
type=AVC msg=audit(1724231410.885:5252): avc: denied { execmod } for pid=217012 comm="hostname" path="/usr/bin/hostname" dev="dm-0" ino=201811050 scontext=sysadm_u:sysadm_r:hostname_t:s0-s15:c0.c1023:iU tcontext=system_u:object_r:hostname_exec_t:s0:iU tclass=file permissive=1
type=AVC msg=audit(1724231462.338:5253): avc: denied { execmod } for pid=228147 comm="strace" path="/root/niuwanli/strace-master/BUILD/strace-5.13/src/strace" dev="dm-0" ino=135987382 scontext=sysadm_u:sysadm_r:sysadm_t:s0-s15:c0.c1023:iU tcontext=sysadm_u:object_r:admin_home_t:s0:iU tclass=file permissive=1
type=AVC msg=audit(1724231468.658:5255): avc: denied { execmod } for pid=228149 comm="strace" path="/root/niuwanli/strace-master/BUILD/strace-5.13/src/strace" dev="dm-0" ino=135987382 scontext=sysadm_u:sysadm_r:sysadm_t:s0-s15:c0.c1023:iU tcontext=sysadm_u:object_r:admin_home_t:s0:iU tclass=file permissive=0
前言
通过内核同事从内核代码中分析,支持text重定位特性的程序是需要经过SELINUX execmod保护。text重定位特性在程序的查看形式如下,对应TEXTREL
属性。
# readelf -d /usr/bin/straceDynamic section at offset 0x167df0 contains 29 entries:标记 类型 名称/值0x0000000000000016 (TEXTREL) 0x0
TEXTREL,又称为Text Relocations,是与位置无关代码(Position Independent Code, PIC)相关的一个概念。在理解TEXTREL之前,需要先了解PIC的基本概念。
PIC是一种编程技术,它使得代码能够在内存中的任何位置执行,而不需要进行重定位。常用于共享库,因为多个进程可能同时加载同一个共享库,但每个进程加载的库地址可能不同。为了实现这一点,PIC使用了一种机制来确保代码中的引用(如函数和全局变量的地址)在运行时能够正确地解析,而不需要在加载时进行重定位。然而,TEXTREL的出现通常表明在代码中存在不符合PIC要求的部分。
TEXTREL指的是在代码段(.text段)中存在需要重定位的元素。在PIC中,代码段应该是只读的,并且不应该包含任何需要重定位的元素。如果代码段中包含了需要重定位的元素(如直接引用了某个固定的内存地址),那么这就违反了PIC的原则,并且可能导致在加载共享库时出现问题。
TEXTREL通常是由于以下几种情况造成的:
- 直接地址引用:在代码中直接使用了某个固定的内存地址,而不是通过相对偏移量或全局偏移表(GOT)来引用。
- 汇编语言编写不当:在汇编语言编写的代码中,如果没有正确遵循PIC的编写规范,也可能导致TEXTREL的出现。
- 编译器或链接器设置不当:在某些情况下,编译器或链接器的设置可能不正确,导致生成了包含TEXTREL的代码。
由于TEXTREL违反了PIC的原则,因此它可能会导致一系列问题,如共享库加载失败、程序崩溃或安全漏洞等。因此,在编写和编译共享库时,需要特别注意避免TEXTREL的出现。
- 参考:
- TEXTRELs (Text Relocations) and their impact on hardening techniques
验证TEXTREL
修改TEXTREL
先找到dynamic节在那个位置,在文件从0x167df0
开始,长度为0x210
长度,单个元素大小是0x10
字节
# readelf -S /usr/bin/strace
节头:[号] 名称 类型 地址 偏移量大小 全体大小 旗标 链接 信息 对齐[19] .dynamic DYNAMIC 000000000016bdf0 00167df00000000000000210 0000000000000010 WA 6 0 8
# hexdump /usr/bin/strace | less
00167df0 01 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 |................|
00167e00 01 00 00 00 00 00 00 00 6b 00 00 00 00 00 00 00 |........k.......|
00167e10 01 00 00 00 00 00 00 00 a4 01 00 00 00 00 00 00 |................|
00167e20 01 00 00 00 00 00 00 00 ed 01 00 00 00 00 00 00 |................|
00167e30 19 00 00 00 00 00 00 00 98 a7 16 00 00 00 00 00 |................|
00167e40 1b 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00 |................|
00167e50 1a 00 00 00 00 00 00 00 a0 a7 16 00 00 00 00 00 |................|
00167e60 1c 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00 |................|
00167e70 f5 fe ff 6f 00 00 00 00 90 02 00 00 00 00 00 00 |...o............|
00167e80 05 00 00 00 00 00 00 00 70 20 00 00 00 00 00 00 |........p ......|
00167e90 06 00 00 00 00 00 00 00 60 06 00 00 00 00 00 00 |........`.......|
00167ea0 0a 00 00 00 00 00 00 00 5e 0c 00 00 00 00 00 00 |........^.......|
00167eb0 0b 00 00 00 00 00 00 00 18 00 00 00 00 00 00 00 |................|
00167ec0 15 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00167ed0 03 00 00 00 00 00 00 00 70 c1 16 00 00 00 00 00 |........p.......|
00167ee0 02 00 00 00 00 00 00 00 c8 0d 00 00 00 00 00 00 |................|
00167ef0 14 00 00 00 00 00 00 00 07 00 00 00 00 00 00 00 |................|
00167f00 17 00 00 00 00 00 00 00 c0 d9 05 00 00 00 00 00 |................|
00167f10 07 00 00 00 00 00 00 00 a0 2f 00 00 00 00 00 00 |........./......|
00167f20 08 00 00 00 00 00 00 00 e8 b7 05 00 00 00 00 00 |................|
00167f30 09 00 00 00 00 00 00 00 18 00 00 00 00 00 00 00 |................|
00167f40 16 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
再从binutils
包里搜索TEXTREL
字符串,查到dynamic
节的结构,binutils
包提供的readelf
命令
# rpm -qf /usr/bin/strace
strace-5.13-6.cq24.loongarch64
binutils/BUILD/binutils-2.30/bfd/elf.c:1698switch (dyn.d_tag){default:if (bed->elf_backend_get_target_dtag)name = (*bed->elf_backend_get_target_dtag) (dyn.d_tag);if (!strcmp (name, "")){sprintf (ab, "%#" BFD_VMA_FMT "x", dyn.d_tag);name = ab;}break;case DT_NEEDED: name = "NEEDED"; stringp = TRUE; break;case DT_PLTRELSZ: name = "PLTRELSZ"; break;case DT_PLTGOT: name = "PLTGOT"; break;case DT_HASH: name = "HASH"; break;case DT_STRTAB: name = "STRTAB"; break;case DT_SYMTAB: name = "SYMTAB"; break;case DT_RELA: name = "RELA"; break;case DT_RELASZ: name = "RELASZ"; break;case DT_RELAENT: name = "RELAENT"; break;case DT_STRSZ: name = "STRSZ"; break;case DT_SYMENT: name = "SYMENT"; break;case DT_INIT: name = "INIT"; break;case DT_FINI: name = "FINI"; break;case DT_SONAME: name = "SONAME"; stringp = TRUE; break;case DT_RPATH: name = "RPATH"; stringp = TRUE; break;case DT_SYMBOLIC: name = "SYMBOLIC"; break;case DT_REL: name = "REL"; break;case DT_RELSZ: name = "RELSZ"; break;case DT_RELENT: name = "RELENT"; break;case DT_PLTREL: name = "PLTREL"; break;case DT_DEBUG: name = "DEBUG"; break; # DT_DEBUG 宏定义值为0x15case DT_TEXTREL: name = "TEXTREL"; break; # DT_TEXTREL 宏定义值为0x16
从这里,找到来自于结构体elf_internal_dyn
的tag
binutils/BUILD/binutils-2.30/include/elf/internal.h:161typedef struct elf_internal_dyn {/* This needs to support 64-bit values in elf64. */bfd_vma d_tag; /* entry tag value */union {/* This needs to support 64-bit values in elf64. */bfd_vma d_val;bfd_vma d_ptr;} d_un;
} Elf_Internal_Dyn;
结合readelf -S
得到的一个条目占16个字节和结构体内容分析,一个条目16字节,前8字节是tag,DT_TEXTREL
是0x16
所以。。。00167f40
行的第一个字节0x16
即为DT_TEXTREL
条目,通过hex修改工具修改此项为0x15
为DT_DEBUG
当做没什么用的tag即可
强行取消TEXTREL后执行
使用strace分析,但strace不可以用,gdb也不可用,均是启动过程中失败,可以在强防关闭的时候先行启动
# gdb /usr/bin/strace
(gdb) set args ./strace
(gdb) b main
Breakpoint 1 at 0x53e80: file strace.c, line 3789.
(gdb) r
Breakpoint 1, main (argc=2, argv=0x7fffffff73a8) at strace.c:3789
3789 setlocale(LC_ALL, "");
(gdb) c # 如果有强防,现在在c continue,此时gdb和strace已启动不影响
Continuing.
......
mprotect(0x7ffff7eb0000, 32768, PROT_READ) = 0
mprotect(0x7ffff7b88000, 16384, PROT_READ) = 0
mprotect(0x7ffff7ba4000, 16384, PROT_READ) = 0
mprotect(0x7ffff7d2c000, 16384, PROT_READ) = 0
mprotect(0x7ffff7bd4000, 16384, PROT_READ) = 0
mprotect(0x7ffff7cac000, 16384, PROT_READ) = 0
mprotect(0x7ffff7ccc000, 16384, PROT_READ) = 0
mprotect(0x7ffff7cd8000, 16384, PROT_READ) = 0
mprotect(0x7ffff7d04000, 16384, PROT_READ) = 0
mprotect(0x7ffff7eec000, 16384, PROT_READ) = 0
mprotect(0x7ffff7f98000, 32768, PROT_READ) = 0
mprotect(0x7ffff7fac000, 16384, PROT_READ) = 0
--- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_ACCERR, si_addr=0x555555629108} ---
+++ killed by SIGSEGV (core dumped) +++Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7d6c3f0 in raise () from /usr/lib64/libc.so.6
(gdb) info proc
process 5626# cat /proc/5626/maps
555555554000-55555567c000 r-xp 00000000 fd:00 204478032 /usr/bin/strace
出错是发生在修改0x555555629108
地址内容,但这个内存地址是代码段,这个段落因为没有TEXTREL
权限默认是读和执行,没有写,所以dump
强防开启再抓一次,发现是此时报错,第一步增加修改权限,猜测中间对text段进行了修改,再重新设置读和执行的权限取消写权限时错误
mprotect(555555554000, 16384, PROT_READ|PROT_WRITE) = 0
mprotect(555555554000, 16384, PROT_READ|PROT_EXEC) = -1
后续单独写一个简单的helloword例程,编译后不带TEXTREL
,但单独添加这个tag,强防开启并不影响运行。
# readelf -d ./fPIC Dynamic section at offset 0x3e50 contains 22 entries:标记 类型 名称/值0x0000000000000001 (NEEDED) 共享库:[libc.so.6]0x0000000000000019 (INIT_ARRAY) 0x120007e400x000000000000001b (INIT_ARRAYSZ) 8 (bytes)0x000000000000001a (FINI_ARRAY) 0x120007e480x000000000000001c (FINI_ARRAYSZ) 8 (bytes)0x000000006ffffef5 (GNU_HASH) 0x1200002900x0000000000000005 (STRTAB) 0x1200003980x0000000000000006 (SYMTAB) 0x1200002c00x000000000000000a (STRSZ) 137 (bytes)0x000000000000000b (SYMENT) 24 (bytes)0x0000000000000016 (TEXTREL) 0x00x0000000000000003 (PLTGOT) 0x1200080000x0000000000000002 (PLTRELSZ) 24 (bytes)0x0000000000000014 (PLTREL) RELA0x0000000000000017 (JMPREL) 0x1200005000x0000000000000007 (RELA) 0x1200004580x0000000000000008 (RELASZ) 192 (bytes)0x0000000000000009 (RELAENT) 24 (bytes)0x000000006ffffffe (VERNEED) 0x1200004380x000000006fffffff (VERNEEDNUM) 10x000000006ffffff0 (VERSYM) 0x1200004220x0000000000000000 (NULL) 0x0
# ./fPIC
hello world
所以,强防不能运行,也许需要真的不能写text段,不仅仅是TEXTREL
的影响。
和x86构建对比抓虫
两者构建的gcc参数并不一致
随便拿一段构建rpmbuild -bb
阶段的gcc命令对比
- x86_64
[x86_64] # rpmbuild-local -bb SPECS/strace.spec
........
gcc -DHAVE_CONFIG_H -I./linux/x86_64 -I./linux/x86_64 -I./linux/generic -I./linux/generic -I. -I. -I../bundled/linux/arch/x86/include/uapi -I../bundled/linux/include/uapi -DIN_STRACE=1 -isystem /usr/include -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/generic-hardened-cc1 -specs=/usr/lib/rpm/generic-annobin-cc1 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -I./bundled/linux/arch/x86/include/uapi -I./bundled/linux/include/uapi -Wall -Wextra -Wno-missing-field-initializers -Wno-unused-parameter -Wdate-time -Wformat-security -Wimplicit-fallthrough=5 -Winit-self -Wlogical-op -Wmissing-prototypes -Wnested-externs -Wold-style-definition -Wtrampolines -Wundef -Wwrite-strings -Werror -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/generic-hardened-cc1 -specs=/usr/lib/rpm/generic-annobin-cc1 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -c -o libstrace_a-filter_seccomp.o `test -f 'filter_seccomp.c' || echo './'`filter_seccomp.c
- loongarch64
[loongarch64] # rpmbuild-local -bb SPECS/strace.spec
......
gcc -DHAVE_CONFIG_H -I./linux/loongarch64 -I./linux/loongarch64 -I./linux/generic -I./linux/generic -I. -I. -I../bundled/linux/arch/loongarch/include/uapi -I../bundled/linux/include/uapi -DIN_STRACE=1 -isystem /usr/include -O2 -g -I./bundled/linux/arch/loongarch/include/uapi -I./bundled/linux/include/uapi -Wall -Wextra -Wno-missing-field-initializers -Wno-unused-parameter -Wdate-time -Wformat-security -Wimplicit-fallthrough=5 -Winit-self -Wlogical-op -Wmissing-prototypes -Wnested-externs -Wold-style-definition -Wtrampolines -Wundef -Wwrite-strings -Werror -O2 -g -fPIC -pie -c -o libstrace_a-retval.o `test -f 'retval.c' || echo './'`retval.c
忽略-o
内容的不一致,只是随便摘取的段落,可以看到两者首先长度上就完全不一致,详细查看得知,-fPIC -pie
通过-specs=/usr/lib/rpm/generic-hardened-cc1
传递,这个参数在x86_64中是有的,在loongarch64中则没有。。。
# cd /usr/lib/rpm
# grep -rn fPIC
generic-hardened-cc1:2:+ %{!r:%{!fpie:%{!fPIE:%{!fpic:%{!fPIC:%{!fno-pic:-fPIE}}}}}}# cat /usr/lib/rpm/generic-hardened-cc1
*cc1_options:
+ %{!r:%{!fpie:%{!fPIE:%{!fpic:%{!fPIC:%{!fno-pic:-fPIE}}}}}}
查找rpmbuild
阶段宏的差异
查看SPECS/strace.spec
文件的%build部分
447 %build
448 echo 'BEGIN OF BUILD ENVIRONMENT INFORMATION'
449 uname -a |head -1
450 libc="$(ldd /bin/sh |sed -n 's|^[^/]*\(/[^ ]*/libc\.so[^ ]*\).*|\1|p' |head -1)"
451 $libc |head -1
452 file -L /bin/sh
453 gcc --version |head -1
454 ld --version |head -1
455 kver="$(printf '%%s\n%%s\n' '#include <linux/version.h>' 'LINUX_VERSION_CODE' | gcc -E -P -)"
456 printf 'kernel-headers %%s.%%s.%%s\n' $(($kver/65536)) $(($kver/256%%256)) $(($kver%%256))
457 echo 'END OF BUILD ENVIRONMENT INFORMATION'
458
459 CFLAGS=" $RPM_OPT_FLAGS $LDFLAGS "
460 # Removing explicit -m64 as it breaks mpers
461 [ "x${CFLAGS#* -m64 }" = "x${CFLAGS}" ] || CFLAGS=$(echo "$CFLAGS" | sed 's/ -m64 / /g')
462 export CFLAGS
463
464 CPPFLAGS=" -isystem %{_includedir} %{optflags} "
465 # Removing explicit -m64 as it breaks mpers
466 [ "x${CPPFLAGS#* -m64 }" = "x${CPPFLAGS}" ] || CPPFLAGS=$(echo "$CPPFLAGS" | sed 's/ -m64 / /g')
467 export CPPFLAGS
468
469 CFLAGS_FOR_BUILD="$RPM_OPT_FLAGS"; export CFLAGS_FOR_BUILD
470 %configure --enable-mpers=check --with-libdw --with-libiberty
471 %make_build
和rpmbuild-local -bc SPECS/strace.spec
执行%build
时候停止,查看/var/tmp
下最近日期的临时文件,此文件为build阶段展开后的真正执行的脚本
# cat /var/tmp/rpm-tmp.Kwdpwr -n1 #!/bin/sh2 3 RPM_SOURCE_DIR="/root/strace-master/SOURCES"4 RPM_BUILD_DIR="/root/strace-master/BUILD"5 RPM_OPT_FLAGS="-O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/generic-hardened-cc1 -specs=/usr/lib/rpm/generic-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection"6 RPM_LD_FLAGS="-Wl,-z,relro -Wl,-z,now -specs=/usr/lib/rpm/generic-hardened-ld"7 RPM_ARCH="x86_64"8 RPM_OS="linux"9 RPM_BUILD_NCPUS="4"10 export RPM_SOURCE_DIR RPM_BUILD_DIR RPM_OPT_FLAGS RPM_LD_FLAGS RPM_ARCH RPM_OS RPM_BUILD_NCPUS11 RPM_DOC_DIR="/usr/share/doc"12 export RPM_DOC_DIR13 RPM_PACKAGE_NAME="strace"14 RPM_PACKAGE_VERSION="5.13"15 RPM_PACKAGE_RELEASE="6.cq24"16 export RPM_PACKAGE_NAME RPM_PACKAGE_VERSION RPM_PACKAGE_RELEASE17 LANG=C18 export LANG19 unset CDPATH DISPLAY ||:20 RPM_BUILD_ROOT="/root/strace-master/BUILDROOT/strace-5.13-6.cq24.x86_64"21 export RPM_BUILD_ROOT22 23 PKG_CONFIG_PATH="${PKG_CONFIG_PATH}:/usr/lib64/pkgconfig:/usr/share/pkgconfig"24 export PKG_CONFIG_PATH25 CONFIG_SITE=${CONFIG_SITE:-NONE}26 export CONFIG_SITE27 PYTHON_DISALLOW_AMBIGUOUS_VERSION=warn28 export PYTHON_DISALLOW_AMBIGUOUS_VERSION29 30 set -x31 umask 02232 cd "/root/strace-master/BUILD"33 cd 'strace-5.13'34 echo 'BEGIN OF BUILD ENVIRONMENT INFORMATION'35 uname -a |head -136 libc="$(ldd /bin/sh |sed -n 's|^[^/]*\(/[^ ]*/libc\.so[^ ]*\).*|\1|p' |head -1)"37 $libc |head -138 file -L /bin/sh39 gcc --version |head -140 ld --version |head -141 kver="$(printf '%s\n%s\n' '#include <linux/version.h>' 'LINUX_VERSION_CODE' | gcc -E -P -)"42 printf 'kernel-headers %s.%s.%s\n' $(($kver/65536)) $(($kver/256%256)) $(($kver%256))43 echo 'END OF BUILD ENVIRONMENT INFORMATION'44 45 CFLAGS=" $RPM_OPT_FLAGS $LDFLAGS "46 # Removing explicit -m64 as it breaks mpers47 [ "x${CFLAGS#* -m64 }" = "x${CFLAGS}" ] || CFLAGS=$(echo "$CFLAGS" | sed 's/ -m64 / /g')48 export CFLAGS49 50 CPPFLAGS=" -isystem /usr/include -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/generic-hardened-cc1 -specs=/usr/lib/rpm/generic-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection "51 # Removing explicit -m64 as it breaks mpers52 [ "x${CPPFLAGS#* -m64 }" = "x${CPPFLAGS}" ] || CPPFLAGS=$(echo "$CPPFLAGS" | sed 's/ -m64 / /g')53 export CPPFLAGS54 55 CFLAGS_FOR_BUILD="$RPM_OPT_FLAGS"; export CFLAGS_FOR_BUILD56 57 58 CFLAGS="${CFLAGS:--O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/generic-hardened-cc1 -specs=/usr/lib/rpm/generic-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection}" ; export CFLAGS ; 59 CXXFLAGS="${CXXFLAGS:--O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/generic-hardened-cc1 -specs=/usr/lib/rpm/generic-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection}" ; export CXXFLAGS ; 60 FFLAGS="${FFLAGS:--O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/generic-hardened-cc1 -specs=/usr/lib/rpm/generic-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -I/usr/lib64/gfortran/modules}" ; export FFLAGS ; 61 FCFLAGS="${FCFLAGS:--O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/generic-hardened-cc1 -specs=/usr/lib/rpm/generic-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -I/usr/lib64/gfortran/modules}" ; export FCFLAGS ; 62 LDFLAGS="${LDFLAGS:--Wl,-z,relro -Wl,-z,now -specs=/usr/lib/rpm/generic-hardened-ld}" ; export LDFLAGS; 63 [ "1" = 1 ] && for i in $(find $(dirname ./configure) -name config.guess -o -name config.sub) ; do 64 [ -f /usr/lib/rpm/cysoft/$(basename $i) ] && /usr/bin/rm -f $i && /usr/bin/cp -fv /usr/lib/rpm/cysoft/$(basename $i) $i ; 65 done ; 66 [ "1" = 1 ] && [ x != "x-Wl,-z,now -specs=/usr/lib/rpm/generic-hardened-ld" ] && 67 for i in $(find . -name ltmain.sh) ; do 68 /usr/bin/sed -i.backup -e 's~compiler_flags=$~compiler_flags="-Wl,-z,now -specs=/usr/lib/rpm/generic-hardened-ld"~' $i 69 done ; 70 ./configure --build=x86_64-cysoft-linux-gnu --host=x86_64-cysoft-linux-gnu \71 --program-prefix= \72 --disable-dependency-tracking \73 \74 --prefix=/usr \75 --exec-prefix=/usr \76 --bindir=/usr/bin \77 --sbindir=/usr/sbin \78 --sysconfdir=/etc \79 --datadir=/usr/share \80 --includedir=/usr/include \81 --libdir=/usr/lib64 \82 --libexecdir=/usr/libexec \83 --localstatedir=/var \84 --sharedstatedir=/var/lib \85 --mandir=/usr/share/man \86 --infodir=/usr/share/info --enable-mpers=check --with-libdw --with-libiberty87 /usr/bin/make -O -j4
对比得出:gcc
的CFLAGS
环境变量通过%configure
宏参数或RPM_OPT_FLAGS
变量导入,再继续验证和深入
验证%configure
导入了CFLAGS
# rpm --eval %configureCFLAGS="${CFLAGS:--O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/generic-hardened-cc1 -specs=/usr/lib/rpm/generic-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection}" ; export CFLAGS ; CXXFLAGS="${CXXFLAGS:--O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/generic-hardened-cc1 -specs=/usr/lib/rpm/generic-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection}" ; export CXXFLAGS ; FFLAGS="${FFLAGS:--O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/generic-hardened-cc1 -specs=/usr/lib/rpm/generic-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -I/usr/lib64/gfortran/modules}" ; export FFLAGS ; FCFLAGS="${FCFLAGS:--O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/generic-hardened-cc1 -specs=/usr/lib/rpm/generic-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -I/usr/lib64/gfortran/modules}" ; export FCFLAGS ; LDFLAGS="${LDFLAGS:--Wl,-z,relro -Wl,-z,now -specs=/usr/lib/rpm/generic-hardened-ld}" ; export LDFLAGS; [ "1" = 1 ] && for i in $(find $(dirname ./configure) -name config.guess -o -name config.sub) ; do [ -f /usr/lib/rpm/cysoft/$(basename $i) ] && /usr/bin/rm -f $i && /usr/bin/cp -fv /usr/lib/rpm/cysoft/$(basename $i) $i ; done ; [ "1" = 1 ] && [ x != "x-Wl,-z,now -specs=/usr/lib/rpm/generic-hardened-ld" ] && for i in $(find . -name ltmain.sh) ; do /usr/bin/sed -i.backup -e 's~compiler_flags=$~compiler_flags="-Wl,-z,now -specs=/usr/lib/rpm/generic-hardened-ld"~' $i done ; ./configure --build=x86_64-cysoft-linux-gnu --host=x86_64-cysoft-linux-gnu \--program-prefix= \--disable-dependency-tracking \\--prefix=/usr \--exec-prefix=/usr \--bindir=/usr/bin \--sbindir=/usr/sbin \--sysconfdir=/etc \--datadir=/usr/share \--includedir=/usr/include \--libdir=/usr/lib64 \--libexecdir=/usr/libexec \--localstatedir=/var \--sharedstatedir=/var/lib \--mandir=/usr/share/man \--infodir=/usr/share/info
rpm构建过程中的宏,大多来自于/usr/lib/rpm
目录,查找configure
的CFLAGS
来自于哪里,来自于optflags
# cd /usr/lib/rpm
# grep -rn configure # 搜索configure定义
macros:1026:%configure \
macros-1027- CFLAGS="${CFLAGS:-%optflags}" ; export CFLAGS ; \ # CFLAGS来自于optflags定义
macros-1028- CXXFLAGS="${CXXFLAGS:-%optflags}" ; export CXXFLAGS ; \
macros-1029- FFLAGS="${FFLAGS:-%optflags}" ; export FFLAGS ; \
macros:1030: %{_configure} --host=%{_host} --build=%{_build} \\\
macros-1031- --program-prefix=%{?_program_prefix} \\\
macros-1032- --disable-dependency-tracking \\\
再看下RPM_OPT_FLAGS
,RPM_OPT_FLAGS
不能通过rpm --eval $RPM_OPT_FLAGS
查看,可以直接搜索,发现也是来自于optflags
# cd /usr/lib/rpm
# grep -rn RPM_OPT_FLAGS # 搜索RPM_OPT_FLAGS定义
macros:813: RPM_OPT_FLAGS=\"%{optflags}\"\ # 来自于optflags
# rpm --eval %{optflags} # 查看optflags的定义,bingo
-O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/generic-hardened-cc1 -specs=/usr/lib/rpm/generic-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection
再验证下longarch64
下这个参数是否一致,发现不一致
# rpm --eval %{optflags}
-O2 -g
查找宏差异根源
查找optflags的定义
# cd /usr/lib/rpm
# grep -rn optflags
rpmrc:70:optflags: loongarch64 -O2 -g
rpmrc:24:optflags: x86_64 -O2 -g
cysoft/rpmrc:9:optflags: x86_64 %{__global_compiler_flags} -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection
cysoft/rpmrc:54:optflags: loongson32 %{__global_compiler_flags}
cysoft/rpmrc:55:optflags: loongson64 %{__global_compiler_flags}
软件架构名称会和构建出的包的名称对应,当前系统会使用loongarch64
名称
# rpm -qi cqos-release
Name : cqos-release
Version : 24
Release : 15.cy8
Architecture: loongarch64
x86_64中较长的参数来自于%{__global_compiler_flags}
,在cysoft/rpmrc
这个文件中,并没有定义longarch64
的内容,仿照loongson64
也定义一段试试
[longarch64] /usr/lib/rpm/cysoft/rpmrc 新增:
optflags: longarch64 %{__global_compiler_flags}
[loongarch64] # rpm --eval %{optflags}
-O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/generic-hardened-cc1 -specs=/usr/lib/rpm/generic-annobin-cc1
在longarch64中验证rpm --eval %optflags
和再次构建strace
均ok,完结