Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rewrite most Foo* field_ pointer fields to raw_ptr<Foo> field_ #3239

Closed
magreenblatt opened this issue Dec 16, 2021 · 8 comments
Closed

Rewrite most Foo* field_ pointer fields to raw_ptr<Foo> field_ #3239

magreenblatt opened this issue Dec 16, 2021 · 8 comments
Labels
Framework Related to framework code or APIs task Task to be performed

Comments

@magreenblatt
Copy link
Collaborator

magreenblatt commented Dec 16, 2021

Original report by me.


Chromium has introduced a new raw_ptr<> type that potentially offers protection against use-after-free bugs. We should look at using this type in CEF (libcef/ code) as well.

For more information, see MiraclePtr One Pager [1], the PSA at chromium-dev@ [2], and the raw_ptr documentation at //base/memory/raw_ptr.md.

There is a script for automatically performing the conversion here and related Chromium changes in issue #1073933.

[1] https://docs.google.com/document/d/1pnnOAIz_DMWDI4oIOFoMAqLnf_MZ2GsrJNb_dbQ3ZBg/edit?usp=sharing
[2] https://groups.google.com/a/chromium.org/g/chromium-dev/c/vAEeVifyf78/m/SkBUc6PhBAAJ

@magreenblatt
Copy link
Collaborator Author

magreenblatt commented Dec 17, 2021

