Skip to content

Commit

Permalink
Merge pull request #13030 from SUSE/wip-18612-kraken
Browse files Browse the repository at this point in the history
kraken: client: segfault on ceph_rmdir path /
  • Loading branch information
John Spray committed Jan 25, 2017
2 parents d50af9e + 8d0eb6e commit 08b560c
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 9 deletions.
42 changes: 33 additions & 9 deletions src/client/Client.cc
Expand Up @@ -6164,31 +6164,35 @@ int Client::link(const char *relexisting, const char *relpath, const UserPerm& p
tout(cct) << relpath << std::endl;

filepath existing(relexisting);
filepath path(relpath);
string name = path.last_dentry();
path.pop_dentry();

InodeRef in, dir;
int r = path_walk(existing, &in, perm, true);
if (r < 0)
goto out;
return r;
if (std::string(relpath) == "/") {
r = -EEXIST;
return r;
}
filepath path(relpath);
string name = path.last_dentry();
path.pop_dentry();

r = path_walk(path, &dir, perm, true);
if (r < 0)
goto out;
return r;
if (cct->_conf->client_permissions) {
if (S_ISDIR(in->mode)) {
r = -EPERM;
goto out;
return r;
}
r = may_hardlink(in.get(), perm);
if (r < 0)
goto out;
return r;
r = may_create(dir.get(), perm);
if (r < 0)
goto out;
return r;
}
r = _link(in.get(), dir.get(), name.c_str(), perm);
out:
return r;
}

Expand All @@ -6198,6 +6202,9 @@ int Client::unlink(const char *relpath, const UserPerm& perm)
tout(cct) << "unlink" << std::endl;
tout(cct) << relpath << std::endl;

if (std::string(relpath) == "/")
return -EISDIR;

filepath path(relpath);
string name = path.last_dentry();
path.pop_dentry();
Expand All @@ -6220,6 +6227,9 @@ int Client::rename(const char *relfrom, const char *relto, const UserPerm& perm)
tout(cct) << relfrom << std::endl;
tout(cct) << relto << std::endl;

if (std::string(relfrom) == "/" || std::string(relto) == "/")
return -EBUSY;

filepath from(relfrom);
filepath to(relto);
string fromname = from.last_dentry();
Expand Down Expand Up @@ -6258,6 +6268,9 @@ int Client::mkdir(const char *relpath, mode_t mode, const UserPerm& perm)
tout(cct) << mode << std::endl;
ldout(cct, 10) << "mkdir: " << relpath << dendl;

if (std::string(relpath) == "/")
return -EEXIST;

filepath path(relpath);
string name = path.last_dentry();
path.pop_dentry();
Expand Down Expand Up @@ -6327,6 +6340,10 @@ int Client::rmdir(const char *relpath, const UserPerm& perms)
Mutex::Locker lock(client_lock);
tout(cct) << "rmdir" << std::endl;
tout(cct) << relpath << std::endl;

if (std::string(relpath) == "/")
return -EBUSY;

filepath path(relpath);
string name = path.last_dentry();
path.pop_dentry();
Expand All @@ -6349,6 +6366,10 @@ int Client::mknod(const char *relpath, mode_t mode, const UserPerm& perms, dev_t
tout(cct) << relpath << std::endl;
tout(cct) << mode << std::endl;
tout(cct) << rdev << std::endl;

if (std::string(relpath) == "/")
return -EEXIST;

filepath path(relpath);
string name = path.last_dentry();
path.pop_dentry();
Expand All @@ -6373,6 +6394,9 @@ int Client::symlink(const char *target, const char *relpath, const UserPerm& per
tout(cct) << target << std::endl;
tout(cct) << relpath << std::endl;

if (std::string(relpath) == "/")
return -EEXIST;

filepath path(relpath);
string name = path.last_dentry();
path.pop_dentry();
Expand Down
1 change: 1 addition & 0 deletions src/include/filepath.h
Expand Up @@ -130,6 +130,7 @@ class filepath {

const string& last_dentry() const {
if (bits.empty() && path.length() > 0) parse_bits();
assert(!bits.empty());
return bits[ bits.size()-1 ];
}

Expand Down
38 changes: 38 additions & 0 deletions src/test/libcephfs/test.cc
Expand Up @@ -1773,3 +1773,41 @@ TEST(LibCephFS, ClearSetuid) {
ASSERT_EQ(ceph_ll_close(cmount, fh), 0);
ceph_shutdown(cmount);
}

TEST(LibCephFS, OperationsOnRoot)
{
struct ceph_mount_info *cmount;
ASSERT_EQ(ceph_create(&cmount, NULL), 0);
ASSERT_EQ(ceph_conf_read_file(cmount, NULL), 0);
ASSERT_EQ(0, ceph_conf_parse_env(cmount, NULL));
ASSERT_EQ(ceph_mount(cmount, "/"), 0);

char dirname[32];
sprintf(dirname, "/somedir%x", getpid());

ASSERT_EQ(ceph_mkdir(cmount, dirname, 0755), 0);

ASSERT_EQ(ceph_rmdir(cmount, "/"), -EBUSY);

ASSERT_EQ(ceph_link(cmount, "/", "/"), -EEXIST);
ASSERT_EQ(ceph_link(cmount, dirname, "/"), -EEXIST);
ASSERT_EQ(ceph_link(cmount, "nonExisitingDir", "/"), -ENOENT);

ASSERT_EQ(ceph_unlink(cmount, "/"), -EISDIR);

ASSERT_EQ(ceph_rename(cmount, "/", "/"), -EBUSY);
ASSERT_EQ(ceph_rename(cmount, dirname, "/"), -EBUSY);
ASSERT_EQ(ceph_rename(cmount, "nonExistingDir", "/"), -EBUSY);
ASSERT_EQ(ceph_rename(cmount, "/", dirname), -EBUSY);
ASSERT_EQ(ceph_rename(cmount, "/", "nonExistingDir"), -EBUSY);

ASSERT_EQ(ceph_mkdir(cmount, "/", 0777), -EEXIST);

ASSERT_EQ(ceph_mknod(cmount, "/", 0, 0), -EEXIST);

ASSERT_EQ(ceph_symlink(cmount, "/", "/"), -EEXIST);
ASSERT_EQ(ceph_symlink(cmount, dirname, "/"), -EEXIST);
ASSERT_EQ(ceph_symlink(cmount, "nonExistingDir", "/"), -EEXIST);

ceph_shutdown(cmount);
}

0 comments on commit 08b560c

Please sign in to comment.