Skip to content

Commit

Permalink
load goarc files with safe slave interpreter
Browse files Browse the repository at this point in the history
TCL's safe interpreter hides file operations, source, and exec commands.
Loading goarc files with a safe slave interpreter is a basic security
measure. This change also moves all config variables into a separate
namespace. Our interpreter additionally hides the set command in order to
make sure that goarc files are only able to set predefined variables in
the config namespace.

genodelabs#99
  • Loading branch information
jschlatow committed Sep 6, 2024
1 parent bdee6c6 commit c8c780e
Show file tree
Hide file tree
Showing 20 changed files with 456 additions and 344 deletions.
28 changes: 14 additions & 14 deletions bin/goa
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,8 @@ if {$perform(add-depot-user)} {
# The following commands only work when the current working directory is a goa
# project.
#
if {![looks_like_goa_project_dir $project_dir] && ![has_src_but_no_artifacts $project_dir]} {
exit_with_error "$project_dir does not look like a goa project" }
if {![looks_like_goa_project_dir $config::project_dir] && ![has_src_but_no_artifacts $config::project_dir]} {
exit_with_error "$config::project_dir does not look like a goa project" }


source [file join $tool_dir lib actions versions.tcl]
Expand Down Expand Up @@ -159,8 +159,8 @@ source [file join $tool_dir lib actions build.tcl]
source [file join $tool_dir lib actions depot.tcl]

if {$perform(build-dir)} {
if {[has_src_but_no_artifacts $project_dir]} {
exit_with_error "$project_dir has a 'src' directory but lacks an" \
if {[has_src_but_no_artifacts $config::project_dir]} {
exit_with_error "$config::project_dir has a 'src' directory but lacks an" \
"'artifacts' file. You may start with an empty file."
}
}
Expand Down Expand Up @@ -217,9 +217,9 @@ if {$perform(run-dir)} {

source [file join $tool_dir lib run common.tcl]

set target_file [file join $tool_dir lib run $target.tcl]
if {$target == "common" || ![file exists $target_file]} {
exit_with_error "Target '$target' not available (see 'goa help targets')" }
set target_file [file join $tool_dir lib run $config::target.tcl]
if {$config::target == "common" || ![file exists $target_file]} {
exit_with_error "Target '$config::target' not available (see 'goa help targets')" }

source $target_file

Expand All @@ -230,7 +230,7 @@ if {$perform(run-dir)} {
if {$perform(run)} {

# start recording
set filename [file join $var_dir $project_name.log]
set filename [file join $config::var_dir $config::project_name.log]
log_file -noappend $filename

run_genode
Expand All @@ -256,15 +256,15 @@ if {$perform(run)} {
"\n argument."
}

if {![file exists [file join $run_dir $binary_name]]} {
exit_with_error "binary '$binary_name' does not exist in run directory" \
if {![file exists [file join $config::run_dir $config::binary_name]]} {
exit_with_error "binary '$config::binary_name' does not exist in run directory" \
"\n You can define the binary name explicitly by " \
"\n specifying the '--binary-name <name>' command-line " \
"\n argument."
}

cd $run_dir
exec [file join $tool_dir lib backtrace] $binary_name >@ stdout < $filename
cd $config::run_dir
exec [file join $tool_dir lib backtrace] $config::binary_name >@ stdout < $filename
}

exit
Expand All @@ -281,7 +281,7 @@ if {$perform(export)} {
goa export-src
goa export-pkgs exported_archives
goa export-bin exported_archives
if {$debug} { goa export-dbg }
if {$config::debug} { goa export-dbg }
goa export-index exported_archives

array set export_projects { }
Expand All @@ -292,7 +292,7 @@ if {$perform(export)} {

if {$perform(publish)} {

set pubkey_file [file join $depot_dir $depot_user pubkey]
set pubkey_file [file join $config::depot_dir $config::depot_user pubkey]
if {![file exists $pubkey_file]} {
exit_with_error "missing public key at $pubkey_file\n" \
"\n You may use the 'goa add-depot-user' command." \
Expand Down
30 changes: 20 additions & 10 deletions share/goa/lib/actions/build.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,9 @@ namespace eval goa {
#
proc prepare_abi_stubs { used_apis } {

global tool_dir depot_dir abi_dir cross_dev_prefix ld_march cc_march verbose project_name arch
global tool_dir verbose
global config::depot_dir config::abi_dir config::cross_dev_prefix
global config::ld_march config::cc_march config::project_name config::arch

set cmd "make -f $tool_dir/lib/gen_abi_stubs.mk"
lappend cmd "TOOL_DIR=$tool_dir"
Expand All @@ -110,7 +112,9 @@ namespace eval goa {
#
proc prepare_ldso_support_stub { used_apis } {

global tool_dir depot_dir abi_dir cross_dev_prefix cc_march verbose project_name arch
global tool_dir verbose
global config::depot_dir config::abi_dir config::cross_dev_prefix
global config::cc_march config::project_name config::arch

set so_api { }
foreach api_path $used_apis {
Expand Down Expand Up @@ -145,8 +149,11 @@ namespace eval goa {
#
proc build-dir { } {

global cross_dev_prefix tool_dir depot_dir rebuild arch olevel cc_march
global debug cc_cxx_opt_std ld_march abi_dir build_dir api_dirs
global tool_dir
global config::cross_dev_prefix config::depot_dir config::rebuild
global config::arch config::olevel config::cc_march config::debug
global config::cc_cxx_opt_std config::ld_march config::abi_dir
global config::build_dir config::api_dirs

#
# Check for availability of the Genode tool chain
Expand Down Expand Up @@ -339,8 +346,9 @@ namespace eval goa {

proc extract_artifacts_from_build_dir { } {

global project_dir build_dir bin_dir dbg_dir debug
global library_artifacts
global config::project_dir config::build_dir config::bin_dir
global config::dbg_dir config::debug
variable library_artifacts { }

set artifacts_file_path [file join $project_dir artifacts]

Expand All @@ -356,7 +364,6 @@ namespace eval goa {
file mkdir $bin_dir
if { $debug } { file mkdir $dbg_dir }

set library_artifacts { }
foreach file [artifact_file_list_from_list_file $artifacts_file_path $build_dir] {
set symlink_path [file join $bin_dir [file tail $file]]
file link $symlink_path $file
Expand All @@ -377,7 +384,9 @@ namespace eval goa {

proc check_abis { } {

global arch project_dir tool_dir library_artifacts
global tool_dir
global config::arch config::project_dir
variable library_artifacts

foreach library $library_artifacts {

Expand All @@ -399,7 +408,7 @@ namespace eval goa {

proc extract_api_artifacts { } {

global project_dir build_dir api_dir
global config::project_dir config::build_dir config::api_dir

set api_file_path [file join $project_dir api]

Expand Down Expand Up @@ -429,7 +438,8 @@ namespace eval goa {

proc extract_library_symbols { } {

global build_dir project_dir tool_dir
global tool_dir
global config::build_dir config::project_dir

set artifacts_file_path [file join $project_dir artifacts]

Expand Down
56 changes: 31 additions & 25 deletions share/goa/lib/actions/depot.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ namespace eval goa {
# Run `goa export` in specified project directory
#
proc export_dependent_project { dir arch { pkg_name "" } } {
global argv0 jobs depot_user depot_dir versions_from_genode_dir
global public_dir common_var_dir var_dir verbose search_dir debug
global argv0 config::jobs config::depot_user config::depot_dir
global config::versions_from_genode_dir config::public_dir config::debug
global config::common_var_dir config::var_dir config::verbose
global config::search_dir

set orig_pwd [pwd]
cd $search_dir
Expand Down Expand Up @@ -59,7 +61,7 @@ namespace eval goa {


proc download_archives { archives { no_err 0 } { dbg 0 }} {
global tool_dir depot_dir public_dir
global tool_dir config::depot_dir config::public_dir

if {[llength $archives] > 0} {
set cmd "[file join $tool_dir depot download]"
Expand Down Expand Up @@ -99,7 +101,7 @@ namespace eval goa {
#
proc prepare_depot_with_apis { } {

global depot_user arch
global config::depot_user config::arch

assert_definition_of_depot_user

Expand Down Expand Up @@ -128,7 +130,7 @@ namespace eval goa {
# Download archives into depot
#
proc prepare_depot_with_archives { archive_list } {
global depot_dir
global config::depot_dir

# create list of depot users without duplicates
set depot_users { }
Expand Down Expand Up @@ -161,7 +163,7 @@ namespace eval goa {
# Try downloading debug archives into depot
#
proc prepare_depot_with_debug_archives { archive_list } {
global depot_dir
global config::depot_dir

set missing_debug_archives {}
foreach archive $archive_list {
Expand All @@ -183,7 +185,8 @@ namespace eval goa {
#
proc versioned_project_archive { type { pkg_name ""} } {

global depot_user project_dir project_name version arch sculpt_version
global config::depot_user config::project_dir config::project_name
global config::version config::arch config::sculpt_version

set name $project_name

Expand Down Expand Up @@ -242,7 +245,7 @@ namespace eval goa {
# \return path to the archive directory (or file if type=="index")
#
proc prepare_project_archive_directory { type { pkg_name "" } } {
global depot_dir
global config::depot_dir

set policy [depot_policy]
set archive [versioned_project_archive $type $pkg_name]
Expand Down Expand Up @@ -274,7 +277,7 @@ namespace eval goa {
# Return path to the license file as defined for the project
#
proc license_file { } {
global project_dir license
global config::project_dir config::license

set local_license_file [file join $project_dir LICENSE]
if {[file exists $local_license_file]} {
Expand All @@ -298,7 +301,7 @@ namespace eval goa {
# Supplement index file pkg paths with user and version information
#
proc augment_index_versions { src_file dst_file } {
global depot_user
global config::depot_user

# read src_file
set fd [open $src_file r]
Expand All @@ -321,7 +324,7 @@ namespace eval goa {

proc export-api { } {

global api_dir project_dir
global config::api_dir config::project_dir

if {[file exists $api_dir] && [file isdirectory $api_dir]} {
set dst_dir [prepare_project_archive_directory api]
Expand Down Expand Up @@ -369,7 +372,7 @@ namespace eval goa {

proc export-raw { } {

global project_dir
global config::project_dir

set raw_dir [file join $project_dir raw]
if {[file exists $raw_dir] && [file isdirectory $raw_dir]} {
Expand All @@ -387,7 +390,7 @@ namespace eval goa {

proc export-src { } {

global project_dir
global config::project_dir

# create src archive
set src_dir [file join $project_dir src]
Expand Down Expand Up @@ -430,12 +433,12 @@ namespace eval goa {

proc export-pkgs { &exported_archives } {

global publish_pkg arch
global args config::arch
upvar ${&exported_archives} exported_archives

set pkg_expr "*"
if {$publish_pkg != ""} {
set pkg_expr $publish_pkg }
if {$args(publish_pkg) != ""} {
set pkg_expr $args(publish_pkg) }
set pkgs [glob -nocomplain -directory pkg -tail $pkg_expr -type d]
foreach pkg $pkgs {

Expand Down Expand Up @@ -486,7 +489,7 @@ namespace eval goa {

proc export-bin { &exported_archives } {

global bin_dir
global config::bin_dir
upvar ${&exported_archives} exported_archives

# create bin archive
Expand Down Expand Up @@ -529,7 +532,7 @@ namespace eval goa {

proc export-index { &exported_archives } {

global project_dir depot_user
global config::project_dir config::depot_user
upvar ${&exported_archives} exported_archives

set index_file [file join $project_dir index]
Expand Down Expand Up @@ -580,7 +583,8 @@ namespace eval goa {

proc import-dependencies { exported_archives &export_projects} {

global tool_dir depot_dir public_dir depot_user arch
global tool_dir
global config::depot_dir config::public_dir config::depot_user config::arch
upvar ${&export_projects} export_projects

# determine dependent projects that need exporting
Expand Down Expand Up @@ -636,7 +640,7 @@ namespace eval goa {

proc export-dependencies { &export_projects } {

global arch
global config::arch
upvar ${&export_projects} export_projects

# export bin/pkg archives first and delay arch-independent archives
Expand Down Expand Up @@ -676,7 +680,8 @@ namespace eval goa {

proc published-archives { } {

global project_dir publish_pkg bin_dir api_dir arch
global args
global config::project_dir config::bin_dir config::api_dir config::arch
set archives { }

set raw_dir [file join $project_dir raw]
Expand All @@ -693,8 +698,8 @@ namespace eval goa {
if {[file exists $api_dir] && [file isdirectory $api_dir]} {
lappend archives [versioned_project_archive api] }

if {$publish_pkg != ""} {
lappend archives [apply_arch [versioned_project_archive pkg $publish_pkg] $arch]
if {$args(publish_pkg) != ""} {
lappend archives [apply_arch [versioned_project_archive pkg $args(publish_pkg)] $arch]
} else {
set pkgs [glob -nocomplain -directory pkg -tail * -type d]
foreach pkg $pkgs {
Expand All @@ -720,7 +725,7 @@ namespace eval goa {

proc download-foreign { archives } {

global tool_dir depot_dir public_dir depot_user
global tool_dir config::depot_dir config::public_dir config::depot_user

set missing_archives ""
if {[llength $archives] > 0} {
Expand Down Expand Up @@ -763,7 +768,8 @@ namespace eval goa {

proc publish { archives } {

global tool_dir depot_dir public_dir debug jobs
global tool_dir
global config::depot_dir config::public_dir config::debug config::jobs

if {[llength $archives] > 0} {
set cmd "[file join $tool_dir depot publish]"
Expand Down
Loading

0 comments on commit c8c780e

Please sign in to comment.