mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 17:42:43 +00:00 
			
		
		
		
	 db11cfa2c5
			
		
	
	
		db11cfa2c5
		
	
	
	
	
		
			
			This adds a "temporary promises for the dynamic-linker" flag ('-d')
to the "pledge" utility.
Example usage:
pledge -d -p "stdio rpath" id
Without the '-d' flag, id would crash because the dynamic linker
requires 'prot_exec'.
When this flag is used and the program to be run is dynamically linked,
"pledge" adds promises that are required by the dynamic linker
to the promise set provided by the user.
The dynamic linker will later "give up" the pledge promises it no
longer requires.
		
	
			
		
			
				
	
	
		
			47 lines
		
	
	
	
		
			1.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			47 lines
		
	
	
	
		
			1.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
|  * Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
 | |
|  *
 | |
|  * SPDX-License-Identifier: BSD-2-Clause
 | |
|  */
 | |
| 
 | |
| #include <LibCore/ArgsParser.h>
 | |
| #include <LibCore/MappedFile.h>
 | |
| #include <LibCore/System.h>
 | |
| #include <LibELF/Image.h>
 | |
| #include <LibMain/Main.h>
 | |
| 
 | |
| static ErrorOr<bool> is_dynamically_linked_executable(StringView filename)
 | |
| {
 | |
|     String exec_filename = filename;
 | |
|     if (!filename.contains('/')) {
 | |
|         exec_filename = TRY(Core::System::find_file_in_path(filename));
 | |
|     }
 | |
| 
 | |
|     auto file = TRY(Core::MappedFile::map(exec_filename));
 | |
|     ELF::Image elf_image(file->bytes());
 | |
|     return elf_image.is_dynamic();
 | |
| }
 | |
| 
 | |
| ErrorOr<int> serenity_main(Main::Arguments arguments)
 | |
| {
 | |
|     String promises;
 | |
|     Vector<StringView> command;
 | |
|     bool add_promises_for_dynamic_linker;
 | |
| 
 | |
|     Core::ArgsParser args_parser;
 | |
|     args_parser.add_option(promises, "Space-separated list of pledge promises", "promises", 'p', "promises");
 | |
|     args_parser.add_option(add_promises_for_dynamic_linker, "Add temporary promises for dynamic linker", "dynamic-linker-promises", 'd');
 | |
|     args_parser.add_positional_argument(command, "Command to execute", "command");
 | |
|     args_parser.parse(arguments);
 | |
| 
 | |
|     if (add_promises_for_dynamic_linker && TRY(is_dynamically_linked_executable(command[0]))) {
 | |
|         auto constexpr loader_promises = "stdio rpath prot_exec"sv;
 | |
|         MUST(Core::System::setenv("_LOADER_PLEDGE_PROMISES"sv, loader_promises, true));
 | |
|         MUST(Core::System::setenv("_LOADER_MAIN_PROGRAM_PLEDGE_PROMISES"sv, promises, true));
 | |
|         promises = String::formatted("{} {}", promises, loader_promises);
 | |
|     }
 | |
| 
 | |
|     TRY(Core::System::pledge(StringView(), promises));
 | |
|     TRY(Core::System::exec(command[0], command.span(), Core::System::SearchInPath::Yes));
 | |
|     return 0;
 | |
| }
 |