Skip to content

Commit

Permalink
config: restrict path variables
Browse files Browse the repository at this point in the history
Restrict path variables to working directory and project directory. The
set of allowed paths can be extended by adding `lappend allowed_paths ...`
commands to _~/goarc_ or _/goarc_.

genodelabs#99
  • Loading branch information
jschlatow committed Sep 12, 2024
1 parent 0bb89f5 commit b501c83
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 1 deletion.
9 changes: 9 additions & 0 deletions share/goa/doc/config.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,15 @@ is defined as follows:
If <value> is a path name, the path can be specified relative to the location
of the 'goarc' file or relative to the user's home directory '~'.

By default, Goa prevents definition of path variables outside the current
working directory or project directory. A user may extend this policy by
adding a path to the list 'allowed_paths' as follows:

! lappend allowed_paths <path>

Note that this instruction is only effective within the privileged configuration
files at '~/goarc' and '/goarc'.


Settings
########
Expand Down
61 changes: 60 additions & 1 deletion share/goa/lib/config.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,33 @@ namespace eval ::config {
}


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

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

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

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

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


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

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

Expand Down Expand Up @@ -101,14 +126,36 @@ 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} {
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" \
"your \$HOME/goarc or /goarc file."
}
}

return [set ::config::$name $value]
}


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

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

interp create -safe safeinterp
safeinterp hide set
Expand All @@ -117,6 +164,12 @@ namespace eval ::config {
safeinterp alias set config::_safe_set $rcfile
safeinterp invokehidden source $rcfile

#
# build list of privileged goarc files
#
lappend privileged_rcfiles [file normalize $::env(HOME)]
lappend privileged_rcfiles [file normalize "/"]

#
# Read the hierarcy of 'goarc' files
#
Expand Down Expand Up @@ -146,6 +199,12 @@ namespace eval ::config {
#
cd $goarc_path
safeinterp alias set config::_safe_set $goarc_file_path

# install alias for privileged goarc files
if {[lsearch -exact $privileged_rcfiles $goarc_path] >= 0} {
safeinterp hide lappend
safeinterp alias lappend config::_lappend_allowed_paths safeinterp
}
safeinterp invokehidden source $goarc_file_path
}
}
Expand Down

0 comments on commit b501c83

Please sign in to comment.