Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 876ede8b authored by Li Zefan's avatar Li Zefan Committed by Tejun Heo
Browse files

cgroup: restructure the failure path in cgroup_write_event_control()



It uses a single label and checks the validity of each pointer. This
is err-prone, and actually we had a bug because one of the check was
insufficient.

Use multi lables as we do in other places.

v2:
- drop initializations of local variables.

Signed-off-by: default avatarLi Zefan <lizefan@huawei.com>
Signed-off-by: default avatarTejun Heo <tj@kernel.org>
parent e14880f7
Loading
Loading
Loading
Loading
+18 −21
Original line number Diff line number Diff line
@@ -3934,11 +3934,11 @@ static void cgroup_event_ptable_queue_proc(struct file *file,
static int cgroup_write_event_control(struct cgroup *cgrp, struct cftype *cft,
				      const char *buffer)
{
	struct cgroup_event *event = NULL;
	struct cgroup_event *event;
	struct cgroup *cgrp_cfile;
	unsigned int efd, cfd;
	struct file *efile = NULL;
	struct file *cfile = NULL;
	struct file *efile;
	struct file *cfile;
	char *endp;
	int ret;

@@ -3964,31 +3964,31 @@ static int cgroup_write_event_control(struct cgroup *cgrp, struct cftype *cft,
	efile = eventfd_fget(efd);
	if (IS_ERR(efile)) {
		ret = PTR_ERR(efile);
		goto fail;
		goto out_kfree;
	}

	event->eventfd = eventfd_ctx_fileget(efile);
	if (IS_ERR(event->eventfd)) {
		ret = PTR_ERR(event->eventfd);
		goto fail;
		goto out_put_efile;
	}

	cfile = fget(cfd);
	if (!cfile) {
		ret = -EBADF;
		goto fail;
		goto out_put_eventfd;
	}

	/* the process need read permission on control file */
	/* AV: shouldn't we check that it's been opened for read instead? */
	ret = inode_permission(file_inode(cfile), MAY_READ);
	if (ret < 0)
		goto fail;
		goto out_put_cfile;

	event->cft = __file_cft(cfile);
	if (IS_ERR(event->cft)) {
		ret = PTR_ERR(event->cft);
		goto fail;
		goto out_put_cfile;
	}

	/*
@@ -3998,18 +3998,18 @@ static int cgroup_write_event_control(struct cgroup *cgrp, struct cftype *cft,
	cgrp_cfile = __d_cgrp(cfile->f_dentry->d_parent);
	if (cgrp_cfile != cgrp) {
		ret = -EINVAL;
		goto fail;
		goto out_put_cfile;
	}

	if (!event->cft->register_event || !event->cft->unregister_event) {
		ret = -EINVAL;
		goto fail;
		goto out_put_cfile;
	}

	ret = event->cft->register_event(cgrp, event->cft,
			event->eventfd, buffer);
	if (ret)
		goto fail;
		goto out_put_cfile;

	efile->f_op->poll(efile, &event->pt);

@@ -4029,16 +4029,13 @@ static int cgroup_write_event_control(struct cgroup *cgrp, struct cftype *cft,

	return 0;

fail:
	if (cfile)
out_put_cfile:
	fput(cfile);

	if (event && event->eventfd && !IS_ERR(event->eventfd))
out_put_eventfd:
	eventfd_ctx_put(event->eventfd);

	if (!IS_ERR_OR_NULL(efile))
out_put_efile:
	fput(efile);

out_kfree:
	kfree(event);

	return ret;