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