diff options
author | Michael Brown <mcb30@etherboot.org> | 2008-03-04 18:16:30 +0000 |
---|---|---|
committer | Michael Brown <mcb30@etherboot.org> | 2008-03-04 18:16:30 +0000 |
commit | b62f2325ba2bc4cfacf9d4ce1db6fd37cd966f9c (patch) | |
tree | 66cde99a8b09d12b2fd9cbb487b7c2d87b6809db /src/interface | |
parent | b08a6f530042cfc0f8be2209cde9fab3d0ab9143 (diff) | |
download | ipxe-b62f2325ba2bc4cfacf9d4ce1db6fd37cd966f9c.tar.gz |
[PXEXT] Add PXENV_FILE_EXEC call to PXE extensions API.
This allows pxelinux to execute arbitrary gPXE commands. This is
remarkably unsafe (not least because some of the commands will assume
full ownership of memory and do nasty things like edit the e820 map
underneath the calling pxelinux), but it does allow access to the
"sanboot" command.
Diffstat (limited to 'src/interface')
-rw-r--r-- | src/interface/pxe/pxe_file.c | 40 |
1 files changed, 39 insertions, 1 deletions
diff --git a/src/interface/pxe/pxe_file.c b/src/interface/pxe/pxe_file.c index 01dac8f7d..718f5e38e 100644 --- a/src/interface/pxe/pxe_file.c +++ b/src/interface/pxe/pxe_file.c @@ -31,7 +31,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -FEATURE ( FEATURE_MISC, "PXEXT", DHCP_EB_FEATURE_PXE_EXT, 1 ); +FEATURE ( FEATURE_MISC, "PXEXT", DHCP_EB_FEATURE_PXE_EXT, 2 ); /** * FILE OPEN @@ -189,3 +189,41 @@ PXENV_EXIT_t pxenv_get_file_size ( struct s_PXENV_GET_FILE_SIZE get_file_size->Status = PXENV_STATUS_SUCCESS; return PXENV_EXIT_SUCCESS; } + +/** + * FILE EXEC + * + * @v file_exec Pointer to a struct s_PXENV_FILE_EXEC + * @v s_PXENV_FILE_EXEC::Command Command to execute + * @ret #PXENV_EXIT_SUCCESS Command was executed successfully + * @ret #PXENV_EXIT_FAILURE Command was not executed successfully + * @ret s_PXENV_FILE_EXEC::Status PXE status code + * + */ +PXENV_EXIT_t pxenv_file_exec ( struct s_PXENV_FILE_EXEC *file_exec ) { + userptr_t command; + size_t command_len; + int rc; + + DBG ( "PXENV_FILE_EXEC" ); + + /* Copy name from external program, and exec it */ + command = real_to_user ( file_exec->Command.segment, + file_exec->Command.offset ); + command_len = strlen_user ( command, 0 ); + { + char command_string[ command_len + 1 ]; + + copy_from_user ( command_string, command, 0, + sizeof ( command_string ) ); + DBG ( " %s", command_string ); + + if ( ( rc = system ( command_string ) ) != 0 ) { + file_exec->Status = PXENV_STATUS ( rc ); + return PXENV_EXIT_FAILURE; + } + } + + file_exec->Status = PXENV_STATUS_SUCCESS; + return PXENV_EXIT_SUCCESS; +} |