Closed Bug 925031 Opened 11 years ago Closed 2 years ago

TextInputHandler.mm:3841:5 [-Warray-bounds] array index 1 is past the end of the array (which contains 1 element)

Categories

(Core :: Widget: Cocoa, defect)

x86
macOS
defect
Not set
normal

Tracking

()

RESOLVED INCOMPLETE

People

(Reporter: jaas, Unassigned)

References

Details

Attachments

(1 file, 3 obsolete files)

Our code:

    InterfaceTypeList supportedServices;
    supportedServices[0] = kTextServiceDocumentInterfaceType;
    supportedServices[1] = kUnicodeDocumentInterfaceType;
    ::NewTSMDocument(2, supportedServices, &mPluginTSMDoc, 0);

The definition for InterfaceTypeList:

    typedef OSType InterfaceTypeList[1];

Thus supportedServices[1] is an invalid assignment. I wonder if this ever shows up in crash stats.
Assignee: nobody → masayuki
Severity: normal → critical
Group: core-security
Marking this security sensitive to be safe.
I think I'm originally responsible for that code, so I'll take it.

The fix should be very straightforward.
Assignee: masayuki → smichaud
Still (re)building my patch.

But I've found that, at least in recent clang builds, we're saved by the skin of our teeth from having this bug cause any crashes.

PluginTextInputHandler::ActivatePluginTSMDocument() (which has this bug) is only compiled in 32-bit mode.  Furthermore supportedServices is its only stack variable -- which (on the face of it) makes it likely there's extra room in the space set aside for stack variables, and that writing one element beyond the end of this array won't stomp on anything else.

I've confirmed (using gdb's disassemble) that's the case in recent clang builds:  Altogether 20 bytes are provided for stack variables, and 8 bytes are provided for supportedServices -- which is exactly what's needed.
(I checked this in a recent mozilla-central nightly, which is an opt build without symbols stripped.)
Attached patch Fix (obsolete) — Splinter Review
The syntax is a bit weird, so I'm doing a set of Mac tryserver builds before I ask for a review.  Clang wouldn't let me C-cast an OSType* to an InterfaceTypeList, but had no problems with this syntax.  The resulting assembly code also looked correct.

I'll ask Josh for a review if/when the tryserver builds turn out OK.  The results will eventually be available here:

https://tbpl.mozilla.org/?tree=Try&rev=2b8afda65006
Comment on attachment 815140 [details] [diff] [review]
Fix

Review of attachment 815140 [details] [diff] [review]:
-----------------------------------------------------------------

::: widget/cocoa/TextInputHandler.mm
@@ +3836,5 @@
>      // more than one kind of input (say Hiragana and Romaji).  This is what
>      // the OS does when it creates a TSM document for use by an
>      // NSTSMInputContext class.
> +    OSType holder[2];
> +    InterfaceTypeList& supportedServices = (InterfaceTypeList&) holder;

Better to use static_cast if nothing is preventing you from doing so.
Attached patch Fix rev1 (obsolete) — Splinter Review
Apparently the rules for static_cast are stricter than those for C-style casts -- I found I couldn't get static_cast to work with my previous patch.  So I rewrote it.  Along the way I found you still get the compiler's warning if you try to set (*supportedServices)[1], so I set holder[1] (and holder[0]) instead.

Clearly Apple's definition of InterfaceTypeList (which makes its size one element) is a design flaw -- Apple's own code uses InterfaceTypeList arrays with more than one element.  But it's not hard to work around.  And in any case the Text Input Manager APIs are now obsolescent.
Attachment #815140 - Attachment is obsolete: true
Attachment #815416 - Flags: review?(joshmoz)
Comment on attachment 815416 [details] [diff] [review]
Fix rev1

Oops, uploaded wrong patch.
Attachment #815416 - Attachment is obsolete: true
Attachment #815416 - Flags: review?(joshmoz)
Attached patch Fix rev1 (obsolete) — Splinter Review
Attachment #815422 - Flags: review?(joshmoz)
Attached patch Fix rev2Splinter Review
Actually it makes better sense to use reinterpret_cast.
Attachment #815422 - Attachment is obsolete: true
Attachment #815422 - Flags: review?(joshmoz)
Attachment #815455 - Flags: review?(joshmoz)
Attachment #815455 - Flags: review?(joshmoz) → review+
Does this do what it's supposed to do? If you ignore the types, you basically pass *holder to NewTSMDocument, and not holder (without the deref)... or is C++ just that confusing?
Comment on attachment 815455 [details] [diff] [review]
Fix rev2

Review of attachment 815455 [details] [diff] [review]:
-----------------------------------------------------------------

I think Markus is right, it's incorrect. The definition for InterfaceTypeList is:

typedef OSType InterfaceTypeList[1];

And the definition for NewTSMDocument is:

extern OSErr NewTSMDocument(SInt16 numOfInterface, InterfaceTypeList supportedInterfaceTypes,
                            TSMDocumentID * idocID, SRefCon refcon)  

So,

InterfaceTypeList* supportedServices = reinterpret_cast<InterfaceTypeList*>(holder);

should be:

InterfaceTypeList supportedServices = reinterpret_cast<InterfaceTypeList>(holder);

Very confusing code.
Attachment #815455 - Flags: review+ → review-
Actually I think my original patch was correct, but what Josh suggests would be less confusing ... if it works.

Note that 'holder' and '&holder' are synonyms, and that I passed '*supportedServices' to NewTSMDocument().

A big raspberry to Apple for its horrible definition of InterfaceTypeList :-(
Josh's suggestion doesn't compile.  Let me see what else I can come up with.
This bug isn't urgent -- we're not crashing because of it.  And I still haven't been able to come up with a solution that's both correct and "easy to read".  So I'm going to put this off for a while, then (hopefully) come back to it later with a fresh outlook.
Severity: critical → normal
It doesn't sound like this is really exploitable, but feel free to adjust the rating as needed.
Keywords: sec-low
Shall we unmark this as a security bug?

We actually don't crash.  And this bug is very easily discovered, since it spawns a warning.
Flags: needinfo?(continuation)
Sounds reasonable to me.
Group: core-security
Flags: needinfo?(continuation)
Keywords: sec-low

Sorry, there was a problem with the detection of inactive users. There was no action for a while so I won't revert the change, but feel free to reassign it to yourself in case you're still planning to work on this.

Sorry, there was a problem with the detection of inactive users. I'm reverting the change.

Assignee: nobody → smichaud

This is left over from when I was a Mozilla employee. I'll never get back to it.

Assignee: smichaud → nobody

There is no trace of this code left in tree anymore.

Status: NEW → RESOLVED
Closed: 2 years ago
Resolution: --- → INCOMPLETE
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: