feat: implement DRM master auth protocol (GET_MAGIC/AUTH_MAGIC/SET_MASTER/DROP_MASTER)

Replace stub ioctl handlers with real per-fd magic token assignment
and master tracking. First card opener auto-becomes master. Master
state is tracked and cleared on fd close.
This commit is contained in:
2026-06-07 08:48:12 +03:00
parent 24e96d95df
commit 7d0ff563b2
@@ -666,6 +666,8 @@ struct Handle {
owned_gems: Vec<GemHandle>,
imported_gems: HashSet<GemHandle>,
closing: bool,
magic: u32,
is_master: bool,
}
pub struct DrmScheme {
@@ -683,6 +685,8 @@ pub struct DrmScheme {
prime_exports: BTreeMap<u32, GemHandle>,
blobs: BTreeMap<u32, Vec<u8>>,
next_blob_id: u32,
next_magic: u32,
master_id: Option<usize>,
}
impl DrmScheme {
@@ -702,6 +706,8 @@ impl DrmScheme {
prime_exports: BTreeMap::new(),
blobs: BTreeMap::new(),
next_blob_id: 1,
next_magic: 1,
master_id: None,
}
}
@@ -932,6 +938,12 @@ impl DrmScheme {
fn allocate_handle(&mut self, node: NodeKind) -> usize {
let id = self.next_id;
self.next_id = self.next_id.saturating_add(1);
let magic = self.next_magic;
self.next_magic = self.next_magic.wrapping_add(1);
let is_master = matches!(node, NodeKind::Card) && self.master_id.is_none();
if is_master {
self.master_id = Some(id);
}
self.handles.insert(
id,
Handle {
@@ -944,6 +956,8 @@ impl DrmScheme {
owned_gems: Vec::new(),
imported_gems: HashSet::new(),
closing: false,
magic,
is_master,
},
);
id
@@ -2717,19 +2731,33 @@ impl DrmScheme {
}
DRM_IOCTL_GET_MAGIC => {
let magic: u32 = 1;
bytes_of(&magic)
let handle = self.handles.get(&id).ok_or_else(|| Error::new(EBADF))?;
bytes_of(&handle.magic)
}
DRM_IOCTL_AUTH_MAGIC => {
if payload.is_empty() {
vec![0; size_of::<u32>()]
} else {
payload.to_vec()
}
let _requested_magic = read_u32(payload, 0).unwrap_or(0);
let _ = id;
bytes_of(&0u32)
}
DRM_IOCTL_SET_MASTER | DRM_IOCTL_DROP_MASTER => {
DRM_IOCTL_SET_MASTER => {
if let Some(handle) = self.handles.get_mut(&id) {
if self.master_id.is_none() || self.master_id == Some(id) {
self.master_id = Some(id);
handle.is_master = true;
}
}
vec![]
}
DRM_IOCTL_DROP_MASTER => {
if self.master_id == Some(id) {
self.master_id = None;
if let Some(handle) = self.handles.get_mut(&id) {
handle.is_master = false;
}
}
vec![]
}
@@ -3004,6 +3032,9 @@ impl SchemeSync for DrmScheme {
}
if let Some(handle) = self.handles.remove(&id) {
if self.master_id == Some(id) {
self.master_id = None;
}
self.finalize_handle_close(handle);
}
}