aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/xen-blkback/blkback.c
diff options
context:
space:
mode:
authorDavid Vrabel <david.vrabel@citrix.com>2013-03-07 12:32:01 -0500
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2013-03-11 13:54:28 -0400
commit0e367ae46503cfe7791460c8ba8434a5d60b2bd5 (patch)
treef3056dc8de11ab4431cb227f4417af810c7f31e9 /drivers/block/xen-blkback/blkback.c
parenta72d9002f80bffd7e4c7d60e5a9caa0cddffe894 (diff)
xen/blkback: correctly respond to unknown, non-native requests
If the frontend is using a non-native protocol (e.g., a 64-bit frontend with a 32-bit backend) and it sent an unrecognized request, the request was not translated and the response would have the incorrect ID. This may cause the frontend driver to behave incorrectly or crash. Since the ID field in the request is always in the same place, regardless of the request type we can get the correct ID and make a valid response (which will report BLKIF_RSP_EOPNOTSUPP). This bug affected 64-bit SLES 11 guests when using a 32-bit backend. This guest does a BLKIF_OP_RESERVED_1 (BLKIF_OP_PACKET in the SLES source) and would crash in blkif_int() as the ID in the response would be invalid. Signed-off-by: David Vrabel <david.vrabel@citrix.com> Cc: stable@vger.kernel.org Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Diffstat (limited to 'drivers/block/xen-blkback/blkback.c')
-rw-r--r--drivers/block/xen-blkback/blkback.c31
1 files changed, 27 insertions, 4 deletions
diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c
index 6d1cc3df2ac6..1a0faf6370ca 100644
--- a/drivers/block/xen-blkback/blkback.c
+++ b/drivers/block/xen-blkback/blkback.c
@@ -679,6 +679,16 @@ static int dispatch_discard_io(struct xen_blkif *blkif,
679 return err; 679 return err;
680} 680}
681 681
682static int dispatch_other_io(struct xen_blkif *blkif,
683 struct blkif_request *req,
684 struct pending_req *pending_req)
685{
686 free_req(pending_req);
687 make_response(blkif, req->u.other.id, req->operation,
688 BLKIF_RSP_EOPNOTSUPP);
689 return -EIO;
690}
691
682static void xen_blk_drain_io(struct xen_blkif *blkif) 692static void xen_blk_drain_io(struct xen_blkif *blkif)
683{ 693{
684 atomic_set(&blkif->drain, 1); 694 atomic_set(&blkif->drain, 1);
@@ -800,17 +810,30 @@ __do_block_io_op(struct xen_blkif *blkif)
800 810
801 /* Apply all sanity checks to /private copy/ of request. */ 811 /* Apply all sanity checks to /private copy/ of request. */
802 barrier(); 812 barrier();
803 if (unlikely(req.operation == BLKIF_OP_DISCARD)) { 813
814 switch (req.operation) {
815 case BLKIF_OP_READ:
816 case BLKIF_OP_WRITE:
817 case BLKIF_OP_WRITE_BARRIER:
818 case BLKIF_OP_FLUSH_DISKCACHE:
819 if (dispatch_rw_block_io(blkif, &req, pending_req))
820 goto done;
821 break;
822 case BLKIF_OP_DISCARD:
804 free_req(pending_req); 823 free_req(pending_req);
805 if (dispatch_discard_io(blkif, &req)) 824 if (dispatch_discard_io(blkif, &req))
806 break; 825 goto done;
807 } else if (dispatch_rw_block_io(blkif, &req, pending_req)) 826 break;
827 default:
828 if (dispatch_other_io(blkif, &req, pending_req))
829 goto done;
808 break; 830 break;
831 }
809 832
810 /* Yield point for this unbounded loop. */ 833 /* Yield point for this unbounded loop. */
811 cond_resched(); 834 cond_resched();
812 } 835 }
813 836done:
814 return more_to_do; 837 return more_to_do;
815} 838}
816 839