summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/xattr.c22
-rw-r--r--lib/iov_iter.c4
-rw-r--r--net/socket.c15
3 files changed, 32 insertions, 9 deletions
diff --git a/fs/xattr.c b/fs/xattr.c
index 3368659..2d13b4e 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -170,7 +170,7 @@ int __vfs_setxattr_noperm(struct dentry *dentry, const char *name,
const void *value, size_t size, int flags)
{
struct inode *inode = dentry->d_inode;
- int error = -EOPNOTSUPP;
+ int error = -EAGAIN;
int issec = !strncmp(name, XATTR_SECURITY_PREFIX,
XATTR_SECURITY_PREFIX_LEN);
@@ -183,15 +183,21 @@ int __vfs_setxattr_noperm(struct dentry *dentry, const char *name,
security_inode_post_setxattr(dentry, name, value,
size, flags);
}
- } else if (issec) {
- const char *suffix = name + XATTR_SECURITY_PREFIX_LEN;
-
+ } else {
if (unlikely(is_bad_inode(inode)))
return -EIO;
- error = security_inode_setsecurity(inode, suffix, value,
- size, flags);
- if (!error)
- fsnotify_xattr(dentry);
+ }
+ if (error == -EAGAIN) {
+ error = -EOPNOTSUPP;
+
+ if (issec) {
+ const char *suffix = name + XATTR_SECURITY_PREFIX_LEN;
+
+ error = security_inode_setsecurity(inode, suffix, value,
+ size, flags);
+ if (!error)
+ fsnotify_xattr(dentry);
+ }
}
return error;
diff --git a/lib/iov_iter.c b/lib/iov_iter.c
index f0c7f14..f2bd21b 100644
--- a/lib/iov_iter.c
+++ b/lib/iov_iter.c
@@ -683,10 +683,11 @@ static void pipe_advance(struct iov_iter *i, size_t size)
struct pipe_inode_info *pipe = i->pipe;
struct pipe_buffer *buf;
int idx = i->idx;
- size_t off = i->iov_offset;
+ size_t off = i->iov_offset, orig_sz;
if (unlikely(i->count < size))
size = i->count;
+ orig_sz = size;
if (size) {
if (off) /* make it relative to the beginning of buffer */
@@ -713,6 +714,7 @@ static void pipe_advance(struct iov_iter *i, size_t size)
pipe->nrbufs--;
}
}
+ i->count -= orig_sz;
}
void iov_iter_advance(struct iov_iter *i, size_t size)
diff --git a/net/socket.c b/net/socket.c
index 272518b..73dc69f 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -341,8 +341,23 @@ static const struct xattr_handler sockfs_xattr_handler = {
.get = sockfs_xattr_get,
};
+static int sockfs_security_xattr_set(const struct xattr_handler *handler,
+ struct dentry *dentry, struct inode *inode,
+ const char *suffix, const void *value,
+ size_t size, int flags)
+{
+ /* Handled by LSM. */
+ return -EAGAIN;
+}
+
+static const struct xattr_handler sockfs_security_xattr_handler = {
+ .prefix = XATTR_SECURITY_PREFIX,
+ .set = sockfs_security_xattr_set,
+};
+
static const struct xattr_handler *sockfs_xattr_handlers[] = {
&sockfs_xattr_handler,
+ &sockfs_security_xattr_handler,
NULL
};