Skip to content

Port Apple's various shell commands from C to Rust

Notifications You must be signed in to change notification settings

CleanCut/shell_cmds

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

51 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Rust port of Apple's shell_cmds

Port Apple's shell commands from C to Rust. To learn more about ancient shell commands and Rust, and to have fun.

Contributing

  • Want to help? Please do! The easiest way to contact me to discuss things is by creating an issue or pull request

  • Code to port: shell_cmds version 198

  • Commands need a file in src/bin/ with a fn main(). For example echo has src/bin/echo.rs

  • To compile+run your new command (for example) echo arg1 arg2 you would do cargo run --bin echo -- arg1 arg2

  • Use std::env::args() directly for the dirt-simple utilities. Use getopts for the fancier ones.

  • Put the man pages (files ending in .1) in the man/ directory.

  • Put the companion shell scripts in the sh/ directory.

  • When there's a license header, copy it over verbatim into the .rs file for the binary. (Lawyer repellent.)

Porting Status

  • alias - Just a man page pointer to builtin.1, which is csh's manpage.
  • apply - Some serious pointer-loop reverse engineering on this one.
  • basename - Ancient utilities are frustrating because their behavior with arguments makes no blasted sense. basename is one of these. If it has exactly two arguments, then it acts completely differently.
  • chroot - Many calls to libc. Seems to have matched behavior exactly, except for the buffer overflow vulnerability.
  • date
  • dirname - Shares a man page with basename.
  • echo - Got an education in rust Strings.
  • env
  • expr
  • false - Simple.
  • find
  • getopt
  • hexdump
  • hostname
  • id
  • jot
  • kill
  • killall
  • lastcomm
  • locate
  • logname
  • mktemp
  • nice
  • nohup
  • path_helper
  • printenv - Done. Did you know printenv silently ignores any extra arguments?
  • pwd
  • renice
  • script
  • seq
  • sh
  • shlock
  • sleep - Instead of treating invalid input as 0 silently, we spit out the usage and die.
  • su
  • systime
  • tee - Done. Good practice with Vec, zip(), stdin/stdout/stderr, and files.
  • test
  • time
  • true - Simple.
  • uname
  • users
  • w
  • what
  • whereis
  • which
  • who
  • xargs
  • yes - Did you know that yes takes an optional argument?

Bugs in Original

Below is a partial list of bugs discovered in C code of Apple's shell_cmds which ship on macOS.

chroot.c

  • Buffer Overflow: If more than 16 valid groups are provided to the -G option, then the gidlist buffer overflows and starts overwriting later data in the stack frame with resolved group ids. That is not difficult to do since macOS ships with over 100 valid groups by default. In Rust, we use a Vec to store the resolved group ids. Vec is dynamically sized, so it won't overflow.

About

Port Apple's various shell commands from C to Rust

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published