cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

tomoyo.c (16072B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * security/tomoyo/tomoyo.c
      4 *
      5 * Copyright (C) 2005-2011  NTT DATA CORPORATION
      6 */
      7
      8#include <linux/lsm_hooks.h>
      9#include "common.h"
     10
     11/**
     12 * tomoyo_domain - Get "struct tomoyo_domain_info" for current thread.
     13 *
     14 * Returns pointer to "struct tomoyo_domain_info" for current thread.
     15 */
     16struct tomoyo_domain_info *tomoyo_domain(void)
     17{
     18	struct tomoyo_task *s = tomoyo_task(current);
     19
     20	if (s->old_domain_info && !current->in_execve) {
     21		atomic_dec(&s->old_domain_info->users);
     22		s->old_domain_info = NULL;
     23	}
     24	return s->domain_info;
     25}
     26
     27/**
     28 * tomoyo_cred_prepare - Target for security_prepare_creds().
     29 *
     30 * @new: Pointer to "struct cred".
     31 * @old: Pointer to "struct cred".
     32 * @gfp: Memory allocation flags.
     33 *
     34 * Returns 0.
     35 */
     36static int tomoyo_cred_prepare(struct cred *new, const struct cred *old,
     37			       gfp_t gfp)
     38{
     39	/* Restore old_domain_info saved by previous execve() request. */
     40	struct tomoyo_task *s = tomoyo_task(current);
     41
     42	if (s->old_domain_info && !current->in_execve) {
     43		atomic_dec(&s->domain_info->users);
     44		s->domain_info = s->old_domain_info;
     45		s->old_domain_info = NULL;
     46	}
     47	return 0;
     48}
     49
     50/**
     51 * tomoyo_bprm_committed_creds - Target for security_bprm_committed_creds().
     52 *
     53 * @bprm: Pointer to "struct linux_binprm".
     54 */
     55static void tomoyo_bprm_committed_creds(struct linux_binprm *bprm)
     56{
     57	/* Clear old_domain_info saved by execve() request. */
     58	struct tomoyo_task *s = tomoyo_task(current);
     59
     60	atomic_dec(&s->old_domain_info->users);
     61	s->old_domain_info = NULL;
     62}
     63
     64#ifndef CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER
     65/**
     66 * tomoyo_bprm_creds_for_exec - Target for security_bprm_creds_for_exec().
     67 *
     68 * @bprm: Pointer to "struct linux_binprm".
     69 *
     70 * Returns 0.
     71 */
     72static int tomoyo_bprm_creds_for_exec(struct linux_binprm *bprm)
     73{
     74	/*
     75	 * Load policy if /sbin/tomoyo-init exists and /sbin/init is requested
     76	 * for the first time.
     77	 */
     78	if (!tomoyo_policy_loaded)
     79		tomoyo_load_policy(bprm->filename);
     80	return 0;
     81}
     82#endif
     83
     84/**
     85 * tomoyo_bprm_check_security - Target for security_bprm_check().
     86 *
     87 * @bprm: Pointer to "struct linux_binprm".
     88 *
     89 * Returns 0 on success, negative value otherwise.
     90 */
     91static int tomoyo_bprm_check_security(struct linux_binprm *bprm)
     92{
     93	struct tomoyo_task *s = tomoyo_task(current);
     94
     95	/*
     96	 * Execute permission is checked against pathname passed to execve()
     97	 * using current domain.
     98	 */
     99	if (!s->old_domain_info) {
    100		const int idx = tomoyo_read_lock();
    101		const int err = tomoyo_find_next_domain(bprm);
    102
    103		tomoyo_read_unlock(idx);
    104		return err;
    105	}
    106	/*
    107	 * Read permission is checked against interpreters using next domain.
    108	 */
    109	return tomoyo_check_open_permission(s->domain_info,
    110					    &bprm->file->f_path, O_RDONLY);
    111}
    112
    113/**
    114 * tomoyo_inode_getattr - Target for security_inode_getattr().
    115 *
    116 * @path: Pointer to "struct path".
    117 *
    118 * Returns 0 on success, negative value otherwise.
    119 */
    120static int tomoyo_inode_getattr(const struct path *path)
    121{
    122	return tomoyo_path_perm(TOMOYO_TYPE_GETATTR, path, NULL);
    123}
    124
    125/**
    126 * tomoyo_path_truncate - Target for security_path_truncate().
    127 *
    128 * @path: Pointer to "struct path".
    129 *
    130 * Returns 0 on success, negative value otherwise.
    131 */
    132static int tomoyo_path_truncate(const struct path *path)
    133{
    134	return tomoyo_path_perm(TOMOYO_TYPE_TRUNCATE, path, NULL);
    135}
    136
    137/**
    138 * tomoyo_path_unlink - Target for security_path_unlink().
    139 *
    140 * @parent: Pointer to "struct path".
    141 * @dentry: Pointer to "struct dentry".
    142 *
    143 * Returns 0 on success, negative value otherwise.
    144 */
    145static int tomoyo_path_unlink(const struct path *parent, struct dentry *dentry)
    146{
    147	struct path path = { .mnt = parent->mnt, .dentry = dentry };
    148
    149	return tomoyo_path_perm(TOMOYO_TYPE_UNLINK, &path, NULL);
    150}
    151
    152/**
    153 * tomoyo_path_mkdir - Target for security_path_mkdir().
    154 *
    155 * @parent: Pointer to "struct path".
    156 * @dentry: Pointer to "struct dentry".
    157 * @mode:   DAC permission mode.
    158 *
    159 * Returns 0 on success, negative value otherwise.
    160 */
    161static int tomoyo_path_mkdir(const struct path *parent, struct dentry *dentry,
    162			     umode_t mode)
    163{
    164	struct path path = { .mnt = parent->mnt, .dentry = dentry };
    165
    166	return tomoyo_path_number_perm(TOMOYO_TYPE_MKDIR, &path,
    167				       mode & S_IALLUGO);
    168}
    169
    170/**
    171 * tomoyo_path_rmdir - Target for security_path_rmdir().
    172 *
    173 * @parent: Pointer to "struct path".
    174 * @dentry: Pointer to "struct dentry".
    175 *
    176 * Returns 0 on success, negative value otherwise.
    177 */
    178static int tomoyo_path_rmdir(const struct path *parent, struct dentry *dentry)
    179{
    180	struct path path = { .mnt = parent->mnt, .dentry = dentry };
    181
    182	return tomoyo_path_perm(TOMOYO_TYPE_RMDIR, &path, NULL);
    183}
    184
    185/**
    186 * tomoyo_path_symlink - Target for security_path_symlink().
    187 *
    188 * @parent:   Pointer to "struct path".
    189 * @dentry:   Pointer to "struct dentry".
    190 * @old_name: Symlink's content.
    191 *
    192 * Returns 0 on success, negative value otherwise.
    193 */
    194static int tomoyo_path_symlink(const struct path *parent, struct dentry *dentry,
    195			       const char *old_name)
    196{
    197	struct path path = { .mnt = parent->mnt, .dentry = dentry };
    198
    199	return tomoyo_path_perm(TOMOYO_TYPE_SYMLINK, &path, old_name);
    200}
    201
    202/**
    203 * tomoyo_path_mknod - Target for security_path_mknod().
    204 *
    205 * @parent: Pointer to "struct path".
    206 * @dentry: Pointer to "struct dentry".
    207 * @mode:   DAC permission mode.
    208 * @dev:    Device attributes.
    209 *
    210 * Returns 0 on success, negative value otherwise.
    211 */
    212static int tomoyo_path_mknod(const struct path *parent, struct dentry *dentry,
    213			     umode_t mode, unsigned int dev)
    214{
    215	struct path path = { .mnt = parent->mnt, .dentry = dentry };
    216	int type = TOMOYO_TYPE_CREATE;
    217	const unsigned int perm = mode & S_IALLUGO;
    218
    219	switch (mode & S_IFMT) {
    220	case S_IFCHR:
    221		type = TOMOYO_TYPE_MKCHAR;
    222		break;
    223	case S_IFBLK:
    224		type = TOMOYO_TYPE_MKBLOCK;
    225		break;
    226	default:
    227		goto no_dev;
    228	}
    229	return tomoyo_mkdev_perm(type, &path, perm, dev);
    230 no_dev:
    231	switch (mode & S_IFMT) {
    232	case S_IFIFO:
    233		type = TOMOYO_TYPE_MKFIFO;
    234		break;
    235	case S_IFSOCK:
    236		type = TOMOYO_TYPE_MKSOCK;
    237		break;
    238	}
    239	return tomoyo_path_number_perm(type, &path, perm);
    240}
    241
    242/**
    243 * tomoyo_path_link - Target for security_path_link().
    244 *
    245 * @old_dentry: Pointer to "struct dentry".
    246 * @new_dir:    Pointer to "struct path".
    247 * @new_dentry: Pointer to "struct dentry".
    248 *
    249 * Returns 0 on success, negative value otherwise.
    250 */
    251static int tomoyo_path_link(struct dentry *old_dentry, const struct path *new_dir,
    252			    struct dentry *new_dentry)
    253{
    254	struct path path1 = { .mnt = new_dir->mnt, .dentry = old_dentry };
    255	struct path path2 = { .mnt = new_dir->mnt, .dentry = new_dentry };
    256
    257	return tomoyo_path2_perm(TOMOYO_TYPE_LINK, &path1, &path2);
    258}
    259
    260/**
    261 * tomoyo_path_rename - Target for security_path_rename().
    262 *
    263 * @old_parent: Pointer to "struct path".
    264 * @old_dentry: Pointer to "struct dentry".
    265 * @new_parent: Pointer to "struct path".
    266 * @new_dentry: Pointer to "struct dentry".
    267 * @flags: Rename options.
    268 *
    269 * Returns 0 on success, negative value otherwise.
    270 */
    271static int tomoyo_path_rename(const struct path *old_parent,
    272			      struct dentry *old_dentry,
    273			      const struct path *new_parent,
    274			      struct dentry *new_dentry,
    275			      const unsigned int flags)
    276{
    277	struct path path1 = { .mnt = old_parent->mnt, .dentry = old_dentry };
    278	struct path path2 = { .mnt = new_parent->mnt, .dentry = new_dentry };
    279
    280	if (flags & RENAME_EXCHANGE) {
    281		const int err = tomoyo_path2_perm(TOMOYO_TYPE_RENAME, &path2,
    282				&path1);
    283
    284		if (err)
    285			return err;
    286	}
    287	return tomoyo_path2_perm(TOMOYO_TYPE_RENAME, &path1, &path2);
    288}
    289
    290/**
    291 * tomoyo_file_fcntl - Target for security_file_fcntl().
    292 *
    293 * @file: Pointer to "struct file".
    294 * @cmd:  Command for fcntl().
    295 * @arg:  Argument for @cmd.
    296 *
    297 * Returns 0 on success, negative value otherwise.
    298 */
    299static int tomoyo_file_fcntl(struct file *file, unsigned int cmd,
    300			     unsigned long arg)
    301{
    302	if (!(cmd == F_SETFL && ((arg ^ file->f_flags) & O_APPEND)))
    303		return 0;
    304	return tomoyo_check_open_permission(tomoyo_domain(), &file->f_path,
    305					    O_WRONLY | (arg & O_APPEND));
    306}
    307
    308/**
    309 * tomoyo_file_open - Target for security_file_open().
    310 *
    311 * @f: Pointer to "struct file".
    312 *
    313 * Returns 0 on success, negative value otherwise.
    314 */
    315static int tomoyo_file_open(struct file *f)
    316{
    317	/* Don't check read permission here if called from execve(). */
    318	if (current->in_execve)
    319		return 0;
    320	return tomoyo_check_open_permission(tomoyo_domain(), &f->f_path,
    321					    f->f_flags);
    322}
    323
    324/**
    325 * tomoyo_file_ioctl - Target for security_file_ioctl().
    326 *
    327 * @file: Pointer to "struct file".
    328 * @cmd:  Command for ioctl().
    329 * @arg:  Argument for @cmd.
    330 *
    331 * Returns 0 on success, negative value otherwise.
    332 */
    333static int tomoyo_file_ioctl(struct file *file, unsigned int cmd,
    334			     unsigned long arg)
    335{
    336	return tomoyo_path_number_perm(TOMOYO_TYPE_IOCTL, &file->f_path, cmd);
    337}
    338
    339/**
    340 * tomoyo_path_chmod - Target for security_path_chmod().
    341 *
    342 * @path: Pointer to "struct path".
    343 * @mode: DAC permission mode.
    344 *
    345 * Returns 0 on success, negative value otherwise.
    346 */
    347static int tomoyo_path_chmod(const struct path *path, umode_t mode)
    348{
    349	return tomoyo_path_number_perm(TOMOYO_TYPE_CHMOD, path,
    350				       mode & S_IALLUGO);
    351}
    352
    353/**
    354 * tomoyo_path_chown - Target for security_path_chown().
    355 *
    356 * @path: Pointer to "struct path".
    357 * @uid:  Owner ID.
    358 * @gid:  Group ID.
    359 *
    360 * Returns 0 on success, negative value otherwise.
    361 */
    362static int tomoyo_path_chown(const struct path *path, kuid_t uid, kgid_t gid)
    363{
    364	int error = 0;
    365
    366	if (uid_valid(uid))
    367		error = tomoyo_path_number_perm(TOMOYO_TYPE_CHOWN, path,
    368						from_kuid(&init_user_ns, uid));
    369	if (!error && gid_valid(gid))
    370		error = tomoyo_path_number_perm(TOMOYO_TYPE_CHGRP, path,
    371						from_kgid(&init_user_ns, gid));
    372	return error;
    373}
    374
    375/**
    376 * tomoyo_path_chroot - Target for security_path_chroot().
    377 *
    378 * @path: Pointer to "struct path".
    379 *
    380 * Returns 0 on success, negative value otherwise.
    381 */
    382static int tomoyo_path_chroot(const struct path *path)
    383{
    384	return tomoyo_path_perm(TOMOYO_TYPE_CHROOT, path, NULL);
    385}
    386
    387/**
    388 * tomoyo_sb_mount - Target for security_sb_mount().
    389 *
    390 * @dev_name: Name of device file. Maybe NULL.
    391 * @path:     Pointer to "struct path".
    392 * @type:     Name of filesystem type. Maybe NULL.
    393 * @flags:    Mount options.
    394 * @data:     Optional data. Maybe NULL.
    395 *
    396 * Returns 0 on success, negative value otherwise.
    397 */
    398static int tomoyo_sb_mount(const char *dev_name, const struct path *path,
    399			   const char *type, unsigned long flags, void *data)
    400{
    401	return tomoyo_mount_permission(dev_name, path, type, flags, data);
    402}
    403
    404/**
    405 * tomoyo_sb_umount - Target for security_sb_umount().
    406 *
    407 * @mnt:   Pointer to "struct vfsmount".
    408 * @flags: Unmount options.
    409 *
    410 * Returns 0 on success, negative value otherwise.
    411 */
    412static int tomoyo_sb_umount(struct vfsmount *mnt, int flags)
    413{
    414	struct path path = { .mnt = mnt, .dentry = mnt->mnt_root };
    415
    416	return tomoyo_path_perm(TOMOYO_TYPE_UMOUNT, &path, NULL);
    417}
    418
    419/**
    420 * tomoyo_sb_pivotroot - Target for security_sb_pivotroot().
    421 *
    422 * @old_path: Pointer to "struct path".
    423 * @new_path: Pointer to "struct path".
    424 *
    425 * Returns 0 on success, negative value otherwise.
    426 */
    427static int tomoyo_sb_pivotroot(const struct path *old_path, const struct path *new_path)
    428{
    429	return tomoyo_path2_perm(TOMOYO_TYPE_PIVOT_ROOT, new_path, old_path);
    430}
    431
    432/**
    433 * tomoyo_socket_listen - Check permission for listen().
    434 *
    435 * @sock:    Pointer to "struct socket".
    436 * @backlog: Backlog parameter.
    437 *
    438 * Returns 0 on success, negative value otherwise.
    439 */
    440static int tomoyo_socket_listen(struct socket *sock, int backlog)
    441{
    442	return tomoyo_socket_listen_permission(sock);
    443}
    444
    445/**
    446 * tomoyo_socket_connect - Check permission for connect().
    447 *
    448 * @sock:     Pointer to "struct socket".
    449 * @addr:     Pointer to "struct sockaddr".
    450 * @addr_len: Size of @addr.
    451 *
    452 * Returns 0 on success, negative value otherwise.
    453 */
    454static int tomoyo_socket_connect(struct socket *sock, struct sockaddr *addr,
    455				 int addr_len)
    456{
    457	return tomoyo_socket_connect_permission(sock, addr, addr_len);
    458}
    459
    460/**
    461 * tomoyo_socket_bind - Check permission for bind().
    462 *
    463 * @sock:     Pointer to "struct socket".
    464 * @addr:     Pointer to "struct sockaddr".
    465 * @addr_len: Size of @addr.
    466 *
    467 * Returns 0 on success, negative value otherwise.
    468 */
    469static int tomoyo_socket_bind(struct socket *sock, struct sockaddr *addr,
    470			      int addr_len)
    471{
    472	return tomoyo_socket_bind_permission(sock, addr, addr_len);
    473}
    474
    475/**
    476 * tomoyo_socket_sendmsg - Check permission for sendmsg().
    477 *
    478 * @sock: Pointer to "struct socket".
    479 * @msg:  Pointer to "struct msghdr".
    480 * @size: Size of message.
    481 *
    482 * Returns 0 on success, negative value otherwise.
    483 */
    484static int tomoyo_socket_sendmsg(struct socket *sock, struct msghdr *msg,
    485				 int size)
    486{
    487	return tomoyo_socket_sendmsg_permission(sock, msg, size);
    488}
    489
    490struct lsm_blob_sizes tomoyo_blob_sizes __lsm_ro_after_init = {
    491	.lbs_task = sizeof(struct tomoyo_task),
    492};
    493
    494/**
    495 * tomoyo_task_alloc - Target for security_task_alloc().
    496 *
    497 * @task:        Pointer to "struct task_struct".
    498 * @clone_flags: clone() flags.
    499 *
    500 * Returns 0.
    501 */
    502static int tomoyo_task_alloc(struct task_struct *task,
    503			     unsigned long clone_flags)
    504{
    505	struct tomoyo_task *old = tomoyo_task(current);
    506	struct tomoyo_task *new = tomoyo_task(task);
    507
    508	new->domain_info = old->domain_info;
    509	atomic_inc(&new->domain_info->users);
    510	new->old_domain_info = NULL;
    511	return 0;
    512}
    513
    514/**
    515 * tomoyo_task_free - Target for security_task_free().
    516 *
    517 * @task: Pointer to "struct task_struct".
    518 */
    519static void tomoyo_task_free(struct task_struct *task)
    520{
    521	struct tomoyo_task *s = tomoyo_task(task);
    522
    523	if (s->domain_info) {
    524		atomic_dec(&s->domain_info->users);
    525		s->domain_info = NULL;
    526	}
    527	if (s->old_domain_info) {
    528		atomic_dec(&s->old_domain_info->users);
    529		s->old_domain_info = NULL;
    530	}
    531}
    532
    533/*
    534 * tomoyo_security_ops is a "struct security_operations" which is used for
    535 * registering TOMOYO.
    536 */
    537static struct security_hook_list tomoyo_hooks[] __lsm_ro_after_init = {
    538	LSM_HOOK_INIT(cred_prepare, tomoyo_cred_prepare),
    539	LSM_HOOK_INIT(bprm_committed_creds, tomoyo_bprm_committed_creds),
    540	LSM_HOOK_INIT(task_alloc, tomoyo_task_alloc),
    541	LSM_HOOK_INIT(task_free, tomoyo_task_free),
    542#ifndef CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER
    543	LSM_HOOK_INIT(bprm_creds_for_exec, tomoyo_bprm_creds_for_exec),
    544#endif
    545	LSM_HOOK_INIT(bprm_check_security, tomoyo_bprm_check_security),
    546	LSM_HOOK_INIT(file_fcntl, tomoyo_file_fcntl),
    547	LSM_HOOK_INIT(file_open, tomoyo_file_open),
    548	LSM_HOOK_INIT(path_truncate, tomoyo_path_truncate),
    549	LSM_HOOK_INIT(path_unlink, tomoyo_path_unlink),
    550	LSM_HOOK_INIT(path_mkdir, tomoyo_path_mkdir),
    551	LSM_HOOK_INIT(path_rmdir, tomoyo_path_rmdir),
    552	LSM_HOOK_INIT(path_symlink, tomoyo_path_symlink),
    553	LSM_HOOK_INIT(path_mknod, tomoyo_path_mknod),
    554	LSM_HOOK_INIT(path_link, tomoyo_path_link),
    555	LSM_HOOK_INIT(path_rename, tomoyo_path_rename),
    556	LSM_HOOK_INIT(inode_getattr, tomoyo_inode_getattr),
    557	LSM_HOOK_INIT(file_ioctl, tomoyo_file_ioctl),
    558	LSM_HOOK_INIT(path_chmod, tomoyo_path_chmod),
    559	LSM_HOOK_INIT(path_chown, tomoyo_path_chown),
    560	LSM_HOOK_INIT(path_chroot, tomoyo_path_chroot),
    561	LSM_HOOK_INIT(sb_mount, tomoyo_sb_mount),
    562	LSM_HOOK_INIT(sb_umount, tomoyo_sb_umount),
    563	LSM_HOOK_INIT(sb_pivotroot, tomoyo_sb_pivotroot),
    564	LSM_HOOK_INIT(socket_bind, tomoyo_socket_bind),
    565	LSM_HOOK_INIT(socket_connect, tomoyo_socket_connect),
    566	LSM_HOOK_INIT(socket_listen, tomoyo_socket_listen),
    567	LSM_HOOK_INIT(socket_sendmsg, tomoyo_socket_sendmsg),
    568};
    569
    570/* Lock for GC. */
    571DEFINE_SRCU(tomoyo_ss);
    572
    573int tomoyo_enabled __lsm_ro_after_init = 1;
    574
    575/**
    576 * tomoyo_init - Register TOMOYO Linux as a LSM module.
    577 *
    578 * Returns 0.
    579 */
    580static int __init tomoyo_init(void)
    581{
    582	struct tomoyo_task *s = tomoyo_task(current);
    583
    584	/* register ourselves with the security framework */
    585	security_add_hooks(tomoyo_hooks, ARRAY_SIZE(tomoyo_hooks), "tomoyo");
    586	pr_info("TOMOYO Linux initialized\n");
    587	s->domain_info = &tomoyo_kernel_domain;
    588	atomic_inc(&tomoyo_kernel_domain.users);
    589	s->old_domain_info = NULL;
    590	tomoyo_mm_init();
    591
    592	return 0;
    593}
    594
    595DEFINE_LSM(tomoyo) = {
    596	.name = "tomoyo",
    597	.enabled = &tomoyo_enabled,
    598	.flags = LSM_FLAG_LEGACY_MAJOR,
    599	.blobs = &tomoyo_blob_sizes,
    600	.init = tomoyo_init,
    601};