Closed Bug 1533527 Opened 6 years ago Closed 6 years ago

malloc and calloc silently truncate int64_t and uint64_t on 32bit

Categories

(Core :: Graphics: CanvasWebGL, enhancement, P1)

enhancement

Tracking

()

RESOLVED FIXED
mozilla68
Tracking Status
firefox-esr60 --- wontfix
firefox66 --- wontfix
firefox67 --- wontfix
firefox68 --- fixed

People

(Reporter: jgilbert, Assigned: jgilbert)

References

Details

(Keywords: sec-want, Whiteboard: gfx-noted [post-critsmash-triage][adv-main68-])

Attachments

(1 file)

This is just terrible design on the part of malloc and calloc.

I'm worried that even enabling truncation warnings will only find this on 32bit builds.

Fortunately, there's a c++ template construct we can use here.

See Also: → CVE-2019-11693
// Prevent implicit conversions into calloc and malloc.

template<typename RequireSizeT1, typename RequireSizeT2>
void* calloc(RequireSizeT1 n, RequireSizeT2 size) = delete;

template<>
void* calloc<size_t, size_t>(size_t n, size_t size) { return ::calloc(n, size); }

template<typename RequireSizeT>
void* malloc(RequireSizeT size) = delete;

template<>
void* malloc<size_t>(size_t size) { return ::malloc(size); }

// uint32_t is also always ok:
template<>
void* calloc<size_t, uint32_t>(size_t n, uint32_t size) { return ::calloc(n, size); }
template<>
void* calloc<uint32_t, size_t>(uint32_t n, size_t size) { return ::calloc(n, size); }
template<>
void* calloc<uint32_t, uint32_t>(uint32_t n, uint32_t size) { return ::calloc(n, size); }
template<>
void* malloc<uint32_t>(uint32_t size) { return ::malloc(size); }
Assignee: nobody → jgilbert
Priority: -- → P1

:waldo pointed out that typedefs are undetectable to templates, though this did find some bugs on my x64 build, probably due to unsigned int vs unsigned long.

Keywords: sec-want
Whiteboard: gfx-noted

Comment on attachment 9049394 [details]
Bug 1533527 - Forbid non-size_t calls to malloc and calloc.

Security Approval Request

  • How easily could an exploit be constructed based on the patch?: None of the fixed code seems to be vulnerable, but this is something we should spread to the rest of the tree.
  • Do comments in the patch, the check-in comment, or tests included in the patch paint a bulls-eye on the security problem?: Yes
  • Which older supported branches are affected by this flaw?: all
  • If not all supported branches, which bug introduced the flaw?: None
  • Do you have backports for the affected branches?: No
  • If not, how different, hard to create, and risky will they be?: trivial
  • How likely is this patch to cause regressions; how much testing does it need?: Very unlikely.
Attachment #9049394 - Flags: sec-approval?

As a sec-want, this doesn't need sec-approval. We should put this on trunk but it is too late to backport it to 66, which goes to RC next week.

Attachment #9049394 - Flags: sec-approval?

Roger that.

Landed: https://hg.mozilla.org/integration/autoland/rev/5f7ea2187fa661b0d3822c2e82a5601d89a50769

Backed out for build bustages:

https://hg.mozilla.org/integration/autoland/rev/f0eaf5676456b5bc7c8d8e642441cbb9b8d9788f

Push with bustage: https://treeherder.mozilla.org/#/jobs?repo=autoland&resultStatus=retry%2Cusercancel%2Ctestfailed%2Cbusted%2Cexception&group_state=expanded&searchStr=windows%2Cpgo&revision=5f7ea2187fa661b0d3822c2e82a5601d89a50769
Build log: https://treeherder.mozilla.org/logviewer.html#?job_id=232958174&repo=autoland

[task 2019-03-10T01:50:59.672Z] 01:50:59 INFO - In file included from /builds/worker/workspace/build/src/obj-firefox/dist/include/mozilla/gfx/Rect.h:14:
[task 2019-03-10T01:50:59.672Z] 01:50:59 ERROR - /builds/worker/workspace/build/src/obj-firefox/dist/include/mozilla/gfx/Tools.h:128:41: error: call to deleted function 'calloc'
[task 2019-03-10T01:50:59.673Z] 01:50:59 INFO - mStorage = static_cast<uint8_t >(calloc((size_t)1, storageByteCount.value()));
[task 2019-03-10T01:50:59.673Z] 01:50:59 INFO - ^~~~~~
[task 2019-03-10T01:50:59.674Z] 01:50:59 INFO - /builds/worker/workspace/build/src/dom/canvas/WebGLTypes.h:22:7: note: candidate function [with RequireSizeT1 = unsigned long, RequireSizeT2 = int] has been explicitly deleted
[task 2019-03-10T01:50:59.674Z] 01:50:59 INFO - void
calloc(RequireSizeT1 n, RequireSizeT2 size) = delete;
[task 2019-03-10T01:50:59.674Z] 01:50:59 INFO - ^
[task 2019-03-10T01:50:59.674Z] 01:50:59 INFO - /usr/include/malloc.h:54:14: note: candidate function
[task 2019-03-10T01:50:59.674Z] 01:50:59 INFO - extern void *calloc __MALLOC_P ((size_t __nmemb, size_t __size))

Flags: needinfo?(jgilbert)
Group: core-security → gfx-core-security

I'll nurse this through this week.

Fortunately, this doesn't change functionality, so it can go in during soft-freeze.

Flags: needinfo?(jgilbert)
Group: gfx-core-security → core-security-release
Status: NEW → RESOLVED
Closed: 6 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla68

Nothing found here seemed to turn up any sec issues, so fix-optional for 67.

I would de-sec this bug, but I don't really want to do that until we expand this approach to the whole tree.

This can ride the trains if it didn't turn up any sec issues.

Flags: qe-verify-
Whiteboard: gfx-noted → gfx-noted [post-critsmash-triage]
Whiteboard: gfx-noted [post-critsmash-triage] → gfx-noted [post-critsmash-triage][adv-main68-]
Group: core-security-release
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: