Skip to content

mcstrans: fix out-of-bounds read in parse_raw sensitivity parsing - #533

Closed
netliomax25-code wants to merge 1 commit into
SELinuxProject:mainfrom
netliomax25-code:mcstrans-parse-raw-oob
Closed

mcstrans: fix out-of-bounds read in parse_raw sensitivity parsing#533
netliomax25-code wants to merge 1 commit into
SELinuxProject:mainfrom
netliomax25-code:mcstrans-parse-raw-oob

Conversation

@netliomax25-code

Copy link
Copy Markdown
Contributor

Repro: send mcstransd a context whose range high level is "s-1" (e.g. the range "s0-s-1"); trans_context() splits the range on its first dash and calls parse_raw("s-1").

Cause: parse_raw() advances the cursor with raw += numdigits(sens) + 1 after sscanf(raw, "s%u", &sens). sscanf %u accepts a leading minus, so "s-1" stores UINT_MAX into sens and numdigits() returns 10 while only two characters were consumed. raw moves 11 bytes past the 4-byte allocation and the next *raw == : test reads out of bounds. The string is attacker-controlled: it is the MLS range of any context handed to the mcstransd socket via trans_context()/untrans_context() -> extract_range() -> compute_trans_from_raw(). parse_category() advances with the same numdigits construct at two sites; those are currently shielded only by the >= MAX_CATS checks.

Fix: advance by the number of characters sscanf actually consumed via %n at all three sites and drop numdigits(). Validated with an ASAN build of the parse_raw sensitivity logic: input "s-1" reports a heap-buffer-overflow read 7 bytes past the 4-byte buffer before the change, and runs clean after; "s5", "s5:c1.c3" and "s0" parse unchanged.

parse_raw() advanced the cursor with raw += numdigits(sens) + 1 after
sscanf(raw, "s%u", &sens), assuming the consumed length equals the digit
count of the parsed value. sscanf %u accepts a leading minus, so a level
like "s-1" stores UINT_MAX and numdigits() returns 10 while only two
characters were read; raw jumps 11 bytes past a 4-byte buffer and the
following *raw == ':' test reads out of bounds. The range reaches
parse_raw from trans_context()/untrans_context() -> extract_range() ->
compute_trans_from_raw() for any context sent to the mcstransd socket;
trans_context splits the range on its first dash, so a high level such
as "s0-s-1" arrives here as "s-1". parse_category() uses the same
numdigits-based advance at two sites, shielded today only by the
MAX_CATS checks. Use sscanf %n to advance by the characters actually
consumed at all three sites and drop numdigits().

Signed-off-by: netliomax25-code <netliomax25@gmail.com>

@williamcroberts williamcroberts left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed not tested, but it looks good. I had no idea that sscand supports %n.

This needs to go through mailing list like all patches and as @stephensmalley mentioned, your signoff and author details need to be your name.

Negative diffstat for the win, my favorite kind of patches.

@netliomax25-code

Copy link
Copy Markdown
Contributor Author

Sounds good.

  1. The commit already has the full description in the body and a Signed-off-by, so it should be ready as-is. The author and sign-off both use the handle I contribute under; let me know if you need the From/sign-off in a different form for the list and I'll adjust.

  2. On the not-tested point: I validated the sensitivity path under ASAN before sending. "s-1" reads 7 bytes past the 4-byte buffer before the change and runs clean after, while "s5", "s5:c1.c3" and "s0" parse unchanged. Can attach the standalone repro if it's useful.

  3. I'm not currently set up for git send-email. You'd offered before to post on a contributor's behalf, so if that still stands I'd appreciate it; otherwise I'll get send-email working and submit it myself.

@stephensmalley

Copy link
Copy Markdown
Member

Posted to the mailing list with a corrected Signed-off-by line; is there a reason you haven't fixed this on your end?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants