Browse Source

[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 16 years ago
parent
commit
b62f2325ba

+ 5
- 0
src/arch/i386/interface/pxe/pxe_call.c View File

96
 	PXENV_EXIT_t ( * file_select ) ( struct s_PXENV_FILE_SELECT * );
96
 	PXENV_EXIT_t ( * file_select ) ( struct s_PXENV_FILE_SELECT * );
97
 	PXENV_EXIT_t ( * file_read ) ( struct s_PXENV_FILE_READ * );
97
 	PXENV_EXIT_t ( * file_read ) ( struct s_PXENV_FILE_READ * );
98
 	PXENV_EXIT_t ( * get_file_size ) ( struct s_PXENV_GET_FILE_SIZE * );
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
 		pxenv_call.get_file_size = pxenv_get_file_size;
295
 		pxenv_call.get_file_size = pxenv_get_file_size;
295
 		param_len = sizeof ( pxenv_any.get_file_size );
296
 		param_len = sizeof ( pxenv_any.get_file_size );
296
 		break;
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
 	default:
302
 	default:
298
 		DBG ( "PXENV_UNKNOWN_%hx", opcode );
303
 		DBG ( "PXENV_UNKNOWN_%hx", opcode );
299
 		pxenv_call.unknown = pxenv_unknown;
304
 		pxenv_call.unknown = pxenv_unknown;

+ 1
- 0
src/include/pxe.h View File

63
 	struct s_PXENV_FILE_SELECT		file_select;
63
 	struct s_PXENV_FILE_SELECT		file_select;
64
 	struct s_PXENV_FILE_READ		file_read;
64
 	struct s_PXENV_FILE_READ		file_read;
65
 	struct s_PXENV_GET_FILE_SIZE		get_file_size;
65
 	struct s_PXENV_GET_FILE_SIZE		get_file_size;
66
+	struct s_PXENV_FILE_EXEC		file_exec;
66
 };
67
 };
67
 
68
 
68
 typedef union u_PXENV_ANY PXENV_ANY_t;
69
 typedef union u_PXENV_ANY PXENV_ANY_t;

+ 22
- 0
src/include/pxe_api.h View File

1684
 
1684
 
1685
 /** @} */ /* pxenv_get_file_size */
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
 /** @} */ /* pxe_file_api */
1709
 /** @} */ /* pxe_file_api */
1688
 
1710
 
1689
 /** @defgroup pxe_loader_api PXE Loader API
1711
 /** @defgroup pxe_loader_api PXE Loader API

+ 39
- 1
src/interface/pxe/pxe_file.c View File

31
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
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
  * FILE OPEN
37
  * FILE OPEN
189
 	get_file_size->Status = PXENV_STATUS_SUCCESS;
189
 	get_file_size->Status = PXENV_STATUS_SUCCESS;
190
 	return PXENV_EXIT_SUCCESS;
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
+}

Loading…
Cancel
Save