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

Android中SG_IO IOCTL触发sys_rawio AVC权限拒绝问题求助

Android HAL服务SG_IO ioctl触发sys_rawio AVC权限拒绝问题

问题背景

我正在开发Android原生HAL服务,提供从SCSI设备读取信息的接口。在用户空间通过带SG_IO请求的ioctl向/dev/block/sda设备发送命令时,触发了sys_rawio的AVC权限拒绝错误,但使用同一设备节点执行BLKDISCARD等其他ioctl命令时无此问题。此外,sys_rawio已被添加到private/domain.te的neverallow规则中,无法通过SEPolicy添加允许规则。

错误日志

01-01 00:57:50.227  1110  1110 I Diag@1.0-ser: type=1400 audit(0.0:332): avc: denied { sys_rawio } for capability=17 scontext=u:r:hal_Diag_default:s0 tcontext=u:r:hal_Diag_default:s0 tclass=capability permissive=1

触发权限拒绝的核心代码

执行SG_IO ioctl的关键调用:

ret = ioctl(fd, SG_IO, &io_hdr_v4);

完整的SCSI命令发送函数:

int32_t send_scsi_cmd_upiu (_Uint8t *cdb,
                            _Uint8t cdb_len,
                            int32_t fd,
                            _Uint8t *data_ptr,
                            int32_t data_len,
                            int32_t timeout,
                            _Uint8t write)
{
    int             k,ret=0;
    sg_io_hdr_t     hp;
    unsigned char   sense_buffer[32]={0};   
    
    timeout = 60000;
    memset(&hp,0,sizeof(sg_io_hdr_t));
    hp.interface_id='S';
    hp.cmd_len=cdb_len;
    hp.cmdp=cdb;
    hp.mx_sb_len=sizeof(sense_buffer);
    hp.dxfer_len=data_len;
    hp.timeout=60000;
    hp.sbp=sense_buffer;
    hp.iovec_count=0;   
    hp.flags=0;
    hp.dxferp=data_ptr;
    hp.status=0;        
    hp.masked_status=0;
    hp.msg_status=0;
    hp.sb_len_wr=0;
    hp.host_status=0;
    hp.driver_status=0;
    hp.resid=0;
    hp.duration=0;
    hp.info=0;

    if ( write )
    {
        hp.dxfer_direction= SG_DXFER_TO_DEV;
    }
    else
    {
        hp.dxfer_direction= SG_DXFER_FROM_DEV;
    }

    if (ioctl(fd,SG_IO,&hp) == -1)
    {
        __android_log_print(ANDROID_LOG_ERROR,"\"DIAG\"","\"IOCTl SCSI Failed %s\n\"",strerror(errno));
        ret=-1;
    }
    else
    {       
        if (hp.info != 0) 
        {
            ret = -1;
            if (hp.sb_len_wr > 0) {
                __android_log_print(ANDROID_LOG_INFO,"\"DIAG\"","\"INQUIRY sense data: \n \"");
                for (k = 0; k < hp.sb_len_wr; ++k) {
                    if ((k > 0) && (0 == (k % 10)))
                        __android_log_print(ANDROID_LOG_ERROR,"\"DIAG\"","\"\n    \"");
                    __android_log_print(ANDROID_LOG_ERROR,"\"DIAG\"","\"0x%02x \"", sense_buffer[k]);
                }
                __android_log_print(ANDROID_LOG_ERROR,"\"DIAG\"","\"\n\"");
            }
            if (hp.masked_status)
                __android_log_print(ANDROID_LOG_ERROR,"\"DIAG\"","\"INQUIRY SCSI status=0x%x\n\"", hp.status);
            if (hp.host_status)
                __android_log_print(ANDROID_LOG_ERROR,"\"DIAG\"","\"INQUIRY host_status=0x%x\n\"", hp.host_status);
            if (hp.driver_status)
                __android_log_print(ANDROID_LOG_ERROR,"\"DIAG\"","\"INQUIRY driver_status=0x%x\n\"", hp.driver_status);
        }
    }   
    return ret;
}

对比:无权限问题的ioctl代码

使用同一设备节点执行BLKDISCARD命令的代码,未触发权限拒绝:

int ret = 0
int fd;
unsigned long long int range[2];   
const char *device_path = "\"/dev/block/sda31\"";

// Open the device file
fd = open(device_path, O_RDWR);
if (fd == -1) {
    ALOGD("\"Failed to open the device\"");
}
else {
// Issue the BLKDISCARD ioctl command
if (ioctl(fd, BLKDISCARD, &range) == -1) {
    ALOGD("\"BLKDISCARD ioctl failed\"");
}
else
    ALOGD("\"BLKDISCARD operation on %s successful.\n\"", device_path);

// Close the device file
close(fd);
}

解决方案

1. 切换到sg设备节点而非块设备节点

/dev/block/sda是块设备节点,执行SG_IO需要sys_rawio权限;而/dev/sgX(比如/dev/sg0对应/dev/block/sda)是专门的SCSI通用设备节点,Android的SEPolicy通常对这类节点有更宽松的权限配置,无需sys_rawio能力。

  • 可通过遍历/sys/class/scsi_generic/找到对应设备的sg节点,比如:
    ls -l /sys/class/scsi_generic/
    
    找到指向目标块设备的sgX节点,然后打开/dev/sgX替代/dev/block/sda。

2. 复用Android系统原生存储服务

如果你的功能属于存储操作范畴,可以直接复用Android原生的storaged服务或android.hardware.storage HAL接口,这类系统组件已经具备合法权限执行SCSI相关操作,无需自行处理权限问题。

3. 针对性调整SEPolicy(仅适用于定制ROM场景)

如果是定制ROM且有权修改SEPolicy,可尝试为hal_Diag_default域添加对sg_device类的ioctl权限:

allow hal_Diag_default sg_device:chr_file ioctl;

注意:此方法仅在使用sg节点时有效,因为操作sg节点不需要sys_rawio能力,不会触发neverallow规则限制。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 02:17:06