diff options
Diffstat (limited to 'security/commoncap.c')
-rw-r--r-- | security/commoncap.c | 21 |
1 files changed, 9 insertions, 12 deletions
diff --git a/security/commoncap.c b/security/commoncap.c index 4f8e09340956..48620c93d697 100644 --- a/security/commoncap.c +++ b/security/commoncap.c | |||
@@ -348,21 +348,18 @@ static __u32 sansflags(__u32 m) | |||
348 | return m & ~VFS_CAP_FLAGS_EFFECTIVE; | 348 | return m & ~VFS_CAP_FLAGS_EFFECTIVE; |
349 | } | 349 | } |
350 | 350 | ||
351 | static bool is_v2header(size_t size, __le32 magic) | 351 | static bool is_v2header(size_t size, const struct vfs_cap_data *cap) |
352 | { | 352 | { |
353 | __u32 m = le32_to_cpu(magic); | ||
354 | if (size != XATTR_CAPS_SZ_2) | 353 | if (size != XATTR_CAPS_SZ_2) |
355 | return false; | 354 | return false; |
356 | return sansflags(m) == VFS_CAP_REVISION_2; | 355 | return sansflags(le32_to_cpu(cap->magic_etc)) == VFS_CAP_REVISION_2; |
357 | } | 356 | } |
358 | 357 | ||
359 | static bool is_v3header(size_t size, __le32 magic) | 358 | static bool is_v3header(size_t size, const struct vfs_cap_data *cap) |
360 | { | 359 | { |
361 | __u32 m = le32_to_cpu(magic); | ||
362 | |||
363 | if (size != XATTR_CAPS_SZ_3) | 360 | if (size != XATTR_CAPS_SZ_3) |
364 | return false; | 361 | return false; |
365 | return sansflags(m) == VFS_CAP_REVISION_3; | 362 | return sansflags(le32_to_cpu(cap->magic_etc)) == VFS_CAP_REVISION_3; |
366 | } | 363 | } |
367 | 364 | ||
368 | /* | 365 | /* |
@@ -405,7 +402,7 @@ int cap_inode_getsecurity(struct inode *inode, const char *name, void **buffer, | |||
405 | 402 | ||
406 | fs_ns = inode->i_sb->s_user_ns; | 403 | fs_ns = inode->i_sb->s_user_ns; |
407 | cap = (struct vfs_cap_data *) tmpbuf; | 404 | cap = (struct vfs_cap_data *) tmpbuf; |
408 | if (is_v2header((size_t) ret, cap->magic_etc)) { | 405 | if (is_v2header((size_t) ret, cap)) { |
409 | /* If this is sizeof(vfs_cap_data) then we're ok with the | 406 | /* If this is sizeof(vfs_cap_data) then we're ok with the |
410 | * on-disk value, so return that. */ | 407 | * on-disk value, so return that. */ |
411 | if (alloc) | 408 | if (alloc) |
@@ -413,7 +410,7 @@ int cap_inode_getsecurity(struct inode *inode, const char *name, void **buffer, | |||
413 | else | 410 | else |
414 | kfree(tmpbuf); | 411 | kfree(tmpbuf); |
415 | return ret; | 412 | return ret; |
416 | } else if (!is_v3header((size_t) ret, cap->magic_etc)) { | 413 | } else if (!is_v3header((size_t) ret, cap)) { |
417 | kfree(tmpbuf); | 414 | kfree(tmpbuf); |
418 | return -EINVAL; | 415 | return -EINVAL; |
419 | } | 416 | } |
@@ -470,9 +467,9 @@ static kuid_t rootid_from_xattr(const void *value, size_t size, | |||
470 | return make_kuid(task_ns, rootid); | 467 | return make_kuid(task_ns, rootid); |
471 | } | 468 | } |
472 | 469 | ||
473 | static bool validheader(size_t size, __le32 magic) | 470 | static bool validheader(size_t size, const struct vfs_cap_data *cap) |
474 | { | 471 | { |
475 | return is_v2header(size, magic) || is_v3header(size, magic); | 472 | return is_v2header(size, cap) || is_v3header(size, cap); |
476 | } | 473 | } |
477 | 474 | ||
478 | /* | 475 | /* |
@@ -495,7 +492,7 @@ int cap_convert_nscap(struct dentry *dentry, void **ivalue, size_t size) | |||
495 | 492 | ||
496 | if (!*ivalue) | 493 | if (!*ivalue) |
497 | return -EINVAL; | 494 | return -EINVAL; |
498 | if (!validheader(size, cap->magic_etc)) | 495 | if (!validheader(size, cap)) |
499 | return -EINVAL; | 496 | return -EINVAL; |
500 | if (!capable_wrt_inode_uidgid(inode, CAP_SETFCAP)) | 497 | if (!capable_wrt_inode_uidgid(inode, CAP_SETFCAP)) |
501 | return -EPERM; | 498 | return -EPERM; |