4 * Copyright (C) 1991, 1992 Linus Torvalds
5 * changes by Thomas Schoebel-Theuer
8 #include <linux/export.h>
9 #include <linux/time.h>
11 #include <linux/string.h>
12 #include <linux/capability.h>
13 #include <linux/fsnotify.h>
14 #include <linux/fcntl.h>
15 #include <linux/security.h>
16 #include <linux/evm.h>
19 * inode_change_ok - check if attribute changes to an inode are allowed
20 * @inode: inode to check
21 * @attr: attributes to change
23 * Check if we are allowed to change the attributes contained in @attr
24 * in the given inode. This includes the normal unix access permission
25 * checks, as well as checks for rlimits and others.
27 * Should be called as the first thing in ->setattr implementations,
28 * possibly after taking additional locks.
30 int inode_change_ok(const struct inode
*inode
, struct iattr
*attr
)
32 unsigned int ia_valid
= attr
->ia_valid
;
35 * First check size constraints. These can't be overriden using
38 if (ia_valid
& ATTR_SIZE
) {
39 int error
= inode_newsize_ok(inode
, attr
->ia_size
);
44 /* If force is set do it anyway. */
45 if (ia_valid
& ATTR_FORCE
)
48 /* Make sure a caller can chown. */
49 if ((ia_valid
& ATTR_UID
) &&
50 (!uid_eq(current_fsuid(), inode
->i_uid
) ||
51 !uid_eq(attr
->ia_uid
, inode
->i_uid
)) && !capable(CAP_CHOWN
))
54 /* Make sure caller can chgrp. */
55 if ((ia_valid
& ATTR_GID
) &&
56 (!uid_eq(current_fsuid(), inode
->i_uid
) ||
57 (!in_group_p(attr
->ia_gid
) && !gid_eq(attr
->ia_gid
, inode
->i_gid
))) &&
61 /* Make sure a caller can chmod. */
62 if (ia_valid
& ATTR_MODE
) {
63 if (!inode_owner_or_capable(inode
))
65 /* Also check the setgid bit! */
66 if (!in_group_p((ia_valid
& ATTR_GID
) ? attr
->ia_gid
:
67 inode
->i_gid
) && !capable(CAP_FSETID
))
68 attr
->ia_mode
&= ~S_ISGID
;
71 /* Check for setting the inode time. */
72 if (ia_valid
& (ATTR_MTIME_SET
| ATTR_ATIME_SET
| ATTR_TIMES_SET
)) {
73 if (!inode_owner_or_capable(inode
))
79 EXPORT_SYMBOL(inode_change_ok
);
82 * inode_newsize_ok - may this inode be truncated to a given size
83 * @inode: the inode to be truncated
84 * @offset: the new size to assign to the inode
85 * @Returns: 0 on success, -ve errno on failure
87 * inode_newsize_ok must be called with i_mutex held.
89 * inode_newsize_ok will check filesystem limits and ulimits to check that the
90 * new inode size is within limits. inode_newsize_ok will also send SIGXFSZ
91 * when necessary. Caller must not proceed with inode size change if failure is
92 * returned. @inode must be a file (not directory), with appropriate
93 * permissions to allow truncate (inode_newsize_ok does NOT check these
96 int inode_newsize_ok(const struct inode
*inode
, loff_t offset
)
98 if (inode
->i_size
< offset
) {
101 limit
= rlimit(RLIMIT_FSIZE
);
102 if (limit
!= RLIM_INFINITY
&& offset
> limit
)
104 if (offset
> inode
->i_sb
->s_maxbytes
)
108 * truncation of in-use swapfiles is disallowed - it would
109 * cause subsequent swapout to scribble on the now-freed
112 if (IS_SWAPFILE(inode
))
118 send_sig(SIGXFSZ
, current
, 0);
122 EXPORT_SYMBOL(inode_newsize_ok
);
125 * setattr_copy - copy simple metadata updates into the generic inode
126 * @inode: the inode to be updated
127 * @attr: the new attributes
129 * setattr_copy must be called with i_mutex held.
131 * setattr_copy updates the inode's metadata with that specified
132 * in attr. Noticeably missing is inode size update, which is more complex
133 * as it requires pagecache updates.
135 * The inode is not marked as dirty after this operation. The rationale is
136 * that for "simple" filesystems, the struct inode is the inode storage.
137 * The caller is free to mark the inode dirty afterwards if needed.
139 void setattr_copy(struct inode
*inode
, const struct iattr
*attr
)
141 unsigned int ia_valid
= attr
->ia_valid
;
143 if (ia_valid
& ATTR_UID
)
144 inode
->i_uid
= attr
->ia_uid
;
145 if (ia_valid
& ATTR_GID
)
146 inode
->i_gid
= attr
->ia_gid
;
147 if (ia_valid
& ATTR_ATIME
)
148 inode
->i_atime
= timespec_trunc(attr
->ia_atime
,
149 inode
->i_sb
->s_time_gran
);
150 if (ia_valid
& ATTR_MTIME
)
151 inode
->i_mtime
= timespec_trunc(attr
->ia_mtime
,
152 inode
->i_sb
->s_time_gran
);
153 if (ia_valid
& ATTR_CTIME
)
154 inode
->i_ctime
= timespec_trunc(attr
->ia_ctime
,
155 inode
->i_sb
->s_time_gran
);
156 if (ia_valid
& ATTR_MODE
) {
157 umode_t mode
= attr
->ia_mode
;
159 if (!in_group_p(inode
->i_gid
) && !capable(CAP_FSETID
))
161 inode
->i_mode
= mode
;
164 EXPORT_SYMBOL(setattr_copy
);
166 int notify_change(struct dentry
* dentry
, struct iattr
* attr
)
168 struct inode
*inode
= dentry
->d_inode
;
169 umode_t mode
= inode
->i_mode
;
172 unsigned int ia_valid
= attr
->ia_valid
;
174 if (ia_valid
& (ATTR_MODE
| ATTR_UID
| ATTR_GID
| ATTR_TIMES_SET
)) {
175 if (IS_IMMUTABLE(inode
) || IS_APPEND(inode
))
179 if ((ia_valid
& ATTR_SIZE
) && IS_I_VERSION(inode
)) {
180 if (attr
->ia_size
!= inode
->i_size
)
181 inode_inc_iversion(inode
);
184 if ((ia_valid
& ATTR_MODE
)) {
185 umode_t amode
= attr
->ia_mode
;
186 /* Flag setting protected by i_mutex */
188 inode
->i_flags
&= ~S_NOSEC
;
191 now
= current_fs_time(inode
->i_sb
);
193 attr
->ia_ctime
= now
;
194 if (!(ia_valid
& ATTR_ATIME_SET
))
195 attr
->ia_atime
= now
;
196 if (!(ia_valid
& ATTR_MTIME_SET
))
197 attr
->ia_mtime
= now
;
198 if (ia_valid
& ATTR_KILL_PRIV
) {
199 attr
->ia_valid
&= ~ATTR_KILL_PRIV
;
200 ia_valid
&= ~ATTR_KILL_PRIV
;
201 error
= security_inode_need_killpriv(dentry
);
203 error
= security_inode_killpriv(dentry
);
209 * We now pass ATTR_KILL_S*ID to the lower level setattr function so
210 * that the function has the ability to reinterpret a mode change
211 * that's due to these bits. This adds an implicit restriction that
212 * no function will ever call notify_change with both ATTR_MODE and
213 * ATTR_KILL_S*ID set.
215 if ((ia_valid
& (ATTR_KILL_SUID
|ATTR_KILL_SGID
)) &&
216 (ia_valid
& ATTR_MODE
))
219 if (ia_valid
& ATTR_KILL_SUID
) {
220 if (mode
& S_ISUID
) {
221 ia_valid
= attr
->ia_valid
|= ATTR_MODE
;
222 attr
->ia_mode
= (inode
->i_mode
& ~S_ISUID
);
225 if (ia_valid
& ATTR_KILL_SGID
) {
226 if ((mode
& (S_ISGID
| S_IXGRP
)) == (S_ISGID
| S_IXGRP
)) {
227 if (!(ia_valid
& ATTR_MODE
)) {
228 ia_valid
= attr
->ia_valid
|= ATTR_MODE
;
229 attr
->ia_mode
= inode
->i_mode
;
231 attr
->ia_mode
&= ~S_ISGID
;
234 if (!(attr
->ia_valid
& ~(ATTR_KILL_SUID
| ATTR_KILL_SGID
)))
237 error
= security_inode_setattr(dentry
, attr
);
241 if (inode
->i_op
->setattr
)
242 error
= inode
->i_op
->setattr(dentry
, attr
);
244 error
= simple_setattr(dentry
, attr
);
247 fsnotify_change(dentry
, ia_valid
);
248 evm_inode_post_setattr(dentry
, ia_valid
);
254 EXPORT_SYMBOL(notify_change
);
This page took 0.035119 seconds and 5 git commands to generate.