7 如何使用

7.1 将 SELinux 策略应用于应用程序

TelAF 与系统 SELinux 良好集成,并提供接口来支持 TelAF 应用程序和服务来创建和构建 SELinux 策略。

TelAF还为其应用程序和服务提供管理SELinux模块。当启动应用程序或服务时,TelAF会首先检查应用程序的SELinux策略,如果策略模块通过检查,则将其加载到系统中。当升级或删除应用程序和服务时,其相应的SELinux模块也会被升级或删除。

在 TelAF 中,为应用程序提供了一组统一的模板来定义自己的 SELinux 策略。

7.1.1 创建 SELinux 策略目录

在<source_root>\telaf\security\selinux\sepolicy\下创建应用程序的策略目录。

注意:yocto 构建将扫描<source_root>\telaf\security\selinux\sepolicy目录并将所有 SELinux 策略模块编译到 rootfs 映像。建议在此文件夹下管理所有应用程序的 SELinux 策略模块。

7.1.2 创建应用程序的 SELinux 策略

按照所示模板,在前面的说明中创建的目录中创建应用程序自己的 .te、.fc、.if、Makefile 和 Component.cdef 文件。

以下是应用程序 SELinux 策略的示例目录结构:

├── Component.cdef
├── Makefile
├── your_app_name.fc
├── your_app_name.if
└── your_app_name.te
  1. 创建 Component.cdef 文件。
externalBuild:
{
    "make -f ${CURDIR}/Makefile -C ${CURDIR}/ clean"
    "make -f ${CURDIR}/Makefile -C ${CURDIR}/"
}

bundles:
{
    file:
    {
        [r] ${CURDIR}/your_app_name.pp /
    }
}
  1. 创建生成文件。
# Makefile for building SELinux module

AWK ?= gawk
NAME ?= $(strip $(shell $(AWK) -F= '/^SELINUXTYPE/{ print $$2 }' $(OECORE_TARGET_SYSROOT)/etc/selinux/config))
SHAREDIR := $(OECORE_TARGET_SYSROOT)/usr/share/selinux/mls

ifeq ($(MLSENABLED),)
    MLSENABLED := 1
endif

ifeq ($(MLSENABLED),1)
    NTYPE = mcs
endif

ifeq ($(NAME),mls)
    NTYPE = mls
endif

TYPE ?= $(NTYPE)

HEADERDIR := $(SHAREDIR)/include
include $(HEADERDIR)/Makefile
  1. 创建应用程序文件上下文。
    应用程序的文件上下文定义在 .fc 中定义,类似于以下示例:
/legato/systems/current/appsWriteable/<your_app_name>/lib(/.*)?                 gen_context(system_u:object_r:telaf_lib_t,s0)
/legato/systems/current/appsWriteable/<your_app_name>/bin/<your_app_name>       gen_context(system_u:object_r:telaf_<your_app_name>_exec_t,s0)
/legato/apps/[^/]*/read-only/bin/<your_app_name>                                gen_context(system_u:object_r:telaf_<your_app_name>_exec_t,s0)
  1. 创建应用程序类型强制。
    在.te文件中定义规则如下:
policy_module(<your_app_name>, 1.0)

# The context of the application executable
type telaf_<your_app_name>_exec_t;
files_type(telaf_<your_app_name>_exec_t);

# The domain of the application

type telaf_<your_app_name>_t;

# The optional data context of the application

type telaf_<your_app_name>_data_t;
files_type(telaf_<your_app_name>_data_t);

# The type transition of the application

init_telaf_app_domain(telaf_<your_app_name>_t,telaf_<your_app_name>_exec_t)

# Allow update daemon to install/uninstall the application
telaf_admin_manage_all_files_perms(telaf_<your_app_name>_data_t)
telaf_admin_manage_all_files_perms(telaf_<your_app_name>_exec_t)
  1. 创建应用程序策略接口。
    在同一文件夹下创建<your_app_name>.if文件。如果策略模块没有提供接口,请将其保留为空文件。

7.1.3 构建应用程序的 SELinux 策略

  1. 将 SELinux 策略模块组件包含在应用程序的 .adef 文件中,如下所示:
// Add SELinux module
components:
{
    $TELAF_ROOT/security/selinux/sepolicy/<your_app_name>_module
}
  1. 应用程序构建过程将编译并打包sepolicy 模块到应用程序包中。

7.2 调试应用程序

