aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Cox <alan@lxorguk.ukuu.org.uk>2007-11-04 22:05:49 -0500
committerJeff Garzik <jeff@garzik.org>2008-01-23 05:24:09 -0500
commitae8d4ee7ff429136c8b482c3b38ed994c021d3fc (patch)
treebf45047ab8a4f5325c6b752be02313d3112eded0
parentffe188dd83e84119516688c822388c8f30a54877 (diff)
libata: Disable ATA8-ACS proposed Trusted Computing features by default
Historically word 48 in the identify data was used to mean 32bit I/O was supported for VLB IDE etc. ATA8 reassigns this word to the Trusted Computing Group, where it is used for TCG features. This means that an ATA8 TCG drive is going to trigger 32bit I/O on some systems which will be funny. Anyway we need to sort this out ready for ATA8 so: - Reorder the ata.h header a bit so the ata_version function occurs early in it - Make dword_io check the ATA version - Add an ATA8 version checking TCG presence test While we are at it the current drafts have a flaw where it may not be possible to disable TCG features at boot (and opt out of the trusted model) as TCG intends because it relies on presence of a different optional feature (DCS). Handle this in software by refusing the TCG commands if libata.allow_tpm is not set. (We must make it possible as some environments such as proprietary VDR devices will doubtless want to use it to lock up content) Finally as with CPRM print a warning so that the user knows they may not be able to full access and use the device. Signed-off-by: Alan Cox <alan@redhat.com>
-rw-r--r--drivers/ata/libata-core.c12
-rw-r--r--drivers/ata/libata-scsi.c18
-rw-r--r--drivers/ata/libata.h1
-rw-r--r--include/linux/ata.h22
4 files changed, 51 insertions, 2 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 6380726f7538..9b7f3c477730 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -119,6 +119,10 @@ int libata_noacpi = 0;
119module_param_named(noacpi, libata_noacpi, int, 0444); 119module_param_named(noacpi, libata_noacpi, int, 0444);
120MODULE_PARM_DESC(noacpi, "Disables the use of ACPI in probe/suspend/resume when set"); 120MODULE_PARM_DESC(noacpi, "Disables the use of ACPI in probe/suspend/resume when set");
121 121
122int libata_allow_tpm = 0;
123module_param_named(allow_tpm, libata_allow_tpm, int, 0444);
124MODULE_PARM_DESC(allow_tpm, "Permit the use of TPM commands");
125
122MODULE_AUTHOR("Jeff Garzik"); 126MODULE_AUTHOR("Jeff Garzik");
123MODULE_DESCRIPTION("Library module for ATA devices"); 127MODULE_DESCRIPTION("Library module for ATA devices");
124MODULE_LICENSE("GPL"); 128MODULE_LICENSE("GPL");
@@ -2161,8 +2165,14 @@ int ata_dev_configure(struct ata_device *dev)
2161 "supports DRM functions and may " 2165 "supports DRM functions and may "
2162 "not be fully accessable.\n"); 2166 "not be fully accessable.\n");
2163 snprintf(revbuf, 7, "CFA"); 2167 snprintf(revbuf, 7, "CFA");
2164 } else 2168 } else {
2165 snprintf(revbuf, 7, "ATA-%d", ata_id_major_version(id)); 2169 snprintf(revbuf, 7, "ATA-%d", ata_id_major_version(id));
2170 /* Warn the user if the device has TPM extensions */
2171 if (ata_id_has_tpm(id))
2172 ata_dev_printk(dev, KERN_WARNING,
2173 "supports DRM functions and may "
2174 "not be fully accessable.\n");
2175 }
2166 2176
2167 dev->n_sectors = ata_id_n_sectors(id); 2177 dev->n_sectors = ata_id_n_sectors(id);
2168 2178
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 14daf4848f09..f802dbce41ae 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -2690,6 +2690,24 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
2690 if ((tf->protocol = ata_scsi_map_proto(cdb[1])) == ATA_PROT_UNKNOWN) 2690 if ((tf->protocol = ata_scsi_map_proto(cdb[1])) == ATA_PROT_UNKNOWN)
2691 goto invalid_fld; 2691 goto invalid_fld;
2692 2692
2693 /*
2694 * Filter TPM commands by default. These provide an
2695 * essentially uncontrolled encrypted "back door" between
2696 * applications and the disk. Set libata.allow_tpm=1 if you
2697 * have a real reason for wanting to use them. This ensures
2698 * that installed software cannot easily mess stuff up without
2699 * user intent. DVR type users will probably ship with this enabled
2700 * for movie content management.
2701 *
2702 * Note that for ATA8 we can issue a DCS change and DCS freeze lock
2703 * for this and should do in future but that it is not sufficient as
2704 * DCS is an optional feature set. Thus we also do the software filter
2705 * so that we comply with the TC consortium stated goal that the user
2706 * can turn off TC features of their system.
2707 */
2708 if (tf->command >= 0x5C && tf->command <= 0x5F && !libata_allow_tpm)
2709 goto invalid_fld;
2710
2693 /* We may not issue DMA commands if no DMA mode is set */ 2711 /* We may not issue DMA commands if no DMA mode is set */
2694 if (tf->protocol == ATA_PROT_DMA && dev->dma_mode == 0) 2712 if (tf->protocol == ATA_PROT_DMA && dev->dma_mode == 0)
2695 goto invalid_fld; 2713 goto invalid_fld;
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index bbe59c2fd1e2..048e26cfb339 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -60,6 +60,7 @@ extern int atapi_dmadir;
60extern int atapi_passthru16; 60extern int atapi_passthru16;
61extern int libata_fua; 61extern int libata_fua;
62extern int libata_noacpi; 62extern int libata_noacpi;
63extern int libata_allow_tpm;
63extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev); 64extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev);
64extern int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev, 65extern int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev,
65 u64 block, u32 n_block, unsigned int tf_flags, 66 u64 block, u32 n_block, unsigned int tf_flags,
diff --git a/include/linux/ata.h b/include/linux/ata.h
index e672e80202a8..3fbe6d7784ab 100644
--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -379,7 +379,6 @@ struct ata_taskfile {
379#define ata_id_has_ncq(id) ((id)[76] & (1 << 8)) 379#define ata_id_has_ncq(id) ((id)[76] & (1 << 8))
380#define ata_id_queue_depth(id) (((id)[75] & 0x1f) + 1) 380#define ata_id_queue_depth(id) (((id)[75] & 0x1f) + 1)
381#define ata_id_removeable(id) ((id)[0] & (1 << 7)) 381#define ata_id_removeable(id) ((id)[0] & (1 << 7))
382#define ata_id_has_dword_io(id) ((id)[48] & (1 << 0))
383#define ata_id_has_atapi_AN(id) \ 382#define ata_id_has_atapi_AN(id) \
384 ( (((id)[76] != 0x0000) && ((id)[76] != 0xffff)) && \ 383 ( (((id)[76] != 0x0000) && ((id)[76] != 0xffff)) && \
385 ((id)[78] & (1 << 5)) ) 384 ((id)[78] & (1 << 5)) )
@@ -415,6 +414,7 @@ static inline bool ata_id_has_dipm(const u16 *id)
415 return val & (1 << 3); 414 return val & (1 << 3);
416} 415}
417 416
417
418static inline int ata_id_has_fua(const u16 *id) 418static inline int ata_id_has_fua(const u16 *id)
419{ 419{
420 if ((id[84] & 0xC000) != 0x4000) 420 if ((id[84] & 0xC000) != 0x4000)
@@ -519,6 +519,26 @@ static inline int ata_id_is_sata(const u16 *id)
519 return ata_id_major_version(id) >= 5 && id[93] == 0; 519 return ata_id_major_version(id) >= 5 && id[93] == 0;
520} 520}
521 521
522static inline int ata_id_has_tpm(const u16 *id)
523{
524 /* The TPM bits are only valid on ATA8 */
525 if (ata_id_major_version(id) < 8)
526 return 0;
527 if ((id[48] & 0xC000) != 0x4000)
528 return 0;
529 return id[48] & (1 << 0);
530}
531
532static inline int ata_id_has_dword_io(const u16 *id)
533{
534 /* ATA 8 reuses this flag for "trusted" computing */
535 if (ata_id_major_version(id) > 7)
536 return 0;
537 if (id[48] & (1 << 0))
538 return 1;
539 return 0;
540}
541
522static inline int ata_id_current_chs_valid(const u16 *id) 542static inline int ata_id_current_chs_valid(const u16 *id)
523{ 543{
524 /* For ATA-1 devices, if the INITIALIZE DEVICE PARAMETERS command 544 /* For ATA-1 devices, if the INITIALIZE DEVICE PARAMETERS command