You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

树莓派4 Yocto定制镜像:RAM根文件系统下ACL失效问题排查

问题描述

我正在使用Yocto为Raspberry Pi 4构建定制镜像,尝试通过ACL设置用户组权限。当根文件系统位于SD卡时一切正常,但根文件系统在RAM(fitImage)中时,ACL似乎无法工作。内核配置中已开启CONFIG_TMPFS_POSIX_ACL=y,以下是我的initramfs配方:

require recipes-core/images/super-pi.bb

IMAGE_NAME = "super-pi-initramfs"
IMAGE_FSTYPES := "${INITRAMFS_FSTYPES}"
IMAGE_FSTYPES:remove = " wic wic.gz"

PACKAGE_INSTALL:append = " ${IMAGE_INSTALL}"

IMAGE_NAME_SUFFIX ?= ""
IMAGE_LINGUAS = ""
IMAGE_ROOTFS_EXTRA_SPACE = "0"

DEPENDS:append = " acl-native"


inherit extrausers


#to generate hash for password: printf "%q" $(mkpasswd -m sha256crypt <password>)
#pass: puma1
DEVELOPER_PASSWORD_HASH = "\$5\$5j7bye3XKroIht0\$rZ3af/o3gVXLYo5vqtfbjllCSa5jtx2QrRraKaWwqn5"
#pass: puma2
PRODUCTION_PASSWORD_HASH = "\$5\$uoMhBHIwh8ReIv1\$Fxuh8QN4my0pNfOe/RGfLhMGD5LxVk6UOWupprvgFT/"
#pass: puma3
SERVIS_PASSWORD_HASH = "\$5\$Q.5Zmboz3pIJ3hT\$Xi0f6YTzYGvTjD3cnniNa6htyBB/cY5GT7eUUM1Puq4"
#pass: puma4
VISITOR_PASSWORD_HASH = "\$5\$7CBZsfthWke7GmAw\$uuejwFB.BuAyFAeTY7b40qXxg4oA4G8e7X/hztSIsh0"

EXTRA_USERS_PARAMS = "\
    groupadd --gid 1001 developer; \
    groupadd --gid 1002 production; \
    groupadd --gid 1003 servis; \
    groupadd --gid 1004 visitor; \
    useradd --uid 1011 --no-user-group --no-create-home --password '${DEVELOPER_PASSWORD_HASH}' --shell /bin/bash developer; \
    useradd --uid 1012 --no-user-group --no-create-home --password '${PRODUCTION_PASSWORD_HASH}' --shell /bin/bash production; \
    useradd --uid 1013 --no-user-group --no-create-home --password '${SERVIS_PASSWORD_HASH}' --shell /bin/bash servis; \
    useradd --uid 1014 --no-user-group --create-home --password '${VISITOR_PASSWORD_HASH}' --shell /bin/bash visitor; \
    usermod -g developer developer; \
    usermod -g production production; \
    usermod -g servis servis; \
    usermod -g visitor visitor; \
"

modify_user_access() {

    setfacl -R -m g:developer:rwX ${IMAGE_ROOTFS}/etc  \
                   ${IMAGE_ROOTFS}/usr  \
                   ${IMAGE_ROOTFS}/lib  \
                   ${IMAGE_ROOTFS}/bin  \
                   ${IMAGE_ROOTFS}/sbin \
                   ${IMAGE_ROOTFS}/sys  \
                   ${IMAGE_ROOTFS}/boot \
                   ${IMAGE_ROOTFS}/proc \
                   ${IMAGE_ROOTFS}/media \
                   ${IMAGE_ROOTFS}/mnt \
                   ${IMAGE_ROOTFS}/var \
                   ${IMAGE_ROOTFS}/run;
    bbnote "setfacl result: $?"

    setfacl -R -m g:production:rwX ${IMAGE_ROOTFS}/etc \
                ${IMAGE_ROOTFS}/usr \
                ${IMAGE_ROOTFS}/lib \
                ${IMAGE_ROOTFS}/bin \
                ${IMAGE_ROOTFS}/sbin \
                ${IMAGE_ROOTFS}/media \
                ${IMAGE_ROOTFS}/mnt;                    

    bbnote "setfacl result: $?"              
    setfacl -R -m g:servis:rX ${IMAGE_ROOTFS}/etc \
                ${IMAGE_ROOTFS}/usr \
                ${IMAGE_ROOTFS}/bin \
                ${IMAGE_ROOTFS}/sbin \
                ${IMAGE_ROOTFS}/media \
                ${IMAGE_ROOTFS}/mnt;
    bbnote "setfacl result: $?"                     
    setfacl -R -m g:visitor:--- ${IMAGE_ROOTFS}/;              
    setfacl -R -m g:visitor:r ${IMAGE_ROOTFS}/home/visitor;
    bbnote "setfacl result: $?"                
}


