Fix various issues in frequency trimming
Found by fuzzing. The frequency trimming functions did a bad job of checking for possible out of bounds accesses and didn't handle various failure cases correctly. Add suitable checks to fix the issues found. v2: fix one check, add several new ones
This commit is contained in:
parent
b9208c4772
commit
ca30a508aa
@ -1089,15 +1089,19 @@ class Stc15AProtocol(Stc12Protocol):
|
|||||||
self.write_packet(packet)
|
self.write_packet(packet)
|
||||||
self.pulse(timeout=1.0)
|
self.pulse(timeout=1.0)
|
||||||
response = self.read_packet()
|
response = self.read_packet()
|
||||||
if response[0] != 0x65:
|
if len(response) < 36 or response[0] != 0x65:
|
||||||
raise StcProtocolException("incorrect magic in handshake packet")
|
raise StcProtocolException("incorrect magic in handshake packet")
|
||||||
|
|
||||||
# determine programming speed trim value
|
# determine programming speed trim value
|
||||||
target_trim_a, target_count_a = struct.unpack(">HH", response[28:32])
|
target_trim_a, target_count_a = struct.unpack(">HH", response[28:32])
|
||||||
target_trim_b, target_count_b = struct.unpack(">HH", response[32:36])
|
target_trim_b, target_count_b = struct.unpack(">HH", response[32:36])
|
||||||
|
if target_count_a == target_count_b:
|
||||||
|
raise StcProtocolException("frequency trimming failed")
|
||||||
m = (target_trim_b - target_trim_a) / (target_count_b - target_count_a)
|
m = (target_trim_b - target_trim_a) / (target_count_b - target_count_a)
|
||||||
n = target_trim_a - m * target_count_a
|
n = target_trim_a - m * target_count_a
|
||||||
program_trim = round(m * program_count + n)
|
program_trim = round(m * program_count + n)
|
||||||
|
if program_trim > 65535 or program_trim < 0:
|
||||||
|
raise StcProtocolException("frequency trimming failed")
|
||||||
|
|
||||||
# determine trim trials for second round
|
# determine trim trials for second round
|
||||||
trim_a, count_a = struct.unpack(">HH", response[12:16])
|
trim_a, count_a = struct.unpack(">HH", response[12:16])
|
||||||
@ -1116,10 +1120,14 @@ class Stc15AProtocol(Stc12Protocol):
|
|||||||
target_count_a = count_a
|
target_count_a = count_a
|
||||||
target_count_b = count_b
|
target_count_b = count_b
|
||||||
# linear interpolate to find range to try next
|
# linear interpolate to find range to try next
|
||||||
|
if target_count_a == target_count_b:
|
||||||
|
raise StcProtocolException("frequency trimming failed")
|
||||||
m = (target_trim_b - target_trim_a) / (target_count_b - target_count_a)
|
m = (target_trim_b - target_trim_a) / (target_count_b - target_count_a)
|
||||||
n = target_trim_a - m * target_count_a
|
n = target_trim_a - m * target_count_a
|
||||||
target_trim = round(m * user_count + n)
|
target_trim = round(m * user_count + n)
|
||||||
target_trim_start = min(max(target_trim - 5, target_trim_a), target_trim_b)
|
target_trim_start = min(max(target_trim - 5, target_trim_a), target_trim_b)
|
||||||
|
if target_trim_start + 11 > 65535 or target_trim_start < 0:
|
||||||
|
raise StcProtocolException("frequency trimming failed")
|
||||||
|
|
||||||
# trim challenge-response, second round
|
# trim challenge-response, second round
|
||||||
packet = bytes([0x65])
|
packet = bytes([0x65])
|
||||||
@ -1131,7 +1139,7 @@ class Stc15AProtocol(Stc12Protocol):
|
|||||||
self.write_packet(packet)
|
self.write_packet(packet)
|
||||||
self.pulse(timeout=1.0)
|
self.pulse(timeout=1.0)
|
||||||
response = self.read_packet()
|
response = self.read_packet()
|
||||||
if response[0] != 0x65:
|
if len(response) < 56 or response[0] != 0x65:
|
||||||
raise StcProtocolException("incorrect magic in handshake packet")
|
raise StcProtocolException("incorrect magic in handshake packet")
|
||||||
|
|
||||||
# determine best trim value
|
# determine best trim value
|
||||||
@ -1239,6 +1247,8 @@ class Stc15Protocol(Stc15AProtocol):
|
|||||||
calib_data = response[2:]
|
calib_data = response[2:]
|
||||||
challenge_data = packet[2:]
|
challenge_data = packet[2:]
|
||||||
calib_len = response[1]
|
calib_len = response[1]
|
||||||
|
if len(calib_data) < 2 * calib_len:
|
||||||
|
raise StcProtocolException("range calibration data missing")
|
||||||
|
|
||||||
for i in range(calib_len - 1):
|
for i in range(calib_len - 1):
|
||||||
count_a, count_b = struct.unpack(">HH", calib_data[2*i:2*i+4])
|
count_a, count_b = struct.unpack(">HH", calib_data[2*i:2*i+4])
|
||||||
@ -1248,6 +1258,8 @@ class Stc15Protocol(Stc15AProtocol):
|
|||||||
m = (trim_b - trim_a) / (count_b - count_a)
|
m = (trim_b - trim_a) / (count_b - count_a)
|
||||||
n = trim_a - m * count_a
|
n = trim_a - m * count_a
|
||||||
target_trim = round(m * target_count + n)
|
target_trim = round(m * target_count + n)
|
||||||
|
if target_trim > 65536 or target_trim < 0:
|
||||||
|
raise StcProtocolException("frequency trimming failed")
|
||||||
return (target_trim, trim_range)
|
return (target_trim, trim_range)
|
||||||
|
|
||||||
return None
|
return None
|
||||||
@ -1259,6 +1271,8 @@ class Stc15Protocol(Stc15AProtocol):
|
|||||||
calib_data = response[2:]
|
calib_data = response[2:]
|
||||||
challenge_data = packet[2:]
|
challenge_data = packet[2:]
|
||||||
calib_len = response[1]
|
calib_len = response[1]
|
||||||
|
if len(calib_data) < 2 * calib_len:
|
||||||
|
raise StcProtocolException("trim calibration data missing")
|
||||||
|
|
||||||
best = None
|
best = None
|
||||||
best_count = sys.maxsize
|
best_count = sys.maxsize
|
||||||
@ -1269,6 +1283,9 @@ class Stc15Protocol(Stc15AProtocol):
|
|||||||
best_count = abs(count - target_count)
|
best_count = abs(count - target_count)
|
||||||
best = (trim_adj, trim_range), count
|
best = (trim_adj, trim_range), count
|
||||||
|
|
||||||
|
if not best:
|
||||||
|
raise StcProtocolException("frequency trimming failed")
|
||||||
|
|
||||||
return best
|
return best
|
||||||
|
|
||||||
def calibrate(self):
|
def calibrate(self):
|
||||||
|
Loading…
Reference in New Issue
Block a user