diff options
author | Sanidhya Kashyap <sanidhya.gatech@gmail.com> | 2015-03-21 17:54:58 +0100 |
---|---|---|
committer | Ilya Dryomov <idryomov@gmail.com> | 2015-04-20 17:55:34 +0200 |
commit | a149bb9a281c5c2904cf6fcdf9ed386340032ce3 (patch) | |
tree | 644078c1ab0c063382210f3d0b43a239070b1364 /fs/ceph/dir.c | |
parent | ceph: properly release page upon error (diff) | |
download | linux-a149bb9a281c5c2904cf6fcdf9ed386340032ce3.tar.xz linux-a149bb9a281c5c2904cf6fcdf9ed386340032ce3.zip |
ceph: kstrdup() memory handling
Currently, there is no check for the kstrdup() for r_path2,
r_path1 and snapdir_name as various locations as there is a
possibility of failure during memory pressure. Therefore,
returning ENOMEM where the checks have been missed.
Signed-off-by: Sanidhya Kashyap <sanidhya.gatech@gmail.com>
Signed-off-by: Yan, Zheng <zyan@redhat.com>
Diffstat (limited to 'fs/ceph/dir.c')
-rw-r--r-- | fs/ceph/dir.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index d486f2a5a88d..98c71e895e81 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c @@ -337,16 +337,23 @@ more: ceph_mdsc_put_request(req); return err; } - req->r_inode = inode; - ihold(inode); - req->r_dentry = dget(file->f_path.dentry); /* hints to request -> mds selection code */ req->r_direct_mode = USE_AUTH_MDS; req->r_direct_hash = ceph_frag_value(frag); req->r_direct_is_hash = true; - req->r_path2 = kstrdup(fi->last_name, GFP_NOFS); + if (fi->last_name) { + req->r_path2 = kstrdup(fi->last_name, GFP_NOFS); + if (!req->r_path2) { + ceph_mdsc_put_request(req); + return -ENOMEM; + } + } req->r_readdir_offset = fi->next_offset; req->r_args.readdir.frag = cpu_to_le32(frag); + + req->r_inode = inode; + ihold(inode); + req->r_dentry = dget(file->f_path.dentry); err = ceph_mdsc_do_request(mdsc, NULL, req); if (err < 0) { ceph_mdsc_put_request(req); @@ -757,10 +764,15 @@ static int ceph_symlink(struct inode *dir, struct dentry *dentry, err = PTR_ERR(req); goto out; } - req->r_dentry = dget(dentry); - req->r_num_caps = 2; req->r_path2 = kstrdup(dest, GFP_NOFS); + if (!req->r_path2) { + err = -ENOMEM; + ceph_mdsc_put_request(req); + goto out; + } req->r_locked_dir = dir; + req->r_dentry = dget(dentry); + req->r_num_caps = 2; req->r_dentry_drop = CEPH_CAP_FILE_SHARED; req->r_dentry_unless = CEPH_CAP_FILE_EXCL; err = ceph_mdsc_do_request(mdsc, dir, req); |