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
7777 return chip->ops->go_idle(chip);
7878 }
7979
80+static void tpm_clk_enable(struct tpm_chip *chip)
81+{
82+ if (chip->ops->clk_enable)
83+ chip->ops->clk_enable(chip, true);
84+}
85+
86+static void tpm_clk_disable(struct tpm_chip *chip)
87+{
88+ if (chip->ops->clk_enable)
89+ chip->ops->clk_enable(chip, false);
90+}
91+
8092 /**
8193 * tpm_chip_start() - power on the TPM
8294 * @chip: a TPM chip to use
@@ -89,13 +101,12 @@ int tpm_chip_start(struct tpm_chip *chip) · 6 unmodified lines
89101 {
90102 int ret;
91103
92− if (chip->ops->clk_enable)
93− chip->ops->clk_enable(chip, true);
104+ tpm_clk_enable(chip);
94105
95106 if (chip->locality == -1) {
96107 ret = tpm_request_locality(chip);
97108 if (ret) {
98− chip->ops->clk_enable(chip, false);
109+ tpm_clk_disable(chip);
99110 return ret;
100111 }
101112 }
@@ -103,8 +114,7 @@ int tpm_chip_start(struct tpm_chip *chip) · 1 unmodified line
103114 ret = tpm_cmd_ready(chip);
104115 if (ret) {
105116 tpm_relinquish_locality(chip);
106− if (chip->ops->clk_enable)
107− chip->ops->clk_enable(chip, false);
117+ tpm_clk_disable(chip);
108118 return ret;
109119 }
110120
@@ -124,8 +134,7 @@ void tpm_chip_stop(struct tpm_chip *chip) · 13 unmodified lines
124134 {
125135 tpm_go_idle(chip);
126136 tpm_relinquish_locality(chip);
127− if (chip->ops->clk_enable)
128− chip->ops->clk_enable(chip, false);
137+ tpm_clk_disable(chip);
129138 }
130139 EXPORT_SYMBOL_GPL(tpm_chip_stop);
131140