diff options
author | Martin Willi <martin@revosec.ch> | 2013-01-11 14:45:32 +0100 |
---|---|---|
committer | Martin Willi <martin@revosec.ch> | 2013-01-11 14:57:08 +0100 |
commit | 54a1a75b2f5f3a9419eb5c18c07173827d5c9b39 (patch) | |
tree | 6f701e5a4c626baf1991b3340bc18976e34b09b7 | |
parent | 2f0441a3a64ccf0e7e9b94d7132884faa2672c91 (diff) | |
download | strongswan-54a1a75b2f5f3a9419eb5c18c07173827d5c9b39.tar.bz2 strongswan-54a1a75b2f5f3a9419eb5c18c07173827d5c9b39.tar.xz |
Don't use bio_writer_t.skip() to write length field when appending more data
If the writer reallocates its buffer, the length pointer might not be valid
anymore, or even worse, point to an arbitrary allocation.
-rw-r--r-- | src/libcharon/encoding/payloads/eap_payload.c | 8 | ||||
-rw-r--r-- | src/libstrongswan/bio/bio_writer.h | 7 |
2 files changed, 9 insertions, 6 deletions
diff --git a/src/libcharon/encoding/payloads/eap_payload.c b/src/libcharon/encoding/payloads/eap_payload.c index dd2e25795..f2f35aa69 100644 --- a/src/libcharon/encoding/payloads/eap_payload.c +++ b/src/libcharon/encoding/payloads/eap_payload.c @@ -410,14 +410,15 @@ eap_payload_t *eap_payload_create_nak(u_int8_t identifier, eap_type_t type, eap_type_t reg_type; u_int32_t reg_vendor; bio_writer_t *writer; - chunk_t length, data; + chunk_t data; bool added_any = FALSE, found_vendor = FALSE; eap_payload_t *payload; writer = bio_writer_create(12); writer->write_uint8(writer, EAP_RESPONSE); writer->write_uint8(writer, identifier); - length = writer->skip(writer, 2); + /* write zero length, we update it once we know the length */ + writer->write_uint16(writer, 0); write_type(writer, EAP_NAK, 0, expanded); @@ -453,10 +454,9 @@ eap_payload_t *eap_payload_create_nak(u_int8_t identifier, eap_type_t type, /* set length */ data = writer->get_buf(writer); - htoun16(length.ptr, data.len); + htoun16(data.ptr + offsetof(eap_packet_t, length), data.len); payload = eap_payload_create_data(data); writer->destroy(writer); return payload; } - diff --git a/src/libstrongswan/bio/bio_writer.h b/src/libstrongswan/bio/bio_writer.h index 57a5c3d38..2ac4f3556 100644 --- a/src/libstrongswan/bio/bio_writer.h +++ b/src/libstrongswan/bio/bio_writer.h @@ -126,8 +126,11 @@ struct bio_writer_t { void (*wrap32)(bio_writer_t *this); /** - * Skips len bytes in the buffer before the next data is written, returns - * a chunk covering the skipped bytes. + * Skips len bytes in the buffer, return chunk of skipped data. + * + * The returned chunk is not valid after calling any other writer function + * (except get_buf()), because a buffer reallocation might move the + * internal buffer to a different memory location! * * @param len number of bytes to skip * @return chunk pointing to skipped bytes in the internal buffer |