aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-scsi.c
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2009-09-03 03:08:11 -0400
committerJeff Garzik <jgarzik@redhat.com>2009-09-08 21:17:43 -0400
commitbd30add88cea831dfb854d564478f09ee66206b5 (patch)
treed0c0354920cd4b51812c51a68539c95e0bd71e90 /drivers/ata/libata-scsi.c
parent72fee3823d2938fa98f2f3113301f46803f4c711 (diff)
libata: unbreak TPM filtering by reorganizing ata_scsi_pass_thru()
ata_scsi_pass_thru() was checking for input sanity and disallowed commands while initializaing qc from scmd. TPM filtering was added right after protocol check at which point tf wasn't initialized properly. This means that TPM filtering has never really worked. This patch fixes the bug by reorganizing ata_scsi_pass_thru() such that qc is fully initialized before checking for invalid conditions which is way less error prone. Discovered while Thilo-Alexander Ginkel was trying debug patches for bko#13416. Signed-off-by: Tejun Heo <tj@kernel.org> Cc: Thilo-Alexander Ginkel <thilo@ginkel.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/ata/libata-scsi.c')
-rw-r--r--drivers/ata/libata-scsi.c104
1 files changed, 51 insertions, 53 deletions
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 5d7a1bd37e9a..b4ee28dec521 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -2760,28 +2760,6 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
2760 goto invalid_fld; 2760 goto invalid_fld;
2761 2761
2762 /* 2762 /*
2763 * Filter TPM commands by default. These provide an
2764 * essentially uncontrolled encrypted "back door" between
2765 * applications and the disk. Set libata.allow_tpm=1 if you
2766 * have a real reason for wanting to use them. This ensures
2767 * that installed software cannot easily mess stuff up without
2768 * user intent. DVR type users will probably ship with this enabled
2769 * for movie content management.
2770 *
2771 * Note that for ATA8 we can issue a DCS change and DCS freeze lock
2772 * for this and should do in future but that it is not sufficient as
2773 * DCS is an optional feature set. Thus we also do the software filter
2774 * so that we comply with the TC consortium stated goal that the user
2775 * can turn off TC features of their system.
2776 */
2777 if (tf->command >= 0x5C && tf->command <= 0x5F && !libata_allow_tpm)
2778 goto invalid_fld;
2779
2780 /* We may not issue DMA commands if no DMA mode is set */
2781 if (tf->protocol == ATA_PROT_DMA && dev->dma_mode == 0)
2782 goto invalid_fld;
2783
2784 /*
2785 * 12 and 16 byte CDBs use different offsets to 2763 * 12 and 16 byte CDBs use different offsets to
2786 * provide the various register values. 2764 * provide the various register values.
2787 */ 2765 */
@@ -2830,6 +2808,41 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
2830 tf->device = dev->devno ? 2808 tf->device = dev->devno ?
2831 tf->device | ATA_DEV1 : tf->device & ~ATA_DEV1; 2809 tf->device | ATA_DEV1 : tf->device & ~ATA_DEV1;
2832 2810
2811 /* READ/WRITE LONG use a non-standard sect_size */
2812 qc->sect_size = ATA_SECT_SIZE;
2813 switch (tf->command) {
2814 case ATA_CMD_READ_LONG:
2815 case ATA_CMD_READ_LONG_ONCE:
2816 case ATA_CMD_WRITE_LONG:
2817 case ATA_CMD_WRITE_LONG_ONCE:
2818 if (tf->protocol != ATA_PROT_PIO || tf->nsect != 1)
2819 goto invalid_fld;
2820 qc->sect_size = scsi_bufflen(scmd);
2821 }
2822
2823 /*
2824 * Set flags so that all registers will be written, pass on
2825 * write indication (used for PIO/DMA setup), result TF is
2826 * copied back and we don't whine too much about its failure.
2827 */
2828 tf->flags = ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
2829 if (scmd->sc_data_direction == DMA_TO_DEVICE)
2830 tf->flags |= ATA_TFLAG_WRITE;
2831
2832 qc->flags |= ATA_QCFLAG_RESULT_TF | ATA_QCFLAG_QUIET;
2833
2834 /*
2835 * Set transfer length.
2836 *
2837 * TODO: find out if we need to do more here to
2838 * cover scatter/gather case.
2839 */
2840 ata_qc_set_pc_nbytes(qc);
2841
2842 /* We may not issue DMA commands if no DMA mode is set */
2843 if (tf->protocol == ATA_PROT_DMA && dev->dma_mode == 0)
2844 goto invalid_fld;
2845
2833 /* sanity check for pio multi commands */ 2846 /* sanity check for pio multi commands */
2834 if ((cdb[1] & 0xe0) && !is_multi_taskfile(tf)) 2847 if ((cdb[1] & 0xe0) && !is_multi_taskfile(tf))
2835 goto invalid_fld; 2848 goto invalid_fld;
@@ -2846,18 +2859,6 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
2846 multi_count); 2859 multi_count);
2847 } 2860 }
2848 2861
2849 /* READ/WRITE LONG use a non-standard sect_size */
2850 qc->sect_size = ATA_SECT_SIZE;
2851 switch (tf->command) {
2852 case ATA_CMD_READ_LONG:
2853 case ATA_CMD_READ_LONG_ONCE:
2854 case ATA_CMD_WRITE_LONG:
2855 case ATA_CMD_WRITE_LONG_ONCE:
2856 if (tf->protocol != ATA_PROT_PIO || tf->nsect != 1)
2857 goto invalid_fld;
2858 qc->sect_size = scsi_bufflen(scmd);
2859 }
2860
2861 /* 2862 /*
2862 * Filter SET_FEATURES - XFER MODE command -- otherwise, 2863 * Filter SET_FEATURES - XFER MODE command -- otherwise,
2863 * SET_FEATURES - XFER MODE must be preceded/succeeded 2864 * SET_FEATURES - XFER MODE must be preceded/succeeded
@@ -2865,30 +2866,27 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
2865 * controller (i.e. the reason for ->set_piomode(), 2866 * controller (i.e. the reason for ->set_piomode(),
2866 * ->set_dmamode(), and ->post_set_mode() hooks). 2867 * ->set_dmamode(), and ->post_set_mode() hooks).
2867 */ 2868 */
2868 if ((tf->command == ATA_CMD_SET_FEATURES) 2869 if (tf->command == ATA_CMD_SET_FEATURES &&
2869 && (tf->feature == SETFEATURES_XFER)) 2870 tf->feature == SETFEATURES_XFER)
2870 goto invalid_fld; 2871 goto invalid_fld;
2871 2872
2872 /* 2873 /*
2873 * Set flags so that all registers will be written, 2874 * Filter TPM commands by default. These provide an
2874 * and pass on write indication (used for PIO/DMA 2875 * essentially uncontrolled encrypted "back door" between
2875 * setup.) 2876 * applications and the disk. Set libata.allow_tpm=1 if you
2876 */ 2877 * have a real reason for wanting to use them. This ensures
2877 tf->flags |= (ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE); 2878 * that installed software cannot easily mess stuff up without
2878 2879 * user intent. DVR type users will probably ship with this enabled
2879 if (scmd->sc_data_direction == DMA_TO_DEVICE) 2880 * for movie content management.
2880 tf->flags |= ATA_TFLAG_WRITE;
2881
2882 /*
2883 * Set transfer length.
2884 * 2881 *
2885 * TODO: find out if we need to do more here to 2882 * Note that for ATA8 we can issue a DCS change and DCS freeze lock
2886 * cover scatter/gather case. 2883 * for this and should do in future but that it is not sufficient as
2884 * DCS is an optional feature set. Thus we also do the software filter
2885 * so that we comply with the TC consortium stated goal that the user
2886 * can turn off TC features of their system.
2887 */ 2887 */
2888 ata_qc_set_pc_nbytes(qc); 2888 if (tf->command >= 0x5C && tf->command <= 0x5F && !libata_allow_tpm)
2889 2889 goto invalid_fld;
2890 /* request result TF and be quiet about device error */
2891 qc->flags |= ATA_QCFLAG_RESULT_TF | ATA_QCFLAG_QUIET;
2892 2890
2893 return 0; 2891 return 0;
2894 2892