Quellcode durchsuchen

[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.
tags/v0.9.4
Michael Brown vor 16 Jahren
Ursprung
Commit
b62f2325ba
4 geänderte Dateien mit 67 neuen und 1 gelöschten Zeilen
  1. 5
    0
      src/arch/i386/interface/pxe/pxe_call.c
  2. 1
    0
      src/include/pxe.h
  3. 22
    0
      src/include/pxe_api.h
  4. 39
    1
      src/interface/pxe/pxe_file.c

+ 5
- 0
src/arch/i386/interface/pxe/pxe_call.c Datei anzeigen

@@ -96,6 +96,7 @@ union pxenv_call {
96 96
 	PXENV_EXIT_t ( * file_select ) ( struct s_PXENV_FILE_SELECT * );
97 97
 	PXENV_EXIT_t ( * file_read ) ( struct s_PXENV_FILE_READ * );
98 98
 	PXENV_EXIT_t ( * get_file_size ) ( struct s_PXENV_GET_FILE_SIZE * );
99
+	PXENV_EXIT_t ( * file_exec ) ( struct s_PXENV_FILE_EXEC * );
99 100
 };
100 101
 
101 102
 /**
@@ -294,6 +295,10 @@ __cdecl void pxe_api_call ( struct i386_all_regs *ix86 ) {
294 295
 		pxenv_call.get_file_size = pxenv_get_file_size;
295 296
 		param_len = sizeof ( pxenv_any.get_file_size );
296 297
 		break;
298
+	case PXENV_FILE_EXEC:
299
+		pxenv_call.file_exec = pxenv_file_exec;
300
+		param_len = sizeof ( pxenv_any.file_exec );
301
+		break;
297 302
 	default:
298 303
 		DBG ( "PXENV_UNKNOWN_%hx", opcode );
299 304
 		pxenv_call.unknown = pxenv_unknown;

+ 1
- 0
src/include/pxe.h Datei anzeigen

@@ -63,6 +63,7 @@ union u_PXENV_ANY {
63 63
 	struct s_PXENV_FILE_SELECT		file_select;
64 64
 	struct s_PXENV_FILE_READ		file_read;
65 65
 	struct s_PXENV_GET_FILE_SIZE		get_file_size;
66
+	struct s_PXENV_FILE_EXEC		file_exec;
66 67
 };
67 68
 
68 69
 typedef union u_PXENV_ANY PXENV_ANY_t;

+ 22
- 0
src/include/pxe_api.h Datei anzeigen

@@ -1684,6 +1684,28 @@ extern PXENV_EXIT_t pxenv_get_file_size ( struct s_PXENV_GET_FILE_SIZE
1684 1684
 
1685 1685
 /** @} */ /* pxenv_get_file_size */
1686 1686
 
1687
+/** @defgroup pxenv_file_exec PXENV_FILE_EXEC
1688
+ *
1689
+ * FILE EXEC
1690
+ *
1691
+ * @{
1692
+ */
1693
+
1694
+/** PXE API function code for pxenv_file_exec() */
1695
+#define PXENV_FILE_EXEC			0x00e5
1696
+
1697
+/** Parameter block for pxenv_file_exec() */
1698
+struct s_PXENV_FILE_EXEC {
1699
+	PXENV_STATUS_t Status;		/**< PXE status code */
1700
+	SEGOFF16_t Command;		/**< Command to execute */
1701
+} PACKED;
1702
+
1703
+typedef struct s_PXENV_FILE_EXEC PXENV_FILE_EXEC_t;
1704
+
1705
+extern PXENV_EXIT_t pxenv_file_exec ( struct s_PXENV_FILE_EXEC *file_exec );
1706
+
1707
+/** @} */ /* pxenv_file_exec */
1708
+
1687 1709
 /** @} */ /* pxe_file_api */
1688 1710
 
1689 1711
 /** @defgroup pxe_loader_api PXE Loader API

+ 39
- 1
src/interface/pxe/pxe_file.c Datei anzeigen

@@ -31,7 +31,7 @@
31 31
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
32 32
  */
33 33
 
34
-FEATURE ( FEATURE_MISC, "PXEXT", DHCP_EB_FEATURE_PXE_EXT, 1 );
34
+FEATURE ( FEATURE_MISC, "PXEXT", DHCP_EB_FEATURE_PXE_EXT, 2 );
35 35
 
36 36
 /**
37 37
  * FILE OPEN
@@ -189,3 +189,41 @@ PXENV_EXIT_t pxenv_get_file_size ( struct s_PXENV_GET_FILE_SIZE
189 189
 	get_file_size->Status = PXENV_STATUS_SUCCESS;
190 190
 	return PXENV_EXIT_SUCCESS;
191 191
 }
192
+
193
+/**
194
+ * FILE EXEC
195
+ *
196
+ * @v file_exec				Pointer to a struct s_PXENV_FILE_EXEC
197
+ * @v s_PXENV_FILE_EXEC::Command	Command to execute
198
+ * @ret #PXENV_EXIT_SUCCESS		Command was executed successfully
199
+ * @ret #PXENV_EXIT_FAILURE		Command was not executed successfully
200
+ * @ret s_PXENV_FILE_EXEC::Status	PXE status code
201
+ *
202
+ */
203
+PXENV_EXIT_t pxenv_file_exec ( struct s_PXENV_FILE_EXEC *file_exec ) {
204
+	userptr_t command;
205
+	size_t command_len;
206
+	int rc;
207
+
208
+	DBG ( "PXENV_FILE_EXEC" );
209
+
210
+	/* Copy name from external program, and exec it */
211
+	command = real_to_user ( file_exec->Command.segment,
212
+				 file_exec->Command.offset );
213
+	command_len = strlen_user ( command, 0 );
214
+	{
215
+		char command_string[ command_len + 1 ];
216
+
217
+		copy_from_user ( command_string, command, 0,
218
+				 sizeof ( command_string ) );
219
+		DBG ( " %s", command_string );
220
+
221
+		if ( ( rc = system ( command_string ) ) != 0 ) {
222
+			file_exec->Status = PXENV_STATUS ( rc );
223
+			return PXENV_EXIT_FAILURE;
224
+		}
225
+	}
226
+
227
+	file_exec->Status = PXENV_STATUS_SUCCESS;
228
+	return PXENV_EXIT_SUCCESS;
229
+}

Laden…
Abbrechen
Speichern