diff options
-rw-r--r-- | src/core/xferbuf.c | 39 | ||||
-rw-r--r-- | src/include/ipxe/xferbuf.h | 5 |
2 files changed, 44 insertions, 0 deletions
diff --git a/src/core/xferbuf.c b/src/core/xferbuf.c index 7f9780b..afc72ae 100644 --- a/src/core/xferbuf.c +++ b/src/core/xferbuf.c @@ -283,3 +283,42 @@ struct xfer_buffer_operations xferbuf_umalloc_operations = { .write = xferbuf_umalloc_write, .read = xferbuf_umalloc_read, }; + +/** + * Get underlying data transfer buffer + * + * @v interface Data transfer interface + * @ret xferbuf Data transfer buffer, or NULL on error + * + * This call will check that the xfer_buffer() handler belongs to the + * destination interface which also provides xfer_deliver() for this + * interface. + * + * This is done to prevent accidental accesses to a data transfer + * buffer which may be located behind a non-transparent datapath via a + * series of pass-through interfaces. + */ +struct xfer_buffer * xfer_buffer ( struct interface *intf ) { + struct interface *dest; + xfer_buffer_TYPE ( void * ) *op = + intf_get_dest_op ( intf, xfer_buffer, &dest ); + void *object = intf_object ( dest ); + struct interface *xfer_deliver_dest; + struct xfer_buffer *xferbuf; + + /* Check that this operation is provided by the same interface + * which handles xfer_deliver(). + */ + intf_get_dest_op ( intf, xfer_deliver, &xfer_deliver_dest ); + + if ( op && ( dest == xfer_deliver_dest ) ) { + xferbuf = op ( object ); + } else { + /* Default is to not have a data transfer buffer */ + xferbuf = NULL; + } + + intf_put ( xfer_deliver_dest ); + intf_put ( dest ); + return xferbuf; +} diff --git a/src/include/ipxe/xferbuf.h b/src/include/ipxe/xferbuf.h index f2f3362..cb0b1a0 100644 --- a/src/include/ipxe/xferbuf.h +++ b/src/include/ipxe/xferbuf.h @@ -12,6 +12,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include <stdint.h> #include <ipxe/iobuf.h> #include <ipxe/uaccess.h> +#include <ipxe/interface.h> #include <ipxe/xfer.h> /** A data transfer buffer */ @@ -97,4 +98,8 @@ extern int xferbuf_deliver ( struct xfer_buffer *xferbuf, struct io_buffer *iobuf, struct xfer_metadata *meta ); +extern struct xfer_buffer * xfer_buffer ( struct interface *intf ); +#define xfer_buffer_TYPE( object_type ) \ + typeof ( struct xfer_buffer * ( object_type ) ) + #endif /* _IPXE_XFERBUF_H */ |