本节总结了调试 TelAF 上运行的应用程序的不同方法。

  • 有多种工具可用于确定应用程序失败或阻塞的原因,包括:
  • 记录以设置过滤器、跟踪等(请参阅日志以获取更多信息。)
  • 检查应用程序状态以获取当前应用程序信息。
  • 运行 sdir 以检查应用程序是否连接到依赖服务。
  • 在应用程序中运行进程以运行或重新运行应用程序中的进程。
  • 检查应用程序以查看内存池详细信息。
  • 检查应用程序崩溃日志以分析系统崩溃日志或核心转储。
  • 使用开源工具获得额外帮助。

7.2.1 检查应用程序状态

在目标上运行app status以列出所有应用程序及其当前状态。请参阅应用程序了解更多信息。

7.2.2 检查应用程序崩溃日志

检查持久或非持久位置中的最新应用程序崩溃日志或核心转储。

当应用程序内的进程出现故障或错误退出时,将捕获当前系统日志缓冲区的副本以及进程崩溃的核心文件(如果生成)。

核心文件最大大小由进程设置决定maxCoreDumpFileBytes,maxFileBytes可在应用程序的 .adef 文件的进程部分中找到。默认情况下,maxCoreDumpFileBytes设置为0,不创建core文件。

为了帮助保护目标免遭闪存烧毁,系统日志和核心文件存储在/tmp下的 RAM FS 中。当发生崩溃时,会创建以下目录:

/tmp/telaf_crash_logs/

该目录中的文件如下所示:

core-myProc-1418694851
syslog-myApp-myProc-1418694851

为了节省 RAM 空间,仅保留每个文件的最新四个副本。

如果该应用程序进程的故障操作是重新启动目标,则输出位置将更改为以下内容:

/data/telaf_crash_logs/

RAM 空间中的最新文件在重新启动后会保留。

7.2.3 运行sdir

sdir list在目标上运行以确定应用程序是否因未绑定(即 IPC 失败)或服务器未运行(即未连接)而失败。如果客户端正在等待服务出现或创建绑定,这会有所帮助。sdir还可以列出提供服务的应用程序或用户。

请参阅sdir了解更多信息。

7.2.4 在应用程序中运行进程

运行app runProc [options]或app runProc [] --exe= [options]在正在运行的应用程序的沙箱中执行特定进程。app runProc还可以设置进程优先级。

请参阅应用程序了解更多信息。

7.2.5 检查应用程序

运行inspect [interval=SECONDS]以设置内存使用更新,以帮助缩小导致故障的任何内存泄漏。

请参阅检查以获取更多信息。

7.2.6 使用开源工具

用户还可以尝试标准的开源调试工具,包括:

  • strace– 系统调用跟踪器,有利于低级代码检查。
  • GDB – GNU 项目调试器,非常适合设置断点。

用户可以运行-help文档选项。

7.2.7 使用 GDB 进行调试

本节提供有关在开发计算机上使用开源 GDB 工具调试非沙盒应用程序的详细信息。这种类型的远程调试在资源有限的情况下非常有用,例如在嵌入式应用程序中。

该示例使用名为 helloWorld 的应用程序和一个可执行文件helloWorld。

要将 GDB 与沙盒应用程序一起使用:

  1. 将 gdb、gdbserver 安装到工具链中。
  2. 使用调试符号构建应用程序。

在目标设备上:

  1. 确保 devMode 应用程序已安装并正在运行。
  2. 运行未沙盒化的应用程序。
  3. gdbserver在应用程序中启动。
  4. 使用 启动应用程序中的进程gdbserver。
  5. gdb完成调试后从沙盒应用程序中删除。

在开发机器上:

  1. gdb从 apps make 目录启动。
  2. 远程连接到目标并运行gdb命令。
  • 将 gdb 和 gdbserver 安装到工具链
  1. 要将 gdb 和 gdbserver 安装到工具链,必须通过以下源代码更改启动 NAD 映像构建:
    通过从 中删除和软件包来更改poky/meta-qti-bsp/conf/distro/mdm.conf文件。gdbgdbserverPACKAGE_EXCLUDE
  2. 创建poky/meta-qti-bsp/recipes-bsp/recipes-devtools/gdb/nativesdk-packagegroup-sdk-host.bbappend 的配方文件,并包含以下内容:
RDEPENDS_${PN} += "\
                nativesdk-gdb \
                nativesdk-gdbserver \
                "
  1. 通过添加到文件末尾来更改poky/meta-qti-bsp/recipes-devtools/gdb/gdb_%.bbappend文件。BBCLASSEXTEND = “nativesdk”
  2. 通过将以下两行添加到文件末尾来更改poky/meta-qti-bsp/recipes-products/images/machine-image.bb文件:
