[Openswan dev] ARM unaligned bug
Paul Wouters
paul at xelerance.com
Wed Jan 20 22:03:10 EST 2010
On Wed, 20 Jan 2010, Albert Veli wrote:
Albert,
Could you confirm the following patch works on your ARM?
Thanks for your time! And thanks to Hugh for the patch!
Paul
-------------- next part --------------
commit fa384bccde5259d440f552da42a7183cd92b6eeb
Author: Paul Wouters <paul at xelerance.com>
Date: Wed Jan 20 21:58:27 2010 -0500
out_modify_previous_np() made assumptions that network order and
byte order would be the same. Patch by dhr.
diff --git a/include/packet.h b/include/packet.h
index 87bc118..5f2f8b4 100644
--- a/include/packet.h
+++ b/include/packet.h
@@ -166,6 +166,12 @@ extern void DBG_print_struct(const char *label, const void *struct_ptr,
* require them to be zero).
*/
+#define NSIZEOF_isakmp_hdr 20 /* on-the-wire sizeof struct isakmpg_hdr */
+#define NOFFSETOF_isa_np 8 /* on-the-wire offset of isa_np (one octet) */
+#define NOFFSETOF_isag_length 2 /* on-the-wire offset of isag_length (two octets, network order */
+#define NOFFSETOF_isag_np 0 /* on-the-wire offset of isag_np (one octet) */
+#define NSIZEOF_isakmp_generic 4 /* on-the-wire sizeof isakmp_generic) */
+
struct isakmp_hdr
{
u_int8_t isa_icookie[COOKIE_SIZE];
diff --git a/lib/libpluto/packet.c b/lib/libpluto/packet.c
index f95c190..3405259 100644
--- a/lib/libpluto/packet.c
+++ b/lib/libpluto/packet.c
@@ -1658,34 +1658,44 @@ out_struct(const void *struct_ptr, struct_desc *sd
return FALSE;
}
+/* Find last complete top-level payload and change its np
+ * * Note: we must deal with payloads already formatted for the network.
+ * _*_Note:_we_don't_think_a_FALSE_return_should_happen_but_old_routine_did.
+ * */
bool
out_modify_previous_np(u_int8_t np, pb_stream *outs)
{
- size_t len = (outs->cur - outs->start), offset;
- if (len < sizeof(struct isakmp_hdr)) {
- return FALSE;
- }
- else if (len == sizeof(struct isakmp_hdr)) {
- struct isakmp_hdr *hdr = (struct isakmp_hdr *)outs->start;
- hdr->isa_np = np;
- return TRUE;
- }
- else {
- struct isakmp_generic *hdr;
- for (offset = sizeof(struct isakmp_hdr); offset < len ;
- offset += ntohs(hdr->isag_length)) {
- if ((len - offset) < sizeof(struct isakmp_generic))
- return FALSE;
- hdr = (struct isakmp_generic *)(outs->start+offset);
- if ((len - offset) < ntohs(hdr->isag_length))
- return FALSE;
- if ((len - offset) == ntohs(hdr->isag_length)) {
- hdr->isag_np = np;
- return TRUE;
- }
+ u_int8_t *pl = outs->start;
+ size_t left = outs->cur - outs->start;
+
+ passert(left >= NSIZEOF_isakmp_hdr); /* not even room for isakmp_hdr! */
+ if (left == NSIZEOF_isakmp_hdr) {
+ /* no payloads, just the isakmp_hdr: insert np here */
+ passert(pl[NOFFSETOF_isa_np] == ISAKMP_NEXT_NONE);
+ pl[NOFFSETOF_isa_np] = np;
+ } else {
+ pl += NSIZEOF_isakmp_hdr; /* skip over isakmp_hdr */
+ left -= NSIZEOF_isakmp_hdr;
+ for (;;) {
+ size_t pllen;
+
+ passert(left >= NSIZEOF_isakmp_generic);
+ pllen = (pl[NOFFSETOF_isag_length] << 8)
+ | pl[NOFFSETOF_isag_length + 1];
+ passert(left >= pllen);
+ if (left == pllen) {
+ /* found last top-level payload */
+ passert(pl[NOFFSETOF_isag_np] == ISAKMP_NEXT_NONE);
+ pl[NOFFSETOF_isag_np] = np;
+ break; /* done */
+ } else {
+ /* this payload is not the last: scan forward */
+ pl += pllen;
+ left -= pllen;
}
}
- return FALSE;
+ }
+ return TRUE;
}
bool
More information about the Dev
mailing list