History

tpm: Fix null pointer dereference on chip register error path

If clk_enable is not defined and chip initialization is canceled code hits null dereference. Easily reproducible with vTPM init fail: swtpm chardev --tpmstate dir=nonexistent_dir --tpm2 --vtpm-proxy BUG: kernel NULL pointer dereference, address: 00000000 ... Call Trace: tpm_chip_start+0x9d/0xa0 [tpm] tpm_chip_register+0x10/0x1a0 [tpm] vtpm_proxy_work+0x11/0x30 [tpm_vtpm_proxy] process_one_work+0x214/0x5a0 worker_thread+0x134/0x3e0 ? process_one_work+0x5a0/0x5a0 kthread+0xd4/0x100 ? process_one_work+0x5a0/0x5a0 ? kthread_park+0x90/0x90 ret_from_fork+0x19/0x24

Milan Broz committed 7 years ago

Commit 1e5ac631 parent 4b6f2311 file · +16 −7Browse files

Unified · Split

drivers/char/tpm/tpm-chip.c+16−7
@@ -77,6 +77,18 @@ static int tpm_go_idle(struct tpm_chip *chip) · 76 unmodified lines
77 return chip->ops->go_idle(chip);77 return chip->ops->go_idle(chip);
78}78}
79 79
80static void tpm_clk_enable(struct tpm_chip *chip)
81{
82 if (chip->ops->clk_enable)
83 chip->ops->clk_enable(chip, true);
84}
85
86static void tpm_clk_disable(struct tpm_chip *chip)
87{
88 if (chip->ops->clk_enable)
89 chip->ops->clk_enable(chip, false);
90}
91
80/**92/**
81 * tpm_chip_start() - power on the TPM93 * tpm_chip_start() - power on the TPM
82 * @chip: a TPM chip to use94 * @chip: a TPM chip to use
@@ -89,13 +101,12 @@ int tpm_chip_start(struct tpm_chip *chip) · 6 unmodified lines
89{101{
90 int ret;102 int ret;
91 103
92 if (chip->ops->clk_enable)104 tpm_clk_enable(chip);
93 chip->ops->clk_enable(chip, true);
94 105
95 if (chip->locality == -1) {106 if (chip->locality == -1) {
96 ret = tpm_request_locality(chip);107 ret = tpm_request_locality(chip);
97 if (ret) {108 if (ret) {
98 chip->ops->clk_enable(chip, false);109 tpm_clk_disable(chip);
99 return ret;110 return ret;
100 }111 }
101 }112 }
@@ -103,8 +114,7 @@ int tpm_chip_start(struct tpm_chip *chip) · 1 unmodified line
103 ret = tpm_cmd_ready(chip);114 ret = tpm_cmd_ready(chip);
104 if (ret) {115 if (ret) {
105 tpm_relinquish_locality(chip);116 tpm_relinquish_locality(chip);
106 if (chip->ops->clk_enable)117 tpm_clk_disable(chip);
107 chip->ops->clk_enable(chip, false);
108 return ret;118 return ret;
109 }119 }
110 120
@@ -124,8 +134,7 @@ void tpm_chip_stop(struct tpm_chip *chip) · 13 unmodified lines
124{134{
125 tpm_go_idle(chip);135 tpm_go_idle(chip);
126 tpm_relinquish_locality(chip);136 tpm_relinquish_locality(chip);
127 if (chip->ops->clk_enable)137 tpm_clk_disable(chip);
128 chip->ops->clk_enable(chip, false);
129}138}
130EXPORT_SYMBOL_GPL(tpm_chip_stop);139EXPORT_SYMBOL_GPL(tpm_chip_stop);
131 140