Skip to content

Commit 7b871c7

Browse files
committed
Merge branch 'work.gfs2' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull gfs2 setattr updates from Al Viro: "Make it possible for filesystems to use a generic 'may_setattr()' and switch gfs2 to using it" * 'work.gfs2' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: gfs2: Switch to may_setattr in gfs2_setattr fs: Move notify_change permission checks into may_setattr
2 parents e2e694b + d75b9fa commit 7b871c7

File tree

3 files changed

+35
-21
lines changed

3 files changed

+35
-21
lines changed

fs/attr.c

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,34 @@ void setattr_copy(struct user_namespace *mnt_userns, struct inode *inode,
249249
}
250250
EXPORT_SYMBOL(setattr_copy);
251251

252+
int may_setattr(struct user_namespace *mnt_userns, struct inode *inode,
253+
unsigned int ia_valid)
254+
{
255+
int error;
256+
257+
if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_TIMES_SET)) {
258+
if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
259+
return -EPERM;
260+
}
261+
262+
/*
263+
* If utimes(2) and friends are called with times == NULL (or both
264+
* times are UTIME_NOW), then we need to check for write permission
265+
*/
266+
if (ia_valid & ATTR_TOUCH) {
267+
if (IS_IMMUTABLE(inode))
268+
return -EPERM;
269+
270+
if (!inode_owner_or_capable(mnt_userns, inode)) {
271+
error = inode_permission(mnt_userns, inode, MAY_WRITE);
272+
if (error)
273+
return error;
274+
}
275+
}
276+
return 0;
277+
}
278+
EXPORT_SYMBOL(may_setattr);
279+
252280
/**
253281
* notify_change - modify attributes of a filesytem object
254282
* @mnt_userns: user namespace of the mount the inode was found from
@@ -290,25 +318,9 @@ int notify_change(struct user_namespace *mnt_userns, struct dentry *dentry,
290318

291319
WARN_ON_ONCE(!inode_is_locked(inode));
292320

293-
if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_TIMES_SET)) {
294-
if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
295-
return -EPERM;
296-
}
297-
298-
/*
299-
* If utimes(2) and friends are called with times == NULL (or both
300-
* times are UTIME_NOW), then we need to check for write permission
301-
*/
302-
if (ia_valid & ATTR_TOUCH) {
303-
if (IS_IMMUTABLE(inode))
304-
return -EPERM;
305-
306-
if (!inode_owner_or_capable(mnt_userns, inode)) {
307-
error = inode_permission(mnt_userns, inode, MAY_WRITE);
308-
if (error)
309-
return error;
310-
}
311-
}
321+
error = may_setattr(mnt_userns, inode, ia_valid);
322+
if (error)
323+
return error;
312324

313325
if ((ia_valid & ATTR_MODE)) {
314326
umode_t amode = attr->ia_mode;

fs/gfs2/inode.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1985,8 +1985,8 @@ static int gfs2_setattr(struct user_namespace *mnt_userns,
19851985
if (error)
19861986
goto out;
19871987

1988-
error = -EPERM;
1989-
if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
1988+
error = may_setattr(&init_user_ns, inode, attr->ia_valid);
1989+
if (error)
19901990
goto error;
19911991

19921992
error = setattr_prepare(&init_user_ns, dentry, attr);

include/linux/fs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3439,6 +3439,8 @@ extern int buffer_migrate_page_norefs(struct address_space *,
34393439
#define buffer_migrate_page_norefs NULL
34403440
#endif
34413441

3442+
int may_setattr(struct user_namespace *mnt_userns, struct inode *inode,
3443+
unsigned int ia_valid);
34423444
int setattr_prepare(struct user_namespace *, struct dentry *, struct iattr *);
34433445
extern int inode_newsize_ok(const struct inode *, loff_t offset);
34443446
void setattr_copy(struct user_namespace *, struct inode *inode,

0 commit comments

Comments
 (0)