dpif-linux: Fix revalidator core caused by flow dumps.
authorEthan Jackson <ethan@nicira.com>
Sat, 24 May 2014 01:07:25 +0000 (18:07 -0700)
committerEthan Jackson <ethan@nicira.com>
Sat, 24 May 2014 01:41:26 +0000 (18:41 -0700)
commit3f0e42704087fb3f72f90ac1e095a55659aeb62b
tree6bf473d19e4cbed6dc5d1ecc86f42218fd85b916
parent11937351e0497c31c4fded153474d5ebcf3ff33e
dpif-linux: Fix revalidator core caused by flow dumps.

The dpif flow dump API guarantees that keys it returns are not deleted
unless dpif_flow_dump_next_may_destroy_keys() warns that they might
be.  When dpif_linux_flow_dump_next() needed extra memory for a
datapath flow's actions, it would use a special temporary buffer.
Unfortunately, it also used memory from this temporary buffer for the
keys it returned.  Thus, on the next loop this memory would be freed,
breaking our invariant.

The correct solution to this problem is probably to fix this rather
awkward API.  However, this patch's solution is small and simple, so
it's fine for now.

The following is a valgrind stack trace which lead to finding this
bug.

Invalid read of size 2
  at 0x4C2D050: memcpy@@GLIBC_2.14 (in ...)
  by 0x4D40B8: dpif_linux_flow_to_ofpbuf (dpif-linux.c:2373)
  by 0x4D4DE4: dpif_linux_operate__ (dpif-linux.c:1394)
  by 0x4D5055: dpif_linux_operate (dpif-linux.c:1480)
  by 0x450D14: dpif_operate (dpif.c:1225)
  by 0x42D706: push_dump_ops__.isra.6 (ofproto-dpif-upcall.c:1362)
  by 0x42E5A8: revalidate.isra.11 (ofproto-dpif-upcall.c:1531)
  by 0x42EB0E: udpif_revalidator (ofproto-dpif-upcall.c:592)
  by 0x495070: ovsthread_wrapper (ovs-thread.c:302)
  by 0x5472E99: start_thread (pthread_create.c:308)
  by 0x5C7C4BC: clone (clone.S:112)
Address 0x227e12d0 is 160 bytes inside a block of size 4,976 free'd
  at 0x4C2A82E: free (in ...)
  by 0x494227: ofpbuf_uninit (ofpbuf.c:136)
  by 0x4D5D34: dpif_linux_flow_dump_next (ofpbuf.h:182)
  by 0x4509BA: dpif_flow_dump_next (dpif.c:1036)
  by 0x42E137: revalidate.isra.11 (ofproto-dpif-upcall.c:1451)
  by 0x42EB0E: udpif_revalidator (ofproto-dpif-upcall.c:592)
  by 0x495070: ovsthread_wrapper (ovs-thread.c:302)
  by 0x5472E99: start_thread (pthread_create.c:308)
  by 0x5C7C4BC: clone (clone.S:112)

Signed-off-by: Ethan Jackson <ethan@nicira.com>
Acked-by: Ben Pfaff <blp@nicira.com>
lib/dpif-linux.c