|
@@ -83,8 +83,33 @@ PXENV_EXIT_t pxenv_get_cached_info ( struct s_PXENV_GET_CACHED_INFO
|
83
|
83
|
DBG ( " to %04x:%04x+%x", get_cached_info->Buffer.segment,
|
84
|
84
|
get_cached_info->Buffer.offset, get_cached_info->BufferSize );
|
85
|
85
|
|
86
|
|
- /* This is really, really awkward to support with our multiple
|
87
|
|
- * sources of options.
|
|
86
|
+ /* The case in which the caller doesn't supply a buffer is
|
|
87
|
+ * really awkward to support given that we have multiple
|
|
88
|
+ * sources of options, and that we don't actually store the
|
|
89
|
+ * DHCP packets. (We may not even have performed DHCP; we may
|
|
90
|
+ * have obtained all configuration from non-volatile stored
|
|
91
|
+ * options or from the command line.) We provide the caller
|
|
92
|
+ * with our base-memory temporary packet buffer and construct
|
|
93
|
+ * the packet in there.
|
|
94
|
+ *
|
|
95
|
+ * To add to the fun, Intel decided at some point in the
|
|
96
|
+ * evolution of the PXE specification to add the BufferLimit
|
|
97
|
+ * field, which we are meant to fill in with the length of our
|
|
98
|
+ * packet buffer, so that the caller can safely modify the
|
|
99
|
+ * boot server reply packet stored therein. However, this
|
|
100
|
+ * field was not present in earlier versions of the PXE spec,
|
|
101
|
+ * and there is at least one PXE NBP (Altiris) which allocates
|
|
102
|
+ * only exactly enough space for this earlier, shorter version
|
|
103
|
+ * of the structure. If we actually fill in the BufferLimit
|
|
104
|
+ * field, we therefore risk trashing random areas of the
|
|
105
|
+ * caller's memory. If we *don't* fill it in, then the caller
|
|
106
|
+ * is at liberty to assume that whatever random value happened
|
|
107
|
+ * to be in that location represents the length of the buffer
|
|
108
|
+ * we've just passed back to it.
|
|
109
|
+ *
|
|
110
|
+ * Since older PXE stacks won't fill this field in anyway,
|
|
111
|
+ * it's probably safe to assume that no callers actually rely
|
|
112
|
+ * on it, so we choose to not fill it in.
|
88
|
113
|
*/
|
89
|
114
|
len = get_cached_info->BufferSize;
|
90
|
115
|
if ( len == 0 ) {
|
|
@@ -92,7 +117,9 @@ PXENV_EXIT_t pxenv_get_cached_info ( struct s_PXENV_GET_CACHED_INFO
|
92
|
117
|
get_cached_info->Buffer.segment = rm_ds;
|
93
|
118
|
get_cached_info->Buffer.offset =
|
94
|
119
|
( unsigned int ) ( & __from_data16 ( basemem_packet ) );
|
95
|
|
- get_cached_info->BufferLimit = len;
|
|
120
|
+ DBG ( " using %04x:%04x+'%x'", get_cached_info->Buffer.segment,
|
|
121
|
+ get_cached_info->Buffer.offset,
|
|
122
|
+ get_cached_info->BufferLimit );
|
96
|
123
|
}
|
97
|
124
|
|
98
|
125
|
/* Allocate space for temporary copy */
|
|
@@ -118,6 +145,7 @@ PXENV_EXIT_t pxenv_get_cached_info ( struct s_PXENV_GET_CACHED_INFO
|
118
|
145
|
|
119
|
146
|
/* Overwrite filename to work around Microsoft RIS bug */
|
120
|
147
|
if ( pxe_ris_filename ) {
|
|
148
|
+ DBG ( " applying RIS hack" );
|
121
|
149
|
strncpy ( dhcppkt.dhcphdr->file, pxe_ris_filename,
|
122
|
150
|
sizeof ( dhcppkt.dhcphdr->file ) );
|
123
|
151
|
}
|
|
@@ -126,6 +154,7 @@ PXENV_EXIT_t pxenv_get_cached_info ( struct s_PXENV_GET_CACHED_INFO
|
126
|
154
|
buffer = real_to_user ( get_cached_info->Buffer.segment,
|
127
|
155
|
get_cached_info->Buffer.offset );
|
128
|
156
|
len = dhcppkt.len;
|
|
157
|
+ DBG ( " length %x", len );
|
129
|
158
|
copy_to_user ( buffer, 0, data, len );
|
130
|
159
|
get_cached_info->BufferSize = len;
|
131
|
160
|
|