Skip to content

Commit f2dac5a

Browse files
fix(psl): harden get_next_offset bounds against malformed input
Replace the raw graph indexing and the over-strict `*pos + 2 >= end` guard with .get() lookups and checked_add for the offset accumulator. The old guard rejected structurally-valid 1- and 2-byte offset codes at the end of the graph and could overflow usize on `*pos + 2`; the new form is panic-free by construction and accepts those codes.
1 parent 1ddd1d8 commit f2dac5a

1 file changed

Lines changed: 10 additions & 16 deletions

File tree

  • libwebauthn/src/ops/webauthn/psl

libwebauthn/src/ops/webauthn/psl/dafsa.rs

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -147,13 +147,12 @@ fn parse_header(bytes: &[u8]) -> Result<Vec<u8>, DafsaFileLoadError> {
147147
/// flag bits) if `key` is present in `graph`, `None` otherwise. ASCII-only: callers
148148
/// must pass keys already converted to IDN-ASCII (punycode for non-ASCII labels).
149149
fn lookup(graph: &[u8], key: &[u8]) -> Option<u8> {
150-
let end = graph.len();
151150
let mut pos: usize = 0;
152151
let mut offset: usize = 0;
153152
let mut key_pos: usize = 0;
154153
let key_end = key.len();
155154

156-
while let Some(()) = get_next_offset(graph, end, &mut pos, &mut offset) {
155+
while get_next_offset(graph, &mut pos, &mut offset).is_some() {
157156
let mut did_consume = false;
158157

159158
if key_pos < key_end && !is_eol(graph, offset) {
@@ -196,32 +195,27 @@ fn lookup(graph: &[u8], key: &[u8]) -> Option<u8> {
196195
None
197196
}
198197

199-
fn get_next_offset(graph: &[u8], end: usize, pos: &mut usize, offset: &mut usize) -> Option<()> {
200-
if *pos >= end {
201-
return None;
202-
}
203-
if *pos + 2 >= end {
204-
return None;
205-
}
206-
let b = graph[*pos];
198+
fn get_next_offset(graph: &[u8], pos: &mut usize, offset: &mut usize) -> Option<()> {
199+
let b = *graph.get(*pos)?;
207200
let consumed = match b & 0x60 {
208201
0x60 => {
209-
*offset += ((b as usize & 0x1F) << 16)
210-
| ((graph[*pos + 1] as usize) << 8)
211-
| (graph[*pos + 2] as usize);
202+
let hi = *graph.get(*pos + 1)? as usize;
203+
let lo = *graph.get(*pos + 2)? as usize;
204+
*offset = offset.checked_add(((b as usize & 0x1F) << 16) | (hi << 8) | lo)?;
212205
3
213206
}
214207
0x40 => {
215-
*offset += ((b as usize & 0x1F) << 8) | (graph[*pos + 1] as usize);
208+
let lo = *graph.get(*pos + 1)? as usize;
209+
*offset = offset.checked_add(((b as usize & 0x1F) << 8) | lo)?;
216210
2
217211
}
218212
_ => {
219-
*offset += (b as usize) & 0x3F;
213+
*offset = offset.checked_add((b as usize) & 0x3F)?;
220214
1
221215
}
222216
};
223217
if b & 0x80 != 0 {
224-
*pos = end;
218+
*pos = graph.len();
225219
} else {
226220
*pos += consumed;
227221
}

0 commit comments

Comments
 (0)