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

Commit d383d484 authored by Luis R. Rodriguez's avatar Luis R. Rodriguez Committed by Linus Torvalds
Browse files

sysctl: fold sysctl_writes_strict checks into helper

The mode sysctl_writes_strict positional checks keep being copy and pasted
as we add new proc handlers.  Just add a helper to avoid code duplication.

Link: http://lkml.kernel.org/r/20170519033554.18592-4-mcgrof@kernel.org


Signed-off-by: default avatarLuis R. Rodriguez <mcgrof@kernel.org>
Suggested-by: default avatarKees Cook <keescook@chromium.org>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent a19ac337
Loading
Loading
Loading
Loading
+32 −24
Original line number Diff line number Diff line
@@ -1970,6 +1970,32 @@ static void warn_sysctl_write(struct ctl_table *table)
		current->comm, table->procname);
}

/**
 * proc_first_pos_non_zero_ignore - check if firs position is allowed
 * @ppos: file position
 * @table: the sysctl table
 *
 * Returns true if the first position is non-zero and the sysctl_writes_strict
 * mode indicates this is not allowed for numeric input types. String proc
 * hadlers can ignore the return value.
 */
static bool proc_first_pos_non_zero_ignore(loff_t *ppos,
					   struct ctl_table *table)
{
	if (!*ppos)
		return false;

	switch (sysctl_writes_strict) {
	case SYSCTL_WRITES_STRICT:
		return true;
	case SYSCTL_WRITES_WARN:
		warn_sysctl_write(table);
		return false;
	default:
		return false;
	}
}

/**
 * proc_dostring - read a string sysctl
 * @table: the sysctl table
@@ -1990,8 +2016,8 @@ static void warn_sysctl_write(struct ctl_table *table)
int proc_dostring(struct ctl_table *table, int write,
		  void __user *buffer, size_t *lenp, loff_t *ppos)
{
	if (write && *ppos && sysctl_writes_strict == SYSCTL_WRITES_WARN)
		warn_sysctl_write(table);
	if (write)
		proc_first_pos_non_zero_ignore(ppos, table);

	return _proc_do_string((char *)(table->data), table->maxlen, write,
			       (char __user *)buffer, lenp, ppos);
@@ -2193,17 +2219,8 @@ static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table,
		conv = do_proc_dointvec_conv;

	if (write) {
		if (*ppos) {
			switch (sysctl_writes_strict) {
			case SYSCTL_WRITES_STRICT:
		if (proc_first_pos_non_zero_ignore(ppos, table))
			goto out;
			case SYSCTL_WRITES_WARN:
				warn_sysctl_write(table);
				break;
			default:
				break;
			}
		}

		if (left > PAGE_SIZE - 1)
			left = PAGE_SIZE - 1;
@@ -2468,17 +2485,8 @@ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int
	left = *lenp;

	if (write) {
		if (*ppos) {
			switch (sysctl_writes_strict) {
			case SYSCTL_WRITES_STRICT:
		if (proc_first_pos_non_zero_ignore(ppos, table))
			goto out;
			case SYSCTL_WRITES_WARN:
				warn_sysctl_write(table);
				break;
			default:
				break;
			}
		}

		if (left > PAGE_SIZE - 1)
			left = PAGE_SIZE - 1;