Skip to content

Commit

Permalink
restrict tool paths
Browse files Browse the repository at this point in the history
Restrict tool paths to PATH, Goa-internal tools and the default Genode
tool-chain path. The set of allowed tool paths can be extended by adding
`lappend allowed_tools ...` commands to _~/goarc_ or _/goarc_.

This commit prevents malicious configuration of cross_dev_prefix.

genodelabs#99
  • Loading branch information
jschlatow committed Sep 11, 2024
1 parent cdddfd8 commit 2a4dd75
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 17 deletions.
6 changes: 6 additions & 0 deletions share/goa/doc/config.txt
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,12 @@ mentioned above, path variables are checked against a list of allowed paths
to make sure that untrusted configuration files cannot trick Goa into undesired
file operations.

Moreover, Goa checks the 'cross_dev_prefix' against a list of allowed tool paths.
By default, Goa allows tools to reside in the directories defined by the PATH
environment variable or in "/usr/local/genode". Similar to extending the
'allowed_paths' variable, a user may extend this policy by adding a path to the
list 'allowed_tools' list.

SEE ALSO
########

Expand Down
44 changes: 27 additions & 17 deletions share/goa/lib/config.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -71,30 +71,40 @@ namespace eval ::config {

# used as alias for 'lappend' in child interpreter
proc _lappend_allowed_paths { safeinterp args } {
global allowed_paths
global allowed_paths allowed_tools

set nargs [llength $args]
if {$nargs < 2} { return }

set name [lindex $args 0]
set value [lindex $args 1]
if {$name == "allowed_paths"} {
if {$name == "allowed_paths" || $name == "allowed_tools"} {
# de-reference home directory
regsub {^~} $::env(HOME) value

# convert relative path to absolute path
set value [file normalize $value]

lappend allowed_paths $value
lappend $name $value
} else {
$safeinterp invokehidden lappend {*}$args
}
}


proc _is_sub_directory { value paths } {

foreach path $paths {
if {[regexp "^$path" $value]} {
return 1 }}

return 0
}


# used as alias for 'set' in child interpreter
proc _safe_set { rcfile args } {
global allowed_paths
global allowed_paths allowed_tools

set nargs [llength $args]
if {$nargs < 1} { return }
Expand Down Expand Up @@ -127,21 +137,17 @@ namespace eval ::config {
# convert relative path to absolute path
set value [file normalize $value]

# check that path is subdirectory of pwd, project dir or one of
# the user-defined directories
set valid_path 0
foreach path $allowed_paths {
if {[regexp "^$path" $value]} {
set valid_path 1
break
}
}
if {!$valid_path} {
set varname allowed_paths
if {$name == "cross_dev_prefix"} {
set varname allowed_tools }

# check that path is a valid subdirectory
if {![_is_sub_directory $value [set $varname]]} {
exit_with_error "In $rcfile:" \
"\n Path variable '$name' set to '$value'" \
"\n defines an invalid path. Valid paths are:\n" \
"\n [join $allowed_paths "\n "]" \
"\n\n You may consider setting 'allowed_paths' in" \
"\n [join [set $varname] "\n "]" \
"\n\n You may consider setting '[set $varname]' in" \
"your \$HOME/goarc or /goarc file."
}
}
Expand All @@ -152,11 +158,15 @@ namespace eval ::config {

proc load_goarc_files {} {
global tool_dir original_dir config::project_dir
global allowed_paths
global allowed_paths allowed_tools

set allowed_paths [list [file normalize $project_dir] [file normalize $original_dir]]
set allowed_paths [lsort -unique $allowed_paths]

set allowed_tools [split $::env(PATH) ":"]
lappend allowed_tools "/usr/local/genode"
lappend allowed_tools $tool_dir

interp create -safe safeinterp
safeinterp hide set

Expand Down

0 comments on commit 2a4dd75

Please sign in to comment.