The benefits here may require PartitionAlloc, in which case we won’t get them when the allocator shim is disabled (see #3061)

magreenblatt added a commit that referenced this issue Apr 28, 2024
This is enabled by default on Mac in M125 but we can't use it until
raw_ptr<> is supported by libcef. For background see
https://chromium.googlesource.com/chromium/src/+/main/docs/dangling_ptr.md
@magreenblatt
Copy link
Collaborator Author

We can also restore the unretained dangling pointer detector crash-by-default behavior after this issue is resolved. See #3693.

@magreenblatt
Copy link
Collaborator Author

According to this chart, PartitionAlloc-Everywhere (PA-E) (use_partition_alloc_as_malloc) is not available in component builds, meaning that build support for Use-after-Free protection via BackupRefPtr (BRP) (enable_backup_ref_ptr_support) will require non-component builds. The actual requirement appears to be is_win && !is_component_build && !is_debug (_default_use_allocator_shim). Other platforms don't seem to have this requirement.

@magreenblatt
Copy link
Collaborator Author

Generating a Release build on Windows (M125) with is_component_build=false dcheck_always_on=true provides the following default values:

> gn args out\Release_GN_x64 --list=use_partition_alloc_as_malloc
use_partition_alloc_as_malloc
    Current value (from the default) = true
      From //base/allocator/partition_allocator/partition_alloc.gni:88

    PartitionAlloc-Everywhere (PA-E). Causes allocator_shim.cc to route
    calls to PartitionAlloc, rather than some other platform allocator.

> gn args out\Release_GN_x64 --list=enable_backup_ref_ptr_support
enable_backup_ref_ptr_support
    Current value (from the default) = true
      From //base/allocator/partition_allocator/partition_alloc.gni:147

> gn args out\Release_GN_x64 --list=enable_backup_ref_ptr_slow_checks
enable_backup_ref_ptr_slow_checks
    Current value (from the default) = false
      From //base/allocator/partition_allocator/partition_alloc.gni:189

> gn args out\Release_GN_x64 --list=enable_dangling_raw_ptr_checks
enable_dangling_raw_ptr_checks
    Current value (from the default) = true
      From //base/allocator/partition_allocator/partition_alloc.gni:204

> gn args out\Release_GN_x64 --list=backup_ref_ptr_poison_oob_ptr
backup_ref_ptr_poison_oob_ptr
    Current value (from the default) = false
      From //base/allocator/partition_allocator/partition_alloc.gni:223

> gn args out\Release_GN_x64 --list=enable_backup_ref_ptr_instance_tracer
enable_backup_ref_ptr_instance_tracer
    Current value (from the default) = false
      From //base/allocator/partition_allocator/partition_alloc.gni:216

@magreenblatt
Copy link
Collaborator Author

magreenblatt commented May 9, 2024

Some problems trying to build the rewrite tool on Windows: https://issues.chromium.org/issues/327699485#comment4

@magreenblatt
Copy link
Collaborator Author

magreenblatt commented May 10, 2024

Building the rewrite tool works on Ubuntu 22. The "Make sure out/rewrite/gen/…../some-generated-header.h files are built" step fails due to too many arguments. Using this version instead to build 1000 targets at a time (executes ~20k steps vs ~65k for a full build):

GEN_H_TARGETS=`ninja -C out/rewrite -t targets all | grep '^gen/.*\(\.h\|inc\|css_tokenizer_codepoints.cc\)' | cut -d : -f 1`
echo $GEN_H_TARGETS > targets.txt
cat targets.txt | xargs -n 1000 ninja -C out/rewrite

Also need to generate the CEF headers:

ninja -C out/rewrite cef_make_headers

@magreenblatt
Copy link
Collaborator Author

magreenblatt commented May 11, 2024

The clang scripts ignore directories that are not part of the main Chromium src repository by default, so we need to modify them a bit to work with the cef directory (apply clang_scripts.patch). We can then run with the following extract of rewrite.sh:

#!/bin/bash

set -e  # makes the script quit on any command failure
set -u  # unset variables are quit-worthy errors

OUT_DIR="out/rewrite"
COMPILE_DIRS=cef/libcef
EDIT_DIRS=cef/libcef

# A preliminary rewriter run in a special mode that generates a list of fields
# to ignore. These fields would likely lead to compiler errors if rewritten.
echo "*** Generating the ignore list ***"
time tools/clang/scripts/run_tool.py \
    --tool rewrite_raw_ptr_fields \
    --generate-compdb \
    -p $OUT_DIR \
    $COMPILE_DIRS > ~/scratch/rewriter.out
cat ~/scratch/rewriter.out \
    | sed '/^==== BEGIN FIELD FILTERS ====$/,/^==== END FIELD FILTERS ====$/{//!b};d' \
    | sort | uniq > ~/scratch/automated-fields-to-ignore.txt
cat ~/scratch/automated-fields-to-ignore.txt \
    tools/clang/rewrite_raw_ptr_fields/manual-fields-to-ignore.txt \
    | grep -v "base::FileDescriptorWatcher::Controller::watcher_" \
    > ~/scratch/combined-fields-to-ignore.txt

# Main rewrite.
echo "*** Running the main rewrite phase ***"
time tools/clang/scripts/run_tool.py \
    --tool rewrite_raw_ptr_fields \
    --tool-arg=--exclude-fields=$HOME/scratch/combined-fields-to-ignore.txt \
    -p $OUT_DIR \
    $COMPILE_DIRS > ~/scratch/rewriter.main.out

# Apply edits generated by the main rewrite.
echo "*** Applying edits ***"
cat ~/scratch/rewriter.main.out | \
    tools/clang/scripts/extract_edits.py | \
    tools/clang/scripts/apply_edits.py -p $OUT_DIR $EDIT_DIRS

Result:

*** Generating the ignore list ***
Evaluating 584 files
Processed 274 files with /home/marshall/code/chromium_git/chromium/src/third_party/llvm-build/Release+Asserts/bin/rewrite_raw_ptr_fields tool (0 failures) [100.00%]

real	12m3.214s
user	87m36.712s
sys	2m48.719s
*** Running the main rewrite phase ***
Evaluating 584 files
Processed 274 files with /home/marshall/code/chromium_git/chromium/src/third_party/llvm-build/Release+Asserts/bin/rewrite_raw_ptr_fields tool (0 failures) [100.00%]

real	11m29.496s
user	85m21.222s
sys	2m29.357s
*** Applying edits ***
Evaluating 584 files
Applied 273 edits (0 errors) to 108 files [100.00%]

@magreenblatt
Copy link
Collaborator Author

  # - enable_backup_ref_ptr_instance_tracer: use a global table to track all
  #   live raw_ptr/raw_ref instances to help debug dangling pointers at test
  #   end.

This is a very useful feature that we'll enable by default in non-Official builds where BackupRefPtr is supported. From the commit, the runtime penalty for this is <10%.

magreenblatt added a commit that referenced this issue May 21, 2024
Compatible configurations include:
- Non-component builds.
- Debug builds on Mac/Linux.
- Release builds on Windows (b/c Debug builds require component builds).
- ASAN builds (which are also Release builds).

See related logic in //build_overrides/partition_alloc.gni
magreenblatt added a commit that referenced this issue May 21, 2024
- Use raw_ptr in class container fields.
- Use defined lifespan for StreamReaderURLLoader.
- Fix lifespan assumptions for WebContents/RFH usage.
magreenblatt added a commit that referenced this issue May 21, 2024
OnBeforeClose notification is delivered via TabModel destruction in
TabStripModel::SendDetachWebContentsNotifications. We need to let
that call stack unwind before triggering TabStripModel destruction
via closure of the native host window.
magreenblatt added a commit that referenced this issue Jun 18, 2024
This reverts commit 47798d3.

It doesn't appear to have fixed the issue (see #3717).
magreenblatt added a commit that referenced this issue Jun 20, 2024
Fixes some issues introduced by 8e79307 (see #3314) and
6354d8d (see #3239).

To test:
- Run `cefclient --url=chrome://net-export`
- Click the "Start Logging to Disk" button
- Exit cefclient; get no debug assertions
magreenblatt added a commit that referenced this issue Jun 20, 2024
Fixes some issues introduced by 8e79307 (see #3314) and
6354d8d (see #3239).

To test:
- Run `cefclient --url=chrome://net-export`
- Click the "Start Logging to Disk" button
- Exit cefclient; get no debug assertions
magreenblatt added a commit that referenced this issue Jun 20, 2024
Fixes some issues introduced by 8e79307 (see #3314) and
6354d8d (see #3239).

To test:
- Run `cefclient --url=chrome://net-export`
- Click the "Start Logging to Disk" button
- Exit cefclient; get no debug assertions
magreenblatt pushed a commit that referenced this issue Jun 21, 2024
Found using a CEF build with clang_use_chrome_plugins=true
and treat_warnings_as_errors=false.

This change rewrites remaining raw pointers reported by
chromium-rawptr checker and fixes a build error reported
by StackAllocatedChecker.
magreenblatt pushed a commit that referenced this issue Jun 21, 2024
Found using a CEF build with clang_use_chrome_plugins=true
and treat_warnings_as_errors=false.

This change rewrites remaining raw pointers reported by
chromium-rawptr checker and fixes a build error reported
by StackAllocatedChecker.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Framework Related to framework code or APIs task Task to be performed
Projects
None yet
Development

No branches or pull requests

1 participant