Beispiel #1
0
asmlinkage long sys_chroot(const char __user * filename)
{
	struct nameidata nd;
	struct fs_struct *fs;
	int error;

	error = __user_walk(filename, LOOKUP_FOLLOW | LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
	if (error)
		goto out;

	error = vfs_permission(d_get_inode_ro(nd.dentry), &nd, MAY_EXEC);
	if (error)
		goto dput_and_out;

	error = -EPERM;
	if (!capable(CAP_SYS_CHROOT))
		goto dput_and_out;

	fs = tx_cache_get_fs(current);

	set_fs_root(fs, nd.mnt, parent(nd.dentry));
	set_fs_altroot();
	error = 0;
dput_and_out:
	path_release(&nd);
out:
	return error;
}
Beispiel #2
0
asmlinkage long sys_chroot(const char * filename)
{
	int error;
	struct nameidata nd;
	char *name;

	name = getname(filename);
	error = PTR_ERR(name);
	if (IS_ERR(name))
		goto out;

	path_init(name, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
		      LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
	error = path_walk(name, &nd);	
	putname(name);
	if (error)
		goto out;

	error = permission(nd.dentry->d_inode,MAY_EXEC);
	if (error)
		goto dput_and_out;

	error = -EPERM;
	if (!capable(CAP_SYS_CHROOT))
		goto dput_and_out;

	set_fs_root(current->fs, nd.mnt, nd.dentry);
	set_fs_altroot();
	error = 0;
dput_and_out:
	path_release(&nd);
out:
	return error;
}
Beispiel #3
0
asmlinkage long sys_chroot(const char __user * filename)
{
	struct nameidata nd;
	int error;

	error = __user_walk(filename, LOOKUP_FOLLOW | LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
	if (error)
		goto out;

	error = permission(nd.dentry->d_inode,MAY_EXEC,&nd);
	if (error)
		goto dput_and_out;

	error = -EPERM;
	if (!capable(CAP_SYS_CHROOT))
		goto dput_and_out;

	set_fs_root(current->fs, nd.mnt, nd.dentry);
	set_fs_altroot();
	error = 0;
dput_and_out:
	path_release(&nd);
out:
	return error;
}
Beispiel #4
0
int
__set_personality(u_long personality)
{
	struct exec_domain	*ep, *oep;

	ep = lookup_exec_domain(personality);
	if(!ep)
		return -ENOEXEC;

	/* if the needed exec domain is already set for this process
	  then we save the works for registering with the new fs
	  and releasing the old fs and exec_domain,
	  we just have to update the personality to this process */
	if (ep == current_thread_info()->exec_domain) {
		current->personality = personality;
		return 0;
	}

	/* when the new fs is already bound to the current process */
	if (atomic_read(&current->fs->count) != 1) {
		struct fs_struct *fsp, *ofsp;

		/* register as client for the new fs by copying it */
		fsp = copy_fs_struct(current->fs);
		if (fsp == NULL) {
			module_put(ep->module);
			return -ENOMEM;
		}

		/* replace the old with the new fs */
		task_lock(current);
		ofsp = current->fs;
		current->fs = fsp;
		task_unlock(current);

		/* quit as a client to the old fs */
		put_fs_struct(ofsp);
	}

	/*
	 * At that point we are guaranteed to be the sole owner of
	 * current->fs.
	 */

	/* replace the old with the new exec_domain */
	current->personality = personality;
	oep = current_thread_info()->exec_domain;
	current_thread_info()->exec_domain = ep;
	set_fs_altroot();

	/* quit as client for the old exec_domain */
	module_put(oep->module);

	return 0;
}
Beispiel #5
0
int
__set_personality(u_long personality)
{
   struct exec_domain   *ep, *oep;

   ep = lookup_exec_domain(personality);
   if (ep == current_thread_info()->exec_domain) {
      current->personality = personality;
      return 0;
   }

   if (atomic_read(&current->fs->count) != 1) {
      struct fs_struct *fsp, *ofsp;

      fsp = copy_fs_struct(current->fs);
      if (fsp == NULL) {
         module_put(ep->module);
         return -ENOMEM;
      }

      task_lock(current);
      ofsp = current->fs;
      current->fs = fsp;
      task_unlock(current);

      put_fs_struct(ofsp);
   }

   /*
    * At that point we are guaranteed to be the sole owner of
    * current->fs.
    */

   current->personality = personality;
   oep = current_thread_info()->exec_domain;
   current_thread_info()->exec_domain = ep;
   set_fs_altroot();

   module_put(oep->module);
   return 0;
}