modify_sudoers() {
    sed -i.bak 's/# Cmnd_Alias\tREBOOT/Cmnd_Alias\tREBOOT/' ${IMAGE_ROOTFS}/etc/sudoers
    sed -i.bak 's/# Cmnd_Alias\tPROCESSES/Cmnd_Alias\tPROCESSES/' ${IMAGE_ROOTFS}/etc/sudoers
    sed -i.bak 's/# \t\t\t    \/usr\/bin\/pkill/ \t\t\t    \/usr\/bin\/pkill/' ${IMAGE_ROOTFS}/etc/sudoers
    
    echo "%developer ALL=(ALL) REBOOT, PROCESSES, /usr/bin/setfacl" > ${IMAGE_ROOTFS}/etc/sudoers.d/0001_custom_sudo_rules
    echo "%production ALL=(ALL) REBOOT, PROCESSES, /usr/bin/setfacl" >> ${IMAGE_ROOTFS}/etc/sudoers.d/0001_custom_sudo_rules

    rm ${IMAGE_ROOTFS}/etc/sudoers.bak
}


rootfs_update_timestamp() {
    date "+%Y%m%d%H%M%S" > ${IMAGE_ROOTFS}/etc/timestamp
}

IMAGE_PREPROCESS_COMMAND += "modify_user_access;"
ROOTFS_POSTPROCESS_COMMAND += "rootfs_update_timestamp;modify_sudoers;"
解决方法

1. 确保tmpfs挂载时添加ACL参数

内核开启CONFIG_TMPFS_POSIX_ACL仅支持tmpfs的ACL功能,默认挂载时不会自动启用。需要在initramfs的启动逻辑中,为根文件系统挂载添加acl选项:

  • 若使用传统init脚本,修改挂载命令为:
    mount -t tmpfs -o rw,acl,size=256M tmpfs /root
    
  • 若使用systemd,可在启动cmdline中添加rootflags=acl,或修改对应的tmpfs挂载单元。

2. 添加运行时ACL依赖

配方中仅添加了acl-native用于构建阶段设置ACL,但运行时环境需要acl包提供libacl库和setfacl/getfacl工具。修改配方:

PACKAGE_INSTALL:append = " acl"

3. 移除虚拟文件系统的ACL设置

modify_user_access函数中对/sys、/proc等虚拟文件系统设置ACL无意义,这些目录在运行时动态挂载,构建阶段的设置不会生效。修改函数,仅针对实际文件系统目录:

modify_user_access() {

    setfacl -R -m g:developer:rwX ${IMAGE_ROOTFS}/etc  \
                   ${IMAGE_ROOTFS}/usr  \
                   ${IMAGE_ROOTFS}/lib  \
                   ${IMAGE_ROOTFS}/bin  \
                   ${IMAGE_ROOTFS}/sbin \
                   ${IMAGE_ROOTFS}/boot \
                   ${IMAGE_ROOTFS}/media \
                   ${IMAGE_ROOTFS}/mnt \
                   ${IMAGE_ROOTFS}/var \
                   ${IMAGE_ROOTFS}/run;
    bbnote "setfacl result: $?"

    setfacl -R -m g:production:rwX ${IMAGE_ROOTFS}/etc \
                ${IMAGE_ROOTFS}/usr \
                ${IMAGE_ROOTFS}/lib \
                ${IMAGE_ROOTFS}/bin \
                ${IMAGE_ROOTFS}/sbin \
                ${IMAGE_ROOTFS}/media \
                ${IMAGE_ROOTFS}/mnt;                    

    bbnote "setfacl result: $?"              
    setfacl -R -m g:servis:rX ${IMAGE_ROOTFS}/etc \
                ${IMAGE_ROOTFS}/usr \
                ${IMAGE_ROOTFS}/bin \
                ${IMAGE_ROOTFS}/sbin \
                ${IMAGE_ROOTFS}/media \
                ${IMAGE_ROOTFS}/mnt;
    bbnote "setfacl result: $?"                     
    setfacl -R -m g:visitor:--- ${IMAGE_ROOTFS}/;              
    setfacl -R -m g:visitor:r ${IMAGE_ROOTFS}/home/visitor;
    bbnote "setfacl result: $?"                
}

4. 验证运行时ACL状态

系统启动后,执行以下命令验证ACL是否生效:

# 检查目录ACL设置
getfacl /etc
# 测试用户组权限
su - developer -c "touch /etc/testfile"

5. 检查initramfs内容完整性

解压initramfs镜像,确认包含ACL相关文件:

# 提取initramfs
mkdir initramfs && cd initramfs
zcat ../initramfs.cpio.gz | cpio -idmv
# 检查文件是否存在
ls usr/lib/libacl* usr/bin/setfacl

内容的提问来源于stack exchange,提问作者grandzello

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 08:12:07