]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-5.1/habanalabs-fix-debugfs-code.patch
4.4-stable patches
[thirdparty/kernel/stable-queue.git] / queue-5.1 / habanalabs-fix-debugfs-code.patch
1 From 8438846cce61e284a22316c13aa4b63772963070 Mon Sep 17 00:00:00 2001
2 From: Jann Horn <jannh@google.com>
3 Date: Sat, 4 May 2019 15:56:08 +0200
4 Subject: habanalabs: fix debugfs code
5
6 From: Jann Horn <jannh@google.com>
7
8 commit 8438846cce61e284a22316c13aa4b63772963070 upstream.
9
10 This fixes multiple things in the habanalabs debugfs code, in particular:
11
12 - mmu_write() was unnecessarily verbose, copying around between multiple
13 buffers
14 - mmu_write() could write a user-specified, unbounded amount of userspace
15 memory into a kernel buffer (out-of-bounds write)
16 - multiple debugfs read handlers ignored the user-supplied count,
17 potentially corrupting out-of-bounds userspace data
18 - hl_device_read() was unnecessarily verbose
19 - hl_device_write() could read uninitialized stack memory
20 - multiple debugfs read handlers copied terminating null characters to
21 userspace
22
23 Signed-off-by: Jann Horn <jannh@google.com>
24 Reviewed-by: Oded Gabbay <oded.gabbay@gmail.com>
25 Signed-off-by: Oded Gabbay <oded.gabbay@gmail.com>
26 Cc: stable@vger.kernel.org
27 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
28
29 ---
30 drivers/misc/habanalabs/debugfs.c | 60 +++++++++++---------------------------
31 1 file changed, 18 insertions(+), 42 deletions(-)
32
33 --- a/drivers/misc/habanalabs/debugfs.c
34 +++ b/drivers/misc/habanalabs/debugfs.c
35 @@ -459,41 +459,31 @@ static ssize_t mmu_write(struct file *fi
36 struct hl_debugfs_entry *entry = s->private;
37 struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
38 struct hl_device *hdev = dev_entry->hdev;
39 - char kbuf[MMU_KBUF_SIZE], asid_kbuf[MMU_ASID_BUF_SIZE],
40 - addr_kbuf[MMU_ADDR_BUF_SIZE];
41 + char kbuf[MMU_KBUF_SIZE];
42 char *c;
43 ssize_t rc;
44
45 if (!hdev->mmu_enable)
46 return count;
47
48 - memset(kbuf, 0, sizeof(kbuf));
49 - memset(asid_kbuf, 0, sizeof(asid_kbuf));
50 - memset(addr_kbuf, 0, sizeof(addr_kbuf));
51 -
52 + if (count > sizeof(kbuf) - 1)
53 + goto err;
54 if (copy_from_user(kbuf, buf, count))
55 goto err;
56 -
57 - kbuf[MMU_KBUF_SIZE - 1] = 0;
58 + kbuf[count] = 0;
59
60 c = strchr(kbuf, ' ');
61 if (!c)
62 goto err;
63 + *c = '\0';
64
65 - memcpy(asid_kbuf, kbuf, c - kbuf);
66 -
67 - rc = kstrtouint(asid_kbuf, 10, &dev_entry->mmu_asid);
68 + rc = kstrtouint(kbuf, 10, &dev_entry->mmu_asid);
69 if (rc)
70 goto err;
71
72 - c = strstr(kbuf, " 0x");
73 - if (!c)
74 + if (strncmp(c+1, "0x", 2))
75 goto err;
76 -
77 - c += 3;
78 - memcpy(addr_kbuf, c, (kbuf + count) - c);
79 -
80 - rc = kstrtoull(addr_kbuf, 16, &dev_entry->mmu_addr);
81 + rc = kstrtoull(c+3, 16, &dev_entry->mmu_addr);
82 if (rc)
83 goto err;
84
85 @@ -525,10 +515,8 @@ static ssize_t hl_data_read32(struct fil
86 }
87
88 sprintf(tmp_buf, "0x%08x\n", val);
89 - rc = simple_read_from_buffer(buf, strlen(tmp_buf) + 1, ppos, tmp_buf,
90 - strlen(tmp_buf) + 1);
91 -
92 - return rc;
93 + return simple_read_from_buffer(buf, count, ppos, tmp_buf,
94 + strlen(tmp_buf));
95 }
96
97 static ssize_t hl_data_write32(struct file *f, const char __user *buf,
98 @@ -559,7 +547,6 @@ static ssize_t hl_get_power_state(struct
99 struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
100 struct hl_device *hdev = entry->hdev;
101 char tmp_buf[200];
102 - ssize_t rc;
103 int i;
104
105 if (*ppos)
106 @@ -574,10 +561,8 @@ static ssize_t hl_get_power_state(struct
107
108 sprintf(tmp_buf,
109 "current power state: %d\n1 - D0\n2 - D3hot\n3 - Unknown\n", i);
110 - rc = simple_read_from_buffer(buf, strlen(tmp_buf) + 1, ppos, tmp_buf,
111 - strlen(tmp_buf) + 1);
112 -
113 - return rc;
114 + return simple_read_from_buffer(buf, count, ppos, tmp_buf,
115 + strlen(tmp_buf));
116 }
117
118 static ssize_t hl_set_power_state(struct file *f, const char __user *buf,
119 @@ -630,8 +615,8 @@ static ssize_t hl_i2c_data_read(struct f
120 }
121
122 sprintf(tmp_buf, "0x%02x\n", val);
123 - rc = simple_read_from_buffer(buf, strlen(tmp_buf) + 1, ppos, tmp_buf,
124 - strlen(tmp_buf) + 1);
125 + rc = simple_read_from_buffer(buf, count, ppos, tmp_buf,
126 + strlen(tmp_buf));
127
128 return rc;
129 }
130 @@ -720,18 +705,9 @@ static ssize_t hl_led2_write(struct file
131 static ssize_t hl_device_read(struct file *f, char __user *buf,
132 size_t count, loff_t *ppos)
133 {
134 - char tmp_buf[200];
135 - ssize_t rc;
136 -
137 - if (*ppos)
138 - return 0;
139 -
140 - sprintf(tmp_buf,
141 - "Valid values: disable, enable, suspend, resume, cpu_timeout\n");
142 - rc = simple_read_from_buffer(buf, strlen(tmp_buf) + 1, ppos, tmp_buf,
143 - strlen(tmp_buf) + 1);
144 -
145 - return rc;
146 + static const char *help =
147 + "Valid values: disable, enable, suspend, resume, cpu_timeout\n";
148 + return simple_read_from_buffer(buf, count, ppos, help, strlen(help));
149 }
150
151 static ssize_t hl_device_write(struct file *f, const char __user *buf,
152 @@ -739,7 +715,7 @@ static ssize_t hl_device_write(struct fi
153 {
154 struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
155 struct hl_device *hdev = entry->hdev;
156 - char data[30];
157 + char data[30] = {0};
158
159 /* don't allow partial writes */
160 if (*ppos != 0)