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

Constructing color codes using snprintf for memory safety #21

Merged

Conversation

garretcarrot
Copy link
Contributor

@garretcarrot garretcarrot commented Sep 24, 2020

Summary: Running the choose binary terminates in a SIGILL (illegal instruction). I'm hoping this change keeps that from happening!

I originally experienced this when looking at Homebrew/homebrew-core#59669. I have some more notes on how I arrived at this point, if anyone is interested. But I'll leave out the boring details, and stick to the relevant points. I'd be happy to answer any questions if I can.

Reproducing the error

These are the steps I took on the default branch. When I do them with applied changes, I see the expected output.

  1. Build from source:

    > xcodebuild SDKROOT= SYMROOT=build clean
    > xcodebuild SDKROOT= SYMROOT=build -configuration Release build
    
  2. Run the executable. Actual output:

    # Bash
    $ /usr/local/Cellar/choose-gui/1.2/bin/choose -h
    Illegal instruction: 4
    
     # Zsh
     % /usr/local/Cellar/choose-gui/1.2/bin/choose -h
     zsh: illegal hardware instruction  /usr/local/Cellar/choose-gui/1.2/bin/choose -h
    
     # fish
     > /usr/local/Cellar/choose-gui/1.2/bin/choose -h
     fish: '/usr/local/Cellar/choose-gui/1.…' terminated by signal SIGILL (Illegal instruction)
    
  3. Expected output:

    > build/Release/choose -h
    usage: build/Release/choose
    --snip--
    

System Software Overview

Versions:

  • System: macOS 10.15.6 (19G2021)
  • Kernel: Darwin 19.6.0
  • Xcode: Version 11.7 (11E801a)

@garretcarrot garretcarrot marked this pull request as ready for review September 24, 2020 17:17
@chipsenkbeil
Copy link
Owner

Great find! Thanks!

@chipsenkbeil chipsenkbeil merged commit 3e7a381 into chipsenkbeil:master Sep 24, 2020
@chipsenkbeil
Copy link
Owner

See new PR for version 1.2.1 (contains your fix) for homebrew: Homebrew/homebrew-core#61618

@chipsenkbeil
Copy link
Owner

Also, @garretcarrot, I'm interested in how you figured out the culprit here, in case you want to share one day. 😄

@garretcarrot
Copy link
Contributor Author

I figured out where the illegal instruction was happening using lldb, but not why it was happening -- until now. Had I known C better, it would have been clear from reading the code: strings are NUL-terminated, so the format string "%2X%2X%2X" is actually seven bytes, not six, and the sprintf was failing to write past the end of the array.

(So there was also a bug in the new code; the fix for that is in #22.)

LLDB actually points out that the process ends up in __sprintf_chk which I did not know about, so at least there's some guard against unsafe memory access!

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.

2 participants