Skip to content

Commit 7764235

Browse files
author
Miklos Szeredi
committed
ovl: use vfs_get_link()
Resulting in a complete removal of a function basically implementing the inverse of vfs_readlink(). As a bonus, now the proper security hook is also called. Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
1 parent d60874c commit 7764235

2 files changed

Lines changed: 7 additions & 49 deletions

File tree

fs/overlayfs/copy_up.c

Lines changed: 6 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -177,40 +177,6 @@ static int ovl_copy_up_data(struct path *old, struct path *new, loff_t len)
177177
return error;
178178
}
179179

180-
static char *ovl_read_symlink(struct dentry *realdentry)
181-
{
182-
int res;
183-
char *buf;
184-
struct inode *inode = realdentry->d_inode;
185-
mm_segment_t old_fs;
186-
187-
res = -EINVAL;
188-
if (!inode->i_op->readlink)
189-
goto err;
190-
191-
res = -ENOMEM;
192-
buf = (char *) __get_free_page(GFP_KERNEL);
193-
if (!buf)
194-
goto err;
195-
196-
old_fs = get_fs();
197-
set_fs(get_ds());
198-
/* The cast to a user pointer is valid due to the set_fs() */
199-
res = inode->i_op->readlink(realdentry,
200-
(char __user *)buf, PAGE_SIZE - 1);
201-
set_fs(old_fs);
202-
if (res < 0) {
203-
free_page((unsigned long) buf);
204-
goto err;
205-
}
206-
buf[res] = '\0';
207-
208-
return buf;
209-
210-
err:
211-
return ERR_PTR(res);
212-
}
213-
214180
static int ovl_set_timestamps(struct dentry *upperdentry, struct kstat *stat)
215181
{
216182
struct iattr attr = {
@@ -342,18 +308,20 @@ static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir,
342308
int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry,
343309
struct path *lowerpath, struct kstat *stat)
344310
{
311+
DEFINE_DELAYED_CALL(done);
345312
struct dentry *workdir = ovl_workdir(dentry);
346313
int err;
347314
struct kstat pstat;
348315
struct path parentpath;
316+
struct dentry *lowerdentry = lowerpath->dentry;
349317
struct dentry *upperdir;
350318
struct dentry *upperdentry;
351-
char *link = NULL;
319+
const char *link = NULL;
352320

353321
if (WARN_ON(!workdir))
354322
return -EROFS;
355323

356-
ovl_do_check_copy_up(lowerpath->dentry);
324+
ovl_do_check_copy_up(lowerdentry);
357325

358326
ovl_path_upper(parent, &parentpath);
359327
upperdir = parentpath.dentry;
@@ -363,7 +331,7 @@ int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry,
363331
return err;
364332

365333
if (S_ISLNK(stat->mode)) {
366-
link = ovl_read_symlink(lowerpath->dentry);
334+
link = vfs_get_link(lowerdentry, &done);
367335
if (IS_ERR(link))
368336
return PTR_ERR(link);
369337
}
@@ -388,9 +356,7 @@ int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry,
388356
}
389357
out_unlock:
390358
unlock_rename(workdir, upperdir);
391-
392-
if (link)
393-
free_page((unsigned long) link);
359+
do_delayed_call(&done);
394360

395361
return err;
396362
}

fs/overlayfs/inode.c

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -156,22 +156,14 @@ static const char *ovl_get_link(struct dentry *dentry,
156156
struct inode *inode,
157157
struct delayed_call *done)
158158
{
159-
struct dentry *realdentry;
160-
struct inode *realinode;
161159
const struct cred *old_cred;
162160
const char *p;
163161

164162
if (!dentry)
165163
return ERR_PTR(-ECHILD);
166164

167-
realdentry = ovl_dentry_real(dentry);
168-
realinode = realdentry->d_inode;
169-
170-
if (WARN_ON(!realinode->i_op->get_link))
171-
return ERR_PTR(-EPERM);
172-
173165
old_cred = ovl_override_creds(dentry->d_sb);
174-
p = realinode->i_op->get_link(realdentry, realinode, done);
166+
p = vfs_get_link(ovl_dentry_real(dentry), done);
175167
revert_creds(old_cred);
176168
return p;
177169
}

0 commit comments

Comments
 (0)