Commit 38f49a5132f24d29236820eb5c7dd956e47f94a3
Committed by
Greg Kroah-Hartman
1 parent
a6849fa1f7
Exists in
master
and in
7 other branches
sysfs: only access bin file vm_ops with the active lock
bb->vm_ops is a cached copy of the vm_ops of the underlying sysfs bin file, which means that after sysfs_bin_remove_file completes it is only longer valid to deference bb->vm_ops. So move all of the tests of bb->vm_ops inside of where we hold the sysfs active lock. Signed-off-by: Eric W. Biederman <ebiederm@aristanetworks.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Showing 1 changed file with 26 additions and 16 deletions Side-by-side Diff
fs/sysfs/bin.c
... | ... | @@ -179,13 +179,14 @@ |
179 | 179 | struct bin_buffer *bb = file->private_data; |
180 | 180 | struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; |
181 | 181 | |
182 | - if (!bb->vm_ops || !bb->vm_ops->open) | |
182 | + if (!bb->vm_ops) | |
183 | 183 | return; |
184 | 184 | |
185 | 185 | if (!sysfs_get_active(attr_sd)) |
186 | 186 | return; |
187 | 187 | |
188 | - bb->vm_ops->open(vma); | |
188 | + if (bb->vm_ops->open) | |
189 | + bb->vm_ops->open(vma); | |
189 | 190 | |
190 | 191 | sysfs_put_active(attr_sd); |
191 | 192 | } |
192 | 193 | |
... | ... | @@ -197,13 +198,15 @@ |
197 | 198 | struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; |
198 | 199 | int ret; |
199 | 200 | |
200 | - if (!bb->vm_ops || !bb->vm_ops->fault) | |
201 | + if (!bb->vm_ops) | |
201 | 202 | return VM_FAULT_SIGBUS; |
202 | 203 | |
203 | 204 | if (!sysfs_get_active(attr_sd)) |
204 | 205 | return VM_FAULT_SIGBUS; |
205 | 206 | |
206 | - ret = bb->vm_ops->fault(vma, vmf); | |
207 | + ret = VM_FAULT_SIGBUS; | |
208 | + if (bb->vm_ops->fault) | |
209 | + ret = bb->vm_ops->fault(vma, vmf); | |
207 | 210 | |
208 | 211 | sysfs_put_active(attr_sd); |
209 | 212 | return ret; |
210 | 213 | |
... | ... | @@ -219,13 +222,12 @@ |
219 | 222 | if (!bb->vm_ops) |
220 | 223 | return VM_FAULT_SIGBUS; |
221 | 224 | |
222 | - if (!bb->vm_ops->page_mkwrite) | |
223 | - return 0; | |
224 | - | |
225 | 225 | if (!sysfs_get_active(attr_sd)) |
226 | 226 | return VM_FAULT_SIGBUS; |
227 | 227 | |
228 | - ret = bb->vm_ops->page_mkwrite(vma, vmf); | |
228 | + ret = 0; | |
229 | + if (bb->vm_ops->page_mkwrite) | |
230 | + ret = bb->vm_ops->page_mkwrite(vma, vmf); | |
229 | 231 | |
230 | 232 | sysfs_put_active(attr_sd); |
231 | 233 | return ret; |
232 | 234 | |
... | ... | @@ -239,13 +241,15 @@ |
239 | 241 | struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; |
240 | 242 | int ret; |
241 | 243 | |
242 | - if (!bb->vm_ops || !bb->vm_ops->access) | |
244 | + if (!bb->vm_ops) | |
243 | 245 | return -EINVAL; |
244 | 246 | |
245 | 247 | if (!sysfs_get_active(attr_sd)) |
246 | 248 | return -EINVAL; |
247 | 249 | |
248 | - ret = bb->vm_ops->access(vma, addr, buf, len, write); | |
250 | + ret = -EINVAL; | |
251 | + if (bb->vm_ops->access) | |
252 | + ret = bb->vm_ops->access(vma, addr, buf, len, write); | |
249 | 253 | |
250 | 254 | sysfs_put_active(attr_sd); |
251 | 255 | return ret; |
252 | 256 | |
... | ... | @@ -259,13 +263,15 @@ |
259 | 263 | struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; |
260 | 264 | int ret; |
261 | 265 | |
262 | - if (!bb->vm_ops || !bb->vm_ops->set_policy) | |
266 | + if (!bb->vm_ops) | |
263 | 267 | return 0; |
264 | 268 | |
265 | 269 | if (!sysfs_get_active(attr_sd)) |
266 | 270 | return -EINVAL; |
267 | 271 | |
268 | - ret = bb->vm_ops->set_policy(vma, new); | |
272 | + ret = 0; | |
273 | + if (bb->vm_ops->set_policy) | |
274 | + ret = bb->vm_ops->set_policy(vma, new); | |
269 | 275 | |
270 | 276 | sysfs_put_active(attr_sd); |
271 | 277 | return ret; |
272 | 278 | |
... | ... | @@ -279,13 +285,15 @@ |
279 | 285 | struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; |
280 | 286 | struct mempolicy *pol; |
281 | 287 | |
282 | - if (!bb->vm_ops || !bb->vm_ops->get_policy) | |
288 | + if (!bb->vm_ops) | |
283 | 289 | return vma->vm_policy; |
284 | 290 | |
285 | 291 | if (!sysfs_get_active(attr_sd)) |
286 | 292 | return vma->vm_policy; |
287 | 293 | |
288 | - pol = bb->vm_ops->get_policy(vma, addr); | |
294 | + pol = vma->vm_policy; | |
295 | + if (bb->vm_ops->get_policy) | |
296 | + pol = bb->vm_ops->get_policy(vma, addr); | |
289 | 297 | |
290 | 298 | sysfs_put_active(attr_sd); |
291 | 299 | return pol; |
292 | 300 | |
... | ... | @@ -299,13 +307,15 @@ |
299 | 307 | struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; |
300 | 308 | int ret; |
301 | 309 | |
302 | - if (!bb->vm_ops || !bb->vm_ops->migrate) | |
310 | + if (!bb->vm_ops) | |
303 | 311 | return 0; |
304 | 312 | |
305 | 313 | if (!sysfs_get_active(attr_sd)) |
306 | 314 | return 0; |
307 | 315 | |
308 | - ret = bb->vm_ops->migrate(vma, from, to, flags); | |
316 | + ret = 0; | |
317 | + if (bb->vm_ops->migrate) | |
318 | + ret = bb->vm_ops->migrate(vma, from, to, flags); | |
309 | 319 | |
310 | 320 | sysfs_put_active(attr_sd); |
311 | 321 | return ret; |