Skip to content

Commit

Permalink
lsm: adds process attribute getter for Landlock
Browse files Browse the repository at this point in the history
Adds a new getprocattr hook function to the Landlock LSM, which tracks
the landlocked state of the process. This is invoked when user-space
reads /proc/[pid]/attr/domain to determine whether a given process is
sand-boxed using Landlock. When the target process is not sand-boxed,
the result is "none", otherwise the result is empty, as we still need to
decide what kind of domain information is best to provide in "domain".

The hook function also performs an access check. The request is rejected
if the tracing process is the same as the target process, or if the
tracing process domain is not an ancestor to the target process domain.

Adds a new directory for landlock under the process attribute
filesystem, and defines "domain" as a read-only process attribute entry
for landlock.

Signed-off-by: Shervin Oloumi <enlightened@chromium.org>
  • Loading branch information
Shervin Oloumi authored and intel-lab-lkp committed May 18, 2023
1 parent 457391b commit be54dbd
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 2 deletions.
11 changes: 11 additions & 0 deletions fs/proc/base.c
Expand Up @@ -2851,6 +2851,13 @@ static const struct pid_entry apparmor_attr_dir_stuff[] = {
LSM_DIR_OPS(apparmor);
#endif

#ifdef CONFIG_SECURITY_LANDLOCK
static const struct pid_entry landlock_attr_dir_stuff[] = {
ATTR("landlock", "domain", 0444),
};
LSM_DIR_OPS(landlock);
#endif

static const struct pid_entry attr_dir_stuff[] = {
ATTR(NULL, "current", 0666),
ATTR(NULL, "prev", 0444),
Expand All @@ -2866,6 +2873,10 @@ static const struct pid_entry attr_dir_stuff[] = {
DIR("apparmor", 0555,
proc_apparmor_attr_dir_inode_ops, proc_apparmor_attr_dir_ops),
#endif
#ifdef CONFIG_SECURITY_LANDLOCK
DIR("landlock", 0555,
proc_landlock_attr_dir_inode_ops, proc_landlock_attr_dir_ops),
#endif
};

static int proc_attr_dir_readdir(struct file *file, struct dir_context *ctx)
Expand Down
38 changes: 38 additions & 0 deletions security/landlock/fs.c
Expand Up @@ -1280,6 +1280,42 @@ static int hook_file_truncate(struct file *const file)
return -EACCES;
}

/* process attribute interfaces */

/**
* landlock_getprocattr - Landlock process attribute getter
* @task: the object task
* @name: the name of the attribute in /proc/.../attr
* @value: where to put the result
*
* Performs access checks and writes any applicable results to value
*
* Returns the length of the result inside value or an error code
*/
static int landlock_getprocattr(struct task_struct *task, const char *name,
char **value)
{
char *val = "";
int slen;

// If the tracing process is landlocked, ensure its domain is an
// ancestor to the target process domain.
if (landlocked(current))
if (current == task || !task_is_scoped(current, task))
return -EACCES;

// The only supported attribute is "domain".
if (strcmp(name, "domain") != 0)
return -EINVAL;

if (!landlocked(task))
val = "none";

slen = strlen(val);
*value = val;
return slen;
}

static struct security_hook_list landlock_hooks[] __lsm_ro_after_init = {
LSM_HOOK_INIT(inode_free_security, hook_inode_free_security),

Expand All @@ -1302,6 +1338,8 @@ static struct security_hook_list landlock_hooks[] __lsm_ro_after_init = {
LSM_HOOK_INIT(file_alloc_security, hook_file_alloc_security),
LSM_HOOK_INIT(file_open, hook_file_open),
LSM_HOOK_INIT(file_truncate, hook_file_truncate),

LSM_HOOK_INIT(getprocattr, landlock_getprocattr),
};

__init void landlock_add_fs_hooks(void)
Expand Down
1 change: 1 addition & 0 deletions security/landlock/fs.h
Expand Up @@ -13,6 +13,7 @@
#include <linux/init.h>
#include <linux/rcupdate.h>

#include "ptrace.h"
#include "ruleset.h"
#include "setup.h"

Expand Down
4 changes: 2 additions & 2 deletions security/landlock/ptrace.c
Expand Up @@ -47,8 +47,8 @@ static bool domain_scope_le(const struct landlock_ruleset *const parent,
return false;
}

static bool task_is_scoped(const struct task_struct *const parent,
const struct task_struct *const child)
const bool task_is_scoped(const struct task_struct *const parent,
const struct task_struct *const child)
{
bool is_scoped;
const struct landlock_ruleset *dom_parent, *dom_child;
Expand Down
3 changes: 3 additions & 0 deletions security/landlock/ptrace.h
Expand Up @@ -11,4 +11,7 @@

__init void landlock_add_ptrace_hooks(void);

const bool task_is_scoped(const struct task_struct *const parent,
const struct task_struct *const child);

#endif /* _SECURITY_LANDLOCK_PTRACE_H */

0 comments on commit be54dbd

Please sign in to comment.