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