diff options
-rw-r--r-- | include/linux/capability.h | 6 | ||||
-rw-r--r-- | security/commoncap.c | 23 |
2 files changed, 17 insertions, 12 deletions
diff --git a/include/linux/capability.h b/include/linux/capability.h index 7a8d7ade28a0..bb017edffd56 100644 --- a/include/linux/capability.h +++ b/include/linux/capability.h | |||
@@ -56,10 +56,8 @@ typedef struct __user_cap_data_struct { | |||
56 | 56 | ||
57 | struct vfs_cap_data { | 57 | struct vfs_cap_data { |
58 | __u32 magic_etc; /* Little endian */ | 58 | __u32 magic_etc; /* Little endian */ |
59 | struct { | 59 | __u32 permitted; /* Little endian */ |
60 | __u32 permitted; /* Little endian */ | 60 | __u32 inheritable; /* Little endian */ |
61 | __u32 inheritable; /* Little endian */ | ||
62 | } data[1]; | ||
63 | }; | 61 | }; |
64 | 62 | ||
65 | #ifdef __KERNEL__ | 63 | #ifdef __KERNEL__ |
diff --git a/security/commoncap.c b/security/commoncap.c index 43f902750a1b..bf67871173ef 100644 --- a/security/commoncap.c +++ b/security/commoncap.c | |||
@@ -190,7 +190,8 @@ int cap_inode_killpriv(struct dentry *dentry) | |||
190 | return inode->i_op->removexattr(dentry, XATTR_NAME_CAPS); | 190 | return inode->i_op->removexattr(dentry, XATTR_NAME_CAPS); |
191 | } | 191 | } |
192 | 192 | ||
193 | static inline int cap_from_disk(__le32 *caps, struct linux_binprm *bprm, | 193 | static inline int cap_from_disk(struct vfs_cap_data *caps, |
194 | struct linux_binprm *bprm, | ||
194 | int size) | 195 | int size) |
195 | { | 196 | { |
196 | __u32 magic_etc; | 197 | __u32 magic_etc; |
@@ -198,7 +199,7 @@ static inline int cap_from_disk(__le32 *caps, struct linux_binprm *bprm, | |||
198 | if (size != XATTR_CAPS_SZ) | 199 | if (size != XATTR_CAPS_SZ) |
199 | return -EINVAL; | 200 | return -EINVAL; |
200 | 201 | ||
201 | magic_etc = le32_to_cpu(caps[0]); | 202 | magic_etc = le32_to_cpu(caps->magic_etc); |
202 | 203 | ||
203 | switch ((magic_etc & VFS_CAP_REVISION_MASK)) { | 204 | switch ((magic_etc & VFS_CAP_REVISION_MASK)) { |
204 | case VFS_CAP_REVISION: | 205 | case VFS_CAP_REVISION: |
@@ -206,8 +207,8 @@ static inline int cap_from_disk(__le32 *caps, struct linux_binprm *bprm, | |||
206 | bprm->cap_effective = true; | 207 | bprm->cap_effective = true; |
207 | else | 208 | else |
208 | bprm->cap_effective = false; | 209 | bprm->cap_effective = false; |
209 | bprm->cap_permitted = to_cap_t( le32_to_cpu(caps[1]) ); | 210 | bprm->cap_permitted = to_cap_t(le32_to_cpu(caps->permitted)); |
210 | bprm->cap_inheritable = to_cap_t( le32_to_cpu(caps[2]) ); | 211 | bprm->cap_inheritable = to_cap_t(le32_to_cpu(caps->inheritable)); |
211 | return 0; | 212 | return 0; |
212 | default: | 213 | default: |
213 | return -EINVAL; | 214 | return -EINVAL; |
@@ -219,7 +220,7 @@ static int get_file_caps(struct linux_binprm *bprm) | |||
219 | { | 220 | { |
220 | struct dentry *dentry; | 221 | struct dentry *dentry; |
221 | int rc = 0; | 222 | int rc = 0; |
222 | __le32 v1caps[XATTR_CAPS_SZ]; | 223 | struct vfs_cap_data incaps; |
223 | struct inode *inode; | 224 | struct inode *inode; |
224 | 225 | ||
225 | if (bprm->file->f_vfsmnt->mnt_flags & MNT_NOSUID) { | 226 | if (bprm->file->f_vfsmnt->mnt_flags & MNT_NOSUID) { |
@@ -232,8 +233,14 @@ static int get_file_caps(struct linux_binprm *bprm) | |||
232 | if (!inode->i_op || !inode->i_op->getxattr) | 233 | if (!inode->i_op || !inode->i_op->getxattr) |
233 | goto out; | 234 | goto out; |
234 | 235 | ||
235 | rc = inode->i_op->getxattr(dentry, XATTR_NAME_CAPS, &v1caps, | 236 | rc = inode->i_op->getxattr(dentry, XATTR_NAME_CAPS, NULL, 0); |
236 | XATTR_CAPS_SZ); | 237 | if (rc > 0) { |
238 | if (rc == XATTR_CAPS_SZ) | ||
239 | rc = inode->i_op->getxattr(dentry, XATTR_NAME_CAPS, | ||
240 | &incaps, XATTR_CAPS_SZ); | ||
241 | else | ||
242 | rc = -EINVAL; | ||
243 | } | ||
237 | if (rc == -ENODATA || rc == -EOPNOTSUPP) { | 244 | if (rc == -ENODATA || rc == -EOPNOTSUPP) { |
238 | /* no data, that's ok */ | 245 | /* no data, that's ok */ |
239 | rc = 0; | 246 | rc = 0; |
@@ -242,7 +249,7 @@ static int get_file_caps(struct linux_binprm *bprm) | |||
242 | if (rc < 0) | 249 | if (rc < 0) |
243 | goto out; | 250 | goto out; |
244 | 251 | ||
245 | rc = cap_from_disk(v1caps, bprm, rc); | 252 | rc = cap_from_disk(&incaps, bprm, rc); |
246 | if (rc) | 253 | if (rc) |
247 | printk(KERN_NOTICE "%s: cap_from_disk returned %d for %s\n", | 254 | printk(KERN_NOTICE "%s: cap_from_disk returned %d for %s\n", |
248 | __FUNCTION__, rc, bprm->filename); | 255 | __FUNCTION__, rc, bprm->filename); |