IMAGE_INSTALL += "gdb"
IMAGE_INSTALL += "gdbserver"
  1. 创建一个配方文件poky/meta-qti-bsp/recipes-kernel/lttng-ust/lttng-ust_%.bbappend b/recipes-kernel/lttng-ust/lttng-ust_%.bbappend 并包含以下内容:
 BBCLASSEXTEND = "nativesdk" 
  1. 创建一个配方文件poky/meta-qti-bsp/recipes-support/liburcu/liburcu_%.bbappend b/recipes-support/liburcu/liburcu_%.bbappend并包含以下内容:
 BBCLASSEXTEND = "nativesdk" 
  1. 运行包含所有这些更改的build-sa515m-nad-image ,并使用 poky/build/tmp-glibc/deploy/images下的oecore-x86_64-armv7at2hf-neon-toolchain-nodistro.0.sh安装脚本安装工具链/sa515m-nad/sdk。
    gdb 和 gdbserver 现在应该在工具链中可用。
  • 使用调试符号构建应用程序

构建应用程序时,按正常方式构建,但添加-d 到 mkapp 命令行以在. 同一目录可用于所有应用程序 - 每个程序或库将使用唯一的名称。

从源代码构建 TelAF 映像时,始终会生成 TelAF 框架的调试符号并将其放置在build//debug中。建议将应用程序调试路径设置为相同的build//debug路径。

使用 devMode 应用程序部署 gdbserver

使用legato/legato-af/apps/tools下的devMode.adef应用程序定义文件构建devMode 工具并将其加载到目标上。

在目标上的应用程序上启动 gdb

在开发计算机上,设置从本地主机到目标的端口转发。这会绕过目标上的防火墙并允许 gdb 服务器进行连接。

  $ ssh -L 2000:localhost:2000 root@192.168.2.2

警告: 不要结束与目标的会话,否则端口转发将结束并且 GDB 将无法连接到目标。

在目标上,首先gdbserver使用后面指定的参数–(两个破折号)启动应用程序:

# app runProc <app name> --exe=<gdbserver bin dir>/gdbserver -- localhost:2000 <app bin dir>/<app bin>

例如:

# app runProc helloWorld --exe=/legato/systems/current/appsWriteable/devMode/bin/gdbserver -- localhost:2000 /legato/systems/current/appsWriteable/helloWorld/bin/helloWorld 

如果启动成功,将返回以下信息:

Process /legato/systems/current/appsWriteable/helloWorld/bin/helloWorld created; pid = 9783
Listening on port 2000

在开发主机上启动 gdb

命令必须从制作 helloWorld 应用程序的目录运行。_build_helloWorld /sa515m/app/helloWorld/staging/read-only/bin/helloWorld路径是相对于app目录的;这个构建目录是在创建应用程序时生成的,并且必须在此处运行 gdb 命令。

以下示例显示运行arm-oe-linux-gnueabi-gdb位于目标工具链路径(对于 sa515m 而言为 /opt/qct/sa515m/sysroots/x86_64-oesdk-linux/usr/bin/arm-oe-linux-gnueabi/ )中的 gdb 工具 ( )。

使用以下命令从工具链启动 gdb:

$ ~/TelAFApps/helloWorld$ /opt/qct/sa515m/sysroots/x86_64-oesdk-linux/usr/bin/arm-oe-linux-gnueabi/arm-oe-linux-gnueabi-gdb

远程连接

gdb 启动后,告诉 gdb 获取库以通过网络进行调试,但使用本地调试符号:

$ (gdb) set debug-file-directory <debug-path>
$ (gdb) set sysroot target:/

注意:
默认情况下将为$TELAF_ROOT/build//debug/. 建议将该目录与版本一起存档,以便能够处理核心转储。

使用target remote命令连接到目标:

$ (gdb) target remote localhost:2000

注意
如果收到有关连接的错误,请确保在开发计算机和目标之间打开了 ssh -L(端口转发)会话。

目标将显示:

Remote debugging using localhost:2000

您应该看到 gdb 读取 TelAF 组件的符号。
您现在可以在helloWorld.

从目标中删除 gdb

调试完成后,gdbserver通过删除 devMode 应用程序来删除。

如果需要使用 gdb 的帮助,请参阅众多可用的开源资源之一。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