@@ -41,6 +41,7 @@ int ovl_setattr(struct dentry *dentry, struct iattr *attr)
41
41
{
42
42
int err ;
43
43
struct dentry * upperdentry ;
44
+ const struct cred * old_cred ;
44
45
45
46
/*
46
47
* Check for permissions before trying to copy-up. This is redundant
@@ -84,7 +85,9 @@ int ovl_setattr(struct dentry *dentry, struct iattr *attr)
84
85
attr -> ia_valid &= ~ATTR_MODE ;
85
86
86
87
inode_lock (upperdentry -> d_inode );
88
+ old_cred = ovl_override_creds (dentry -> d_sb );
87
89
err = notify_change (upperdentry , attr , NULL );
90
+ revert_creds (old_cred );
88
91
if (!err )
89
92
ovl_copyattr (upperdentry -> d_inode , dentry -> d_inode );
90
93
inode_unlock (upperdentry -> d_inode );
@@ -102,9 +105,14 @@ static int ovl_getattr(struct vfsmount *mnt, struct dentry *dentry,
102
105
struct kstat * stat )
103
106
{
104
107
struct path realpath ;
108
+ const struct cred * old_cred ;
109
+ int err ;
105
110
106
111
ovl_path_real (dentry , & realpath );
107
- return vfs_getattr (& realpath , stat );
112
+ old_cred = ovl_override_creds (dentry -> d_sb );
113
+ err = vfs_getattr (& realpath , stat );
114
+ revert_creds (old_cred );
115
+ return err ;
108
116
}
109
117
110
118
int ovl_permission (struct inode * inode , int mask )
@@ -188,6 +196,8 @@ static const char *ovl_get_link(struct dentry *dentry,
188
196
{
189
197
struct dentry * realdentry ;
190
198
struct inode * realinode ;
199
+ const struct cred * old_cred ;
200
+ const char * p ;
191
201
192
202
if (!dentry )
193
203
return ERR_PTR (- ECHILD );
@@ -198,13 +208,18 @@ static const char *ovl_get_link(struct dentry *dentry,
198
208
if (WARN_ON (!realinode -> i_op -> get_link ))
199
209
return ERR_PTR (- EPERM );
200
210
201
- return realinode -> i_op -> get_link (realdentry , realinode , done );
211
+ old_cred = ovl_override_creds (dentry -> d_sb );
212
+ p = realinode -> i_op -> get_link (realdentry , realinode , done );
213
+ revert_creds (old_cred );
214
+ return p ;
202
215
}
203
216
204
217
static int ovl_readlink (struct dentry * dentry , char __user * buf , int bufsiz )
205
218
{
206
219
struct path realpath ;
207
220
struct inode * realinode ;
221
+ const struct cred * old_cred ;
222
+ int err ;
208
223
209
224
ovl_path_real (dentry , & realpath );
210
225
realinode = realpath .dentry -> d_inode ;
@@ -214,10 +229,12 @@ static int ovl_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
214
229
215
230
touch_atime (& realpath );
216
231
217
- return realinode -> i_op -> readlink (realpath .dentry , buf , bufsiz );
232
+ old_cred = ovl_override_creds (dentry -> d_sb );
233
+ err = realinode -> i_op -> readlink (realpath .dentry , buf , bufsiz );
234
+ revert_creds (old_cred );
235
+ return err ;
218
236
}
219
237
220
-
221
238
static bool ovl_is_private_xattr (const char * name )
222
239
{
223
240
return strncmp (name , OVL_XATTR_PRE_NAME , OVL_XATTR_PRE_LEN ) == 0 ;
@@ -229,6 +246,7 @@ int ovl_setxattr(struct dentry *dentry, struct inode *inode,
229
246
{
230
247
int err ;
231
248
struct dentry * upperdentry ;
249
+ const struct cred * old_cred ;
232
250
233
251
err = ovl_want_write (dentry );
234
252
if (err )
@@ -243,7 +261,9 @@ int ovl_setxattr(struct dentry *dentry, struct inode *inode,
243
261
goto out_drop_write ;
244
262
245
263
upperdentry = ovl_dentry_upper (dentry );
264
+ old_cred = ovl_override_creds (dentry -> d_sb );
246
265
err = vfs_setxattr (upperdentry , name , value , size , flags );
266
+ revert_creds (old_cred );
247
267
248
268
out_drop_write :
249
269
ovl_drop_write (dentry );
@@ -255,20 +275,28 @@ ssize_t ovl_getxattr(struct dentry *dentry, struct inode *inode,
255
275
const char * name , void * value , size_t size )
256
276
{
257
277
struct dentry * realdentry = ovl_dentry_real (dentry );
278
+ ssize_t res ;
279
+ const struct cred * old_cred ;
258
280
259
281
if (ovl_is_private_xattr (name ))
260
282
return - ENODATA ;
261
283
262
- return vfs_getxattr (realdentry , name , value , size );
284
+ old_cred = ovl_override_creds (dentry -> d_sb );
285
+ res = vfs_getxattr (realdentry , name , value , size );
286
+ revert_creds (old_cred );
287
+ return res ;
263
288
}
264
289
265
290
ssize_t ovl_listxattr (struct dentry * dentry , char * list , size_t size )
266
291
{
267
292
struct dentry * realdentry = ovl_dentry_real (dentry );
268
293
ssize_t res ;
269
294
int off ;
295
+ const struct cred * old_cred ;
270
296
297
+ old_cred = ovl_override_creds (dentry -> d_sb );
271
298
res = vfs_listxattr (realdentry , list , size );
299
+ revert_creds (old_cred );
272
300
if (res <= 0 || size == 0 )
273
301
return res ;
274
302
@@ -295,6 +323,7 @@ int ovl_removexattr(struct dentry *dentry, const char *name)
295
323
int err ;
296
324
struct path realpath ;
297
325
enum ovl_path_type type = ovl_path_real (dentry , & realpath );
326
+ const struct cred * old_cred ;
298
327
299
328
err = ovl_want_write (dentry );
300
329
if (err )
@@ -316,7 +345,9 @@ int ovl_removexattr(struct dentry *dentry, const char *name)
316
345
ovl_path_upper (dentry , & realpath );
317
346
}
318
347
348
+ old_cred = ovl_override_creds (dentry -> d_sb );
319
349
err = vfs_removexattr (realpath .dentry , name );
350
+ revert_creds (old_cred );
320
351
out_drop_write :
321
352
ovl_drop_write (dentry );
322
353
out :
@@ -326,14 +357,20 @@ int ovl_removexattr(struct dentry *dentry, const char *name)
326
357
struct posix_acl * ovl_get_acl (struct inode * inode , int type )
327
358
{
328
359
struct inode * realinode = ovl_inode_real (inode );
360
+ const struct cred * old_cred ;
361
+ struct posix_acl * acl ;
329
362
330
363
if (!IS_POSIXACL (realinode ))
331
364
return NULL ;
332
365
333
366
if (!realinode -> i_op -> get_acl )
334
367
return NULL ;
335
368
336
- return realinode -> i_op -> get_acl (realinode , type );
369
+ old_cred = ovl_override_creds (inode -> i_sb );
370
+ acl = realinode -> i_op -> get_acl (realinode , type );
371
+ revert_creds (old_cred );
372
+
373
+ return acl ;
337
374
}
338
375
339
376
static bool ovl_open_need_copy_up (int flags , enum ovl_path_type type ,
0 commit comments