Skip to content

Commit

Permalink
Make LM skip instead of crashing for invalid messages (#5290)
Browse files Browse the repository at this point in the history
  • Loading branch information
gdkchan authored Jun 13, 2023
1 parent 52aa4b6 commit cf4c78b
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 14 deletions.
18 changes: 18 additions & 0 deletions src/Ryujinx.Common/Memory/SpanReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,24 @@ public T Read<T>() where T : unmanaged
return value;
}

public bool TryRead<T>(out T value) where T : unmanaged
{
int valueSize = Unsafe.SizeOf<T>();

if (valueSize > _input.Length)
{
value = default;

return false;
}

value = MemoryMarshal.Cast<byte, T>(_input)[0];

_input = _input.Slice(valueSize);

return true;
}

public ReadOnlySpan<byte> GetSpan(int size)
{
ReadOnlySpan<byte> data = _input.Slice(0, size);
Expand Down
45 changes: 31 additions & 14 deletions src/Ryujinx.Horizon/LogManager/Ipc/LmLogger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ partial class LmLogger : ILmLogger
private const int MessageLengthLimit = 5000;

private readonly LogService _log;
private readonly ulong _pid;
private readonly ulong _pid;

private LogPacket _logPacket;

Expand Down Expand Up @@ -74,8 +74,12 @@ private static bool SetProcessId(Span<byte> message, ulong processId)

private bool LogImpl(ReadOnlySpan<byte> message)
{
SpanReader reader = new(message);
LogPacketHeader header = reader.Read<LogPacketHeader>();
SpanReader reader = new(message);

if (!reader.TryRead(out LogPacketHeader header))
{
return true;
}

bool isHeadPacket = (header.Flags & LogPacketFlags.IsHead) != 0;
bool isTailPacket = (header.Flags & LogPacketFlags.IsTail) != 0;
Expand All @@ -84,8 +88,10 @@ private bool LogImpl(ReadOnlySpan<byte> message)

while (reader.Length > 0)
{
int type = ReadUleb128(ref reader);
int size = ReadUleb128(ref reader);
if (!TryReadUleb128(ref reader, out int type) || !TryReadUleb128(ref reader, out int size))
{
return true;
}

LogDataChunkKey key = (LogDataChunkKey)type;

Expand All @@ -101,15 +107,24 @@ private bool LogImpl(ReadOnlySpan<byte> message)
}
else if (key == LogDataChunkKey.Line)
{
_logPacket.Line = reader.Read<int>();
if (!reader.TryRead<int>(out _logPacket.Line))
{
return true;
}
}
else if (key == LogDataChunkKey.DropCount)
{
_logPacket.DropCount = reader.Read<long>();
if (!reader.TryRead<long>(out _logPacket.DropCount))
{
return true;
}
}
else if (key == LogDataChunkKey.Time)
{
_logPacket.Time = reader.Read<long>();
if (!reader.TryRead<long>(out _logPacket.Time))
{
return true;
}
}
else if (key == LogDataChunkKey.Message)
{
Expand Down Expand Up @@ -154,23 +169,25 @@ private bool LogImpl(ReadOnlySpan<byte> message)
return isTailPacket;
}

private static int ReadUleb128(ref SpanReader reader)
private static bool TryReadUleb128(ref SpanReader reader, out int result)
{
int result = 0;
int count = 0;

result = 0;
int count = 0;
byte encoded;

do
{
encoded = reader.Read<byte>();
if (!reader.TryRead<byte>(out encoded))
{
return false;
}

result += (encoded & 0x7F) << (7 * count);

count++;
} while ((encoded & 0x80) != 0);

return result;
return true;
}
}
}

0 comments on commit cf4c78b

Please sign in to comment.