<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
</head>
<body>
<p style="font-family:Arial;font-size:10pt;color:#0078D7;margin:15pt;" align="Left">
[AMD Official Use Only - Internal Distribution Only]<br>
</p>
<br>
<div>
<div dir="auto" style="direction: ltr; margin: 0; padding: 0; font-family: sans-serif; font-size: 11pt; color: black; ">
no. below function checks if block is valid or not.<br>
</div>
<div dir="auto" style="direction: ltr; margin: 0; padding: 0; font-family: sans-serif; font-size: 11pt; color: black; ">
I think you need check your code_checker. or you were checking on a very old codebase?<br>
<br>
</div>
<div dir="auto" style="direction: ltr; margin: 0; padding: 0; font-family: sans-serif; font-size: 11pt; color: black; ">
/* check if ras is supported on block, say, sdma, gfx */<br>
</div>
<div dir="auto" style="direction: ltr; margin: 0; padding: 0; font-family: sans-serif; font-size: 11pt; color: black; ">
static inline int amdgpu_ras_is_supported(struct amdgpu_device *adev,<br>
</div>
<div dir="auto" style="direction: ltr; margin: 0; padding: 0; font-family: sans-serif; font-size: 11pt; color: black; ">
unsigned int block)<br>
</div>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>From:</b> Dan Carpenter <dan.carpenter@oracle.com><br>
<b>Sent:</b> Wednesday, May 6, 2020 5:17:34 PM<br>
<b>To:</b> Zhou1, Tao <Tao.Zhou1@amd.com><br>
<b>Cc:</b> Pan, Xinhui <Xinhui.Pan@amd.com>; amd-gfx@lists.freedesktop.org <amd-gfx@lists.freedesktop.org><br>
<b>Subject:</b> Re: [bug report] drm/amdgpu: add amdgpu_ras.c to support ras (v2)</font>
<div> </div>
</div>
<div class="BodyFragment"><font size="2"><span style="font-size:11pt;">
<div class="PlainText">On Wed, May 06, 2020 at 07:26:16AM +0000, Zhou1, Tao wrote:<br>
> [AMD Public Use]<br>
> <br>
> Hi Dan:<br>
> <br>
> Please check the following piece of code in amdgpu_ras_debugfs_ctrl_parse_data:<br>
> <br>
> if (op != -1) {<br>
> if (amdgpu_ras_find_block_id_by_name(block_name, &block_id))<br>
> return -EINVAL;<br>
> <br>
> data->head.block = block_id;<br>
> <br>
> amdgpu_ras_find_block_id_by_name will return error directly if someone try to provide an invalid block_name intentionally via debugfs.<br>
> <br>
<br>
No. It's the line after that which are the problem.<br>
<br>
drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c<br>
147 static int amdgpu_ras_debugfs_ctrl_parse_data(struct file *f,<br>
148 const char __user *buf, size_t size,<br>
149 loff_t *pos, struct ras_debug_if *data)<br>
150 {<br>
151 ssize_t s = min_t(u64, 64, size);<br>
152 char str[65];<br>
153 char block_name[33];<br>
154 char err[9] = "ue";<br>
155 int op = -1;<br>
156 int block_id;<br>
157 uint32_t sub_block;<br>
158 u64 address, value;<br>
159 <br>
160 if (*pos)<br>
161 return -EINVAL;<br>
162 *pos = size;<br>
163 <br>
164 memset(str, 0, sizeof(str));<br>
165 memset(data, 0, sizeof(*data));<br>
166 <br>
167 if (copy_from_user(str, buf, s))<br>
168 return -EINVAL;<br>
169 <br>
170 if (sscanf(str, "disable %32s", block_name) == 1)<br>
171 op = 0;<br>
172 else if (sscanf(str, "enable %32s %8s", block_name, err) == 2)<br>
173 op = 1;<br>
174 else if (sscanf(str, "inject %32s %8s", block_name, err) == 2)<br>
175 op = 2;<br>
176 else if (str[0] && str[1] && str[2] && str[3])<br>
177 /* ascii string, but commands are not matched. */<br>
<br>
Say we don't write an ascii string.<br>
<br>
178 return -EINVAL;<br>
179 <br>
180 if (op != -1) {<br>
181 if (amdgpu_ras_find_block_id_by_name(block_name, &block_id))<br>
182 return -EINVAL;<br>
183 <br>
184 data->head.block = block_id;<br>
185 /* only ue and ce errors are supported */<br>
186 if (!memcmp("ue", err, 2))<br>
187 data->head.type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE;<br>
188 else if (!memcmp("ce", err, 2))<br>
189 data->head.type = AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE;<br>
190 else<br>
191 return -EINVAL;<br>
192 <br>
193 data->op = op;<br>
194 <br>
195 if (op == 2) {<br>
196 if (sscanf(str, "%*s %*s %*s %u %llu %llu",<br>
197 &sub_block, &address, &value) != 3)<br>
198 if (sscanf(str, "%*s %*s %*s 0x%x 0x%llx 0x%llx",<br>
199 &sub_block, &address, &value) != 3)<br>
200 return -EINVAL;<br>
201 data->head.sub_block_index = sub_block;<br>
202 data->inject.address = address;<br>
203 data->inject.value = value;<br>
204 }<br>
205 } else {<br>
206 if (size < sizeof(*data))<br>
207 return -EINVAL;<br>
208 <br>
209 if (copy_from_user(data, buf, sizeof(*data)))<br>
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^<br>
This lets us set the data->head.block to whatever we want. Premusably<br>
there is a trusted app which knows how to write the correct values.<br>
But if it has a bug that will cause a crash and we'll have to find a<br>
way to disable it in the kernel for kernel lock down mode etc so either<br>
way we'll need to do a bit of work.<br>
<br>
210 return -EINVAL;<br>
211 }<br>
212 <br>
213 return 0;<br>
214 }<br>
<br>
regards,<br>
dan carpenter<br>
<br>
</div>
</span></font></div>
</div>
</body>
</html>