Skip to content

nvidia driver SPK

Latest

Choose a tag to compare

@PeterSuh-Q3 PeterSuh-Q3 released this 19 Aug 15:29
· 16 commits to main since this release

syno_nvidia_driver SPK packages

Offline, one-click DSM Package Center installers for the NVIDIA
driver. Each .spk bundles the kernel modules, shared userspace, and (where
applicable) GSP firmware for its platform group — no network access is
needed during install. This is a companion artifact to the nvidia release
tag (raw .tgz layers + install.sh/uninstall.sh); the layers there
remain the source of truth these packages are built from.

Which file do I need?

File Driver Kernel DSM Platforms
syno-nvidia-driver-kver5-580.173.02-1.spk 580.173.02 5.10.55 7.2+ epyc7002, epyc7003, epyc7003ntb, geminilakenk, icelaked, r1000nk, v1000nk
syno-nvidia-driver-kver4-dsm72-550.163.01-1-dsm7.2-7.4.spk 550.163.01 4.4.302 7.2 – 7.4 apollolake, broadwell, broadwellnk, broadwellnkv2, broadwellntbap, geminilake, purley, r1000, v1000
syno-nvidia-driver-kver4-dsm70-550.163.01-1-dsm7.0-7.1.spk 550.163.01 4.4.180 7.0 – 7.1 (same 9 platforms as above)

Find your platform with uname -a — the token right after synology_ is
the platform name (e.g. synology_apollolake_ds218apollolake).

Why three packages, not one universal installer? The two kver4 packages
target the same 9 platforms but different DSM releases: DSM 7.0/7.1 ships
kernel 4.4.180 on these platforms, DSM 7.2+ moved them to 4.4.302 — same
platform name, different kernel vermagic, so the kernel module must match
exactly. DSM's own os_min_ver field can only express a floor, not a
ceiling, so a single package can't safely claim "7.0 only" vs "7.2+" —
hence two separate packages, with the DSM range spelled out in the filename.

Why is 550.163.01 the ceiling on kver4 (4.4.x kernels)? NVIDIA hard-blocks
driver 560 and newer from loading on kernels older than Linux 4.15 — DSM's
4.4.x kernels don't qualify. 550.163.01 is the newest branch that still
supports them.

GSP firmware: only the kver5/580.173.02 package bundles GSP firmware
(gsp_tu10x.bin, gsp_ga10x.bin) — that's the only branch/platform group
here running Turing/Ampere-class silicon that needs it via
request_firmware(). The 550-branch kver4 packages target older kernels
and don't require it.

What's actually inside

