LSM: SafeSetID: refactor policy parsing
In preparation for changing the policy parsing logic, refactor the line parsing logic to be less verbose and move it into a separate function. Signed-off-by: Jann Horn <jannh@google.com> Signed-off-by: Micah Morton <mortonm@chromium.org>
This commit is contained in:
parent
8068866c4a
commit
78ae7df96d
@ -33,68 +33,50 @@ static struct safesetid_file_entry safesetid_files[] = {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* In the case the input buffer contains one or more invalid UIDs, the kuid_t
|
* In the case the input buffer contains one or more invalid UIDs, the kuid_t
|
||||||
* variables pointed to by 'parent' and 'child' will get updated but this
|
* variables pointed to by @parent and @child will get updated but this
|
||||||
* function will return an error.
|
* function will return an error.
|
||||||
|
* Contents of @buf may be modified.
|
||||||
*/
|
*/
|
||||||
static int parse_safesetid_whitelist_policy(const char __user *buf,
|
static int parse_policy_line(
|
||||||
size_t len,
|
struct file *file, char *buf, kuid_t *parent, kuid_t *child)
|
||||||
kuid_t *parent,
|
|
||||||
kuid_t *child)
|
|
||||||
{
|
{
|
||||||
char *kern_buf;
|
char *child_str;
|
||||||
char *parent_buf;
|
|
||||||
char *child_buf;
|
|
||||||
const char separator[] = ":";
|
|
||||||
int ret;
|
int ret;
|
||||||
size_t first_substring_length;
|
u32 parsed_parent, parsed_child;
|
||||||
long parsed_parent;
|
|
||||||
long parsed_child;
|
|
||||||
|
|
||||||
/* Duplicate string from user memory and NULL-terminate */
|
/* Format of |buf| string should be <UID>:<UID>. */
|
||||||
kern_buf = memdup_user_nul(buf, len);
|
child_str = strchr(buf, ':');
|
||||||
if (IS_ERR(kern_buf))
|
if (child_str == NULL)
|
||||||
return PTR_ERR(kern_buf);
|
return -EINVAL;
|
||||||
|
*child_str = '\0';
|
||||||
|
child_str++;
|
||||||
|
|
||||||
/*
|
ret = kstrtou32(buf, 0, &parsed_parent);
|
||||||
* Format of |buf| string should be <UID>:<UID>.
|
|
||||||
* Find location of ":" in kern_buf (copied from |buf|).
|
|
||||||
*/
|
|
||||||
first_substring_length = strcspn(kern_buf, separator);
|
|
||||||
if (first_substring_length == 0 || first_substring_length == len) {
|
|
||||||
ret = -EINVAL;
|
|
||||||
goto free_kern;
|
|
||||||
}
|
|
||||||
|
|
||||||
parent_buf = kmemdup_nul(kern_buf, first_substring_length, GFP_KERNEL);
|
|
||||||
if (!parent_buf) {
|
|
||||||
ret = -ENOMEM;
|
|
||||||
goto free_kern;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = kstrtol(parent_buf, 0, &parsed_parent);
|
|
||||||
if (ret)
|
if (ret)
|
||||||
goto free_both;
|
return ret;
|
||||||
|
|
||||||
child_buf = kern_buf + first_substring_length + 1;
|
ret = kstrtou32(child_str, 0, &parsed_child);
|
||||||
ret = kstrtol(child_buf, 0, &parsed_child);
|
|
||||||
if (ret)
|
if (ret)
|
||||||
goto free_both;
|
return ret;
|
||||||
|
|
||||||
*parent = make_kuid(current_user_ns(), parsed_parent);
|
*parent = make_kuid(current_user_ns(), parsed_parent);
|
||||||
if (!uid_valid(*parent)) {
|
|
||||||
ret = -EINVAL;
|
|
||||||
goto free_both;
|
|
||||||
}
|
|
||||||
|
|
||||||
*child = make_kuid(current_user_ns(), parsed_child);
|
*child = make_kuid(current_user_ns(), parsed_child);
|
||||||
if (!uid_valid(*child)) {
|
if (!uid_valid(*parent) || !uid_valid(*child))
|
||||||
ret = -EINVAL;
|
return -EINVAL;
|
||||||
goto free_both;
|
|
||||||
}
|
|
||||||
|
|
||||||
free_both:
|
return 0;
|
||||||
kfree(parent_buf);
|
}
|
||||||
free_kern:
|
|
||||||
|
static int parse_safesetid_whitelist_policy(
|
||||||
|
struct file *file, const char __user *buf, size_t len,
|
||||||
|
kuid_t *parent, kuid_t *child)
|
||||||
|
{
|
||||||
|
char *kern_buf = memdup_user_nul(buf, len);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (IS_ERR(kern_buf))
|
||||||
|
return PTR_ERR(kern_buf);
|
||||||
|
ret = parse_policy_line(file, kern_buf, parent, child);
|
||||||
kfree(kern_buf);
|
kfree(kern_buf);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -121,8 +103,8 @@ static ssize_t safesetid_file_write(struct file *file,
|
|||||||
flush_safesetid_whitelist_entries();
|
flush_safesetid_whitelist_entries();
|
||||||
break;
|
break;
|
||||||
case SAFESETID_WHITELIST_ADD:
|
case SAFESETID_WHITELIST_ADD:
|
||||||
ret = parse_safesetid_whitelist_policy(buf, len, &parent,
|
ret = parse_safesetid_whitelist_policy(file, buf, len,
|
||||||
&child);
|
&parent, &child);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user