PCI-E, sysfs 및 사용자 ID 권한 예외

PCI-E, sysfs 및 사용자 ID 권한 예외

3.X 시리즈 커널에서 독점 PCI-Express 장치에는 독점 커널 드라이버가 있습니다. PCI 기능을 검색하는 동안 몇 가지 이상한 버그를 발견했습니다. 훌륭한 문서를 찾을 수 없습니다. 커널 드라이버가 sysfs사용자 ID를 기반으로 어떤 데이터를 제어/노출할 수 있는지 아는 사람이 있습니까?procfs

특히 이 호출은 공급업체 유틸리티에서 실패합니다.

c = pci_find_cap(mdev->pdev, VENDOR_EXT_CAP_ID, PCI_CAP_EXTENDED);

많은 조사 끝에 setpci를 사용하여 찾을 수 있었습니다 VENDOR_EXT_CAP_ID.

내가 보는 것은:

  • FS 권한은 사용자와 루트에 읽기 권한을 부여합니다.
  • "config" 파일을 sysfs열고 $data.
  • $data사용자와 루트는 $data다릅니다 .

이를 수행하는 방법에 대한 문서가 많지 않으며 공급업체와 함께 설정된 좋은 업그레이드 경로도 없습니다. 이거 본 사람 있어?

답변1

예, 커널 드라이버는 사용자 ID 및/또는 기본적으로 커널이 액세스할 수 있는 모든 정보를 기반으로 sysfs/procfs에 노출되는 데이터를 제어할 수 있습니다.

procfs 또는 sysfs에서 무언가를 읽을 때 정보를 읽는 데 사용되는 시스템 호출은 기본적으로 해당 드라이버의 함수를 호출하게 됩니다. 이 함수는 읽기 작업을 호출한 사용자 공간 프로세스에 대한 모든 정보를 볼 수 있으며, 해당 정보나 커널이 액세스할 수 있는 다른 모든 항목을 기반으로 출력을 수정할 수 있습니다.

의 특정 경우에 /sys/bus/pci/devices/<PCI device ID>/config이를 읽으려는 모든 시도는 다음과 같이 끝납니다.pci_read_config()파일의 기능drivers/pci/pci-sysfs.c호출하는 사용자 공간 프로세스에 CAP_SYS_ADMIN 기능이 있는지 확인합니다(대부분의 경우 사용자에게 CAP_SYS_ADMIN 기능이 있음을 의미 root). 사용자에게 이 기능이 없는 경우 이 기능은 읽을 수 있는 PCI 구성 데이터를 첫 번째 (dev->cfg_size)바이트(CardBus의 경우 128바이트)로 제한합니다.

커널 버전 2.6.5 이하에서는 제한이 256바이트였지만 2.6.6에서는 더 엄격해졌습니다 (dev->cfg_size). 최신 시스템에서는 (dev->cfg_size)관련 장치에 따라 64바이트 또는 256바이트가 되는 경향이 있습니다.

간단한 lspci -v.dll을 루트로 실행하면 각 장치의 PCI/PCIe 기능을 볼 수 있습니다. 그러나 일반 사용자로 실행하면 다음과 같은 결과가 나타납니다.

Capabilities: <access denied>

답변2

커널과 함께 AlmaLinux 8.8을 사용하면 4.18.0-477.27.2.el8_8.x86_64일반 사용자로서 PCIe 기능을 디코딩하는 사용자 공간 애플리케이션을 생성하도록 설계되었습니다. 이 애플리케이션의 경우 엔드포인트의 PCIe 링크 폭 및 속도 기능을 엔드포인트가 연결된 PCIe 루트 포트와 연관시키려고 합니다.

다양한 메커니즘 중:

  1. pci_device_cfg_read*실행 파일에 Linux 기능을 제공하지 않고 일반 사용자 로 PCIe 기능을 읽으려고 하면 함수가 실패로 반환됩니다 libpciaccess.ENXIO

    사용 후에는 sudo setcap cap_sys_admin=ep <executable>일반 사용자처럼 PCIe 기능을 읽을 수 있습니다.

  2. 사용 pciutils:

    • , pci_read_byte및 함수는 실행 파일에 Linux 기능을 제공하지 않고 일반 사용자로서 PCI 기능을 읽으려고 할 때 모두 1을 반환합니다 pci_read_word. 실패 시 설정되지 않습니다.pci_read_longerrno
    • pci_read_block함수는 실행 파일에 Linux 기능을 제공하지 않고 일반 사용자로 PCIe 기능을 읽으려고 할 때 실패를 나타내기 위해 0을 반환합니다.

    사용 후에는 sudo setcap cap_sys_admin=ep <executable>일반 사용자처럼 PCIe 기능을 읽을 수 있습니다.

  3. 사용VFIO, 획득된 파일 설명자는 VFIO_GROUP_GET_DEVICE_FDPCIe 기능을 갖춘 일반 사용자로 읽을 수 있습니다.아니요모든 Linux 기능에는 실행 파일이 제공되어야 합니다.

    vfio-pci그러나 이 접근 방식의 단점은 드라이버가 헤더 유형이 있는 PCI 장치에만 바인딩되기 때문에 VFIO를 PCIe 루트 포트와 함께 사용할 수 없다는 것입니다 NORMAL.vfio_pci_probeBRIDGE헤더 유형을 사용하여 VFIO를 PCIe 루트 포트에 바인딩하려고 할 때 발생하는 오류를 설명하는 다음 코드가 포함되어 있습니다 .

     if (pdev->hdr_type != PCI_HEADER_TYPE_NORMAL)
         return -EINVAL;
    

관련 정보