Each package is a standard DSM .spkINFO + package.tgz + lifecycle
scripts (postinst/preuninst/preupgrade/postupgrade/
start-stop-status), all sourced from spk/ in this repo and
assembled by scripts/build-spk.sh. Inside
package.tgz:

  • lib/modules/<platform>/*.ko — the platform's kernel modules for this
    variant's exact kernel/driver combination
  • lib/nvidia/{bin,lib} — shared userspace (nvidia-smi, libraries), staged
    to /usr/local/nvidia and /usr/lib at install time
  • lib/firmware/*.bin — GSP firmware (kver5 package only)
  • share/nvidia-gpu-support.json — offline copy of the GPU ID → arch/GSP
    requirement table, pinned to a fixed tcrp-addons commit so a package
    built today resolves the same table as one built after a future update

There is no persistent daemon: start-stop-status's start action (which
DSM invokes at every boot regardless of the Package Center Start/Stop
buttons) inserts the kernel modules, creates /dev/nvidia* nodes, and
idempotently re-asserts Container Manager / Jellyfin integration if those
optional layers are present. Uninstalling cleanly reverses every change
(preuninst), including restoring Jellyfin's service-setup from the
backup taken before it was ever patched.

⚠️ Security fix (this build) — update if you installed an earlier .spk

Earlier builds' postinst copied the ~450MB shared userspace tree into
/usr/local/nvidia on every install. Two problems, now both fixed:

  1. System-partition duplication. The SPK's own copy already lives on
    the data volume (/volume1/@appstore/<pkg>/...); the cp duplicated
    it onto the system partition (/dev/md0) for no reason — the exact
    space problem the .spk packaging exists to avoid (see the standalone
    install.sh complaints in
    #7).
    /usr/local/nvidia is now a symlink straight into the package
    payload; confirmed on real hardware that install no longer grows
    /dev/md0 by ~450MB.

  2. Privilege escalation. That payload is owned by this package's own
    unprivileged service account — DSM's conf/privilege tool section
    only grants root ownership to individual file paths, not directories,
    so there was no way to get the ~100 userspace files root-owned at
    install time. Once /usr/local/nvidia became a symlink into that
    tree, every consumer on the box (Plex, Jellyfin, anything
    dlopen()-ing via /usr/lib) started loading directly from
    service-account-owned files — which meant that account could plant a
    trojaned .so and have it loaded into a root or other-user process.
    Fixed by re-locking the payload to root:root (parent directories
    included, not just the leaf files — delete-and-recreate is governed
    by the parent's write bit) on every privileged entry point
    (postinst and every boot), the same fix pattern
    SynoSmartInfo v2.0.6
    just applied for the identical class of bug
    (issue #21).

Verified on real hardware (DS1621+): confirmed the leaf-only chown left
the parent directory service-account-writable (attack still possible),
and that locking the parent closes it.

Verification

4110a10a2a5fd31ebe66748a9e65cb281971ffb0bb7e95eec26bd34fd69d4b51  syno-nvidia-driver-kver4-dsm70-550.163.01-1-dsm7.0-7.1.spk
377591d343135366b14cefc48c37d33d19ea6b98da98b76932c0679a72b9ff90  syno-nvidia-driver-kver4-dsm72-550.163.01-1-dsm7.2-7.4.spk
58f00eb0ff82040851c2fed0c32fe35abdc1e324ab58fd6000f3e120acd6c33c  syno-nvidia-driver-kver5-580.173.02-1.spk

Verified end-to-end on real hardware (epyc7002/SA6400 + Quadro P1000):
synopkg install succeeds, all 4 NVIDIA kernel modules load, nvidia-smi
correctly reports the GPU. System-partition/ownership fix separately
verified on DS1621+ (v1000/kver4).


syno_nvidia_driver SPK 패키지

DSM 패키지 센터에서 원클릭으로 설치하는 오프라인 NVIDIA 드라이버
패키지입니다. 각 .spk에는 해당 플랫폼 그룹의 커널 모듈, 공용 유저스페이스,
그리고 필요한 경우 GSP 펌웨어까지 모두 포함되어 있어 설치 중 네트워크 접속이
필요 없습니다. 이 패키지들은 nvidia 릴리즈 태그(원본 .tgz 레이어 +
install.sh/uninstall.sh)의 부속 산출물이며, 실제 빌드 원본은 여전히
그쪽 레이어입니다.

어떤 파일을 받아야 하는가?

파일 드라이버 커널 DSM 플랫폼
syno-nvidia-driver-kver5-580.173.02-1.spk 580.173.02 5.10.55 7.2+ epyc7002, epyc7003, epyc7003ntb, geminilakenk, icelaked, r1000nk, v1000nk
syno-nvidia-driver-kver4-dsm72-550.163.01-1-dsm7.2-7.4.spk 550.163.01 4.4.302 7.2 ~ 7.4 apollolake, broadwell, broadwellnk, broadwellnkv2, broadwellntbap, geminilake, purley, r1000, v1000
syno-nvidia-driver-kver4-dsm70-550.163.01-1-dsm7.0-7.1.spk 550.163.01 4.4.180 7.0 ~ 7.1 (위와 동일한 9개 플랫폼)

내 플랫폼은 uname -a 실행 결과에서 synology_ 바로 뒤 토큰으로 확인할 수
있습니다 (예: synology_apollolake_ds218apollolake).

왜 통합 설치본이 아니라 3개로 나눴는가? kver4용 두 패키지는 동일한
9개 플랫폼
을 대상으로 하지만 DSM 버전에 따라 커널이 다릅니다 — DSM 7.0/7.1은
이 플랫폼들에서 커널 4.4.180을, DSM 7.2+는 4.4.302를 사용합니다. 플랫폼명은
같아도 커널 vermagic이 다르므로 커널 모듈이 정확히 일치해야 합니다. DSM의
os_min_ver 필드는 하한선만 표현할 수 있고 상한선을 지정할 수 없어서, 패키지
하나로는 "7.0 전용"과 "7.2+ 전용"을 안전하게 구분할 수 없습니다. 그래서 두
패키지로 분리하고, 대상 DSM 버전 범위를 파일명에 명시했습니다.

kver4(4.4.x 커널)는 왜 550.163.01이 상한인가? NVIDIA는 드라이버 560 이상
버전에서 Linux 4.15보다 오래된 커널에서의 로드를 하드코딩으로 차단합니다.
DSM의 4.4.x 커널은 이 조건을 만족하지 못하므로, 이 커널들을 지원하는 가장
최신 브랜치인 550.163.01이 상한선입니다.

GSP 펌웨어: kver5/580.173.02 패키지에만 GSP 펌웨어(gsp_tu10x.bin,
gsp_ga10x.bin)가 포함되어 있습니다 — Turing/Ampere급 GPU가 request_firmware()
로 이 펌웨어를 요구하는 유일한 브랜치/플랫폼 그룹이기 때문입니다. 550 브랜치
kver4 패키지들은 더 오래된 커널을 대상으로 하며 GSP가 필요 없습니다.

내부 구성

각 패키지는 표준 DSM .spk 형식(INFO + package.tgz + 생명주기 스크립트
postinst/preuninst/preupgrade/postupgrade/start-stop-status)이며,
전부 이 저장소의 spk/ 디렉토리에서 관리되고
scripts/build-spk.sh로 조립됩니다.
package.tgz 내부 구성:

  • lib/modules/<platform>/*.ko — 해당 변형의 정확한 커널/드라이버 조합에
    맞는 플랫폼별 커널 모듈
  • lib/nvidia/{bin,lib} — 공용 유저스페이스(nvidia-smi, 라이브러리 등),
    설치 시 /usr/local/nvidia/usr/lib에 배치됨
  • lib/firmware/*.bin — GSP 펌웨어 (kver5 패키지에만 포함)
  • share/nvidia-gpu-support.json — GPU ID → 아키텍처/GSP 필요 여부 테이블의
    오프라인 사본. tcrp-addons의 고정 커밋을 참조하므로, 오늘 빌드한
    패키지와 이후 테이블이 업데이트된 뒤 빌드한 패키지가 서로 다른 시점의
    값을 갖는 일이 없습니다.

상시 실행되는 데몬은 없습니다: DSM이 매 부팅 시(패키지 센터의 시작/중지
버튼 표시 여부와 무관하게) 호출하는 start-stop-statusstart 동작이
커널 모듈을 로드하고, /dev/nvidia* 노드를 생성하며, Container Manager /
Jellyfin 연동이 설치되어 있으면 멱등적으로 재적용합니다. 제거 시에는
preuninst가 모든 변경 사항을 깔끔하게 되돌립니다 — Jellyfin의
service-setup도 최초 패치 전 백업본으로 복원됩니다.

⚠️ 보안 수정 (이번 빌드) — 이전 .spk를 설치하셨다면 업데이트하세요

이전 빌드의 postinst는 매 설치마다 약 450MB짜리 공용 유저스페이스
전체를 /usr/local/nvidia에 복사했습니다. 이로 인한 문제 두 가지를
모두 이번 빌드에서 고쳤습니다.

  1. 시스템 파티션 중복 사용. SPK 자체의 사본은 이미 데이터 볼륨
    (/volume1/@appstore/<pkg>/...)에 있는데, cp가 그걸 시스템 파티션
    (/dev/md0)에 또 한 번 중복 배치하고 있었습니다 — .spk 패키징이
    애초에 피하려던 그 공간 문제(이슈 #7
    보고된 스탠드얼론 install.sh의 문제)가 그대로 재현되고 있었던
    것입니다. /usr/local/nvidia는 이제 패키지 payload로 바로 향하는
    심볼릭 링크이며, 실기에서 설치 시 /dev/md0 사용량이 더 이상 450MB
    증가하지 않음을 확인했습니다.

  2. 권한 상승 취약점. 그 payload는 이 패키지 전용 저권한 서비스
    계정
    소유입니다 — DSM의 conf/privilegetool 섹션은 개별
    파일 경로에만 root 소유권을 부여할 수 있고 디렉토리는 안 되므로,
    설치 시점에 약 100개의 유저스페이스 파일을 root 소유로 만들 방법이
    없었습니다. /usr/local/nvidia가 그 트리로 향하는 심볼릭 링크가
    되면서, Plex/Jellyfin 등 /usr/lib을 통해 dlopen()하는 모든
    소비자가 저권한 계정 소유 파일을 직접 로드하게 됐고, 그 계정이
    뚫리면 조작된 .so를 심어 root나 다른 계정 프로세스에 코드 실행을
    심을 수 있는 구조였습니다. postinst뿐 아니라 매 부팅(start)마다
    payload를(리프 파일만이 아니라 부모 디렉토리까지 — 삭제 후 재생성
    공격은 부모의 쓰기 비트로 결정되므로) root:root로 재잠금하도록
    고쳐서 해결했습니다. SynoSmartInfo v2.0.6
    동일한 종류의 버그(이슈 #21)에
    적용한 것과 같은 수정 패턴입니다.

실기(DS1621+)에서 검증: 리프 파일만 chown했을 때는 부모 디렉토리가
여전히 서비스 계정 쓰기 가능 상태라 공격이 가능했고, 부모까지 잠그니
차단됨을 확인했습니다.

검증

4110a10a2a5fd31ebe66748a9e65cb281971ffb0bb7e95eec26bd34fd69d4b51  syno-nvidia-driver-kver4-dsm70-550.163.01-1-dsm7.0-7.1.spk
377591d343135366b14cefc48c37d33d19ea6b98da98b76932c0679a72b9ff90  syno-nvidia-driver-kver4-dsm72-550.163.01-1-dsm7.2-7.4.spk
58f00eb0ff82040851c2fed0c32fe35abdc1e324ab58fd6000f3e120acd6c33c  syno-nvidia-driver-kver5-580.173.02-1.spk

epyc7002(SA6400) + Quadro P1000 실기에서 end-to-end 검증 완료: synopkg install
성공, NVIDIA 커널 모듈 4개 전부 로드, nvidia-smi가 GPU를 정상 인식.
시스템 파티션/권한 수정은 DS1621+(v1000/kver4)에서 별도 검증.