Commit 38f49a5132f24d29236820eb5c7dd956e47f94a3

Authored by Eric W. Biederman
Committed by Greg Kroah-Hartman
1 parent a6849fa1f7

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

... ... @@ -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;