.. | .. |
---|
32 | 32 | return !memcmp(policy1, policy2, fscrypt_policy_size(policy1)); |
---|
33 | 33 | } |
---|
34 | 34 | |
---|
| 35 | +static const union fscrypt_policy * |
---|
| 36 | +fscrypt_get_dummy_policy(struct super_block *sb) |
---|
| 37 | +{ |
---|
| 38 | + if (!sb->s_cop->get_dummy_policy) |
---|
| 39 | + return NULL; |
---|
| 40 | + return sb->s_cop->get_dummy_policy(sb); |
---|
| 41 | +} |
---|
| 42 | + |
---|
35 | 43 | static bool fscrypt_valid_enc_modes(u32 contents_mode, u32 filenames_mode) |
---|
36 | 44 | { |
---|
37 | 45 | if (contents_mode == FSCRYPT_MODE_AES_256_XTS && |
---|
.. | .. |
---|
167 | 175 | return false; |
---|
168 | 176 | } |
---|
169 | 177 | |
---|
170 | | - if (policy->flags & ~FSCRYPT_POLICY_FLAGS_VALID) { |
---|
| 178 | + if (policy->flags & ~(FSCRYPT_POLICY_FLAGS_PAD_MASK | |
---|
| 179 | + FSCRYPT_POLICY_FLAG_DIRECT_KEY | |
---|
| 180 | + FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64 | |
---|
| 181 | + FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32)) { |
---|
171 | 182 | fscrypt_warn(inode, "Unsupported encryption flags (0x%02x)", |
---|
172 | 183 | policy->flags); |
---|
173 | 184 | return false; |
---|
.. | .. |
---|
236 | 247 | } |
---|
237 | 248 | |
---|
238 | 249 | /** |
---|
239 | | - * fscrypt_new_context_from_policy() - create a new fscrypt_context from |
---|
240 | | - * an fscrypt_policy |
---|
| 250 | + * fscrypt_new_context() - create a new fscrypt_context |
---|
241 | 251 | * @ctx_u: output context |
---|
242 | 252 | * @policy_u: input policy |
---|
| 253 | + * @nonce: nonce to use |
---|
243 | 254 | * |
---|
244 | 255 | * Create an fscrypt_context for an inode that is being assigned the given |
---|
245 | | - * encryption policy. A new nonce is randomly generated. |
---|
| 256 | + * encryption policy. @nonce must be a new random nonce. |
---|
246 | 257 | * |
---|
247 | 258 | * Return: the size of the new context in bytes. |
---|
248 | 259 | */ |
---|
249 | | -static int fscrypt_new_context_from_policy(union fscrypt_context *ctx_u, |
---|
250 | | - const union fscrypt_policy *policy_u) |
---|
| 260 | +static int fscrypt_new_context(union fscrypt_context *ctx_u, |
---|
| 261 | + const union fscrypt_policy *policy_u, |
---|
| 262 | + const u8 nonce[FSCRYPT_FILE_NONCE_SIZE]) |
---|
251 | 263 | { |
---|
252 | 264 | memset(ctx_u, 0, sizeof(*ctx_u)); |
---|
253 | 265 | |
---|
.. | .. |
---|
265 | 277 | memcpy(ctx->master_key_descriptor, |
---|
266 | 278 | policy->master_key_descriptor, |
---|
267 | 279 | sizeof(ctx->master_key_descriptor)); |
---|
268 | | - get_random_bytes(ctx->nonce, sizeof(ctx->nonce)); |
---|
| 280 | + memcpy(ctx->nonce, nonce, FSCRYPT_FILE_NONCE_SIZE); |
---|
269 | 281 | return sizeof(*ctx); |
---|
270 | 282 | } |
---|
271 | 283 | case FSCRYPT_POLICY_V2: { |
---|
.. | .. |
---|
281 | 293 | memcpy(ctx->master_key_identifier, |
---|
282 | 294 | policy->master_key_identifier, |
---|
283 | 295 | sizeof(ctx->master_key_identifier)); |
---|
284 | | - get_random_bytes(ctx->nonce, sizeof(ctx->nonce)); |
---|
| 296 | + memcpy(ctx->nonce, nonce, FSCRYPT_FILE_NONCE_SIZE); |
---|
285 | 297 | return sizeof(*ctx); |
---|
286 | 298 | } |
---|
287 | 299 | } |
---|
.. | .. |
---|
357 | 369 | union fscrypt_context ctx; |
---|
358 | 370 | int ret; |
---|
359 | 371 | |
---|
360 | | - ci = READ_ONCE(inode->i_crypt_info); |
---|
| 372 | + ci = fscrypt_get_info(inode); |
---|
361 | 373 | if (ci) { |
---|
362 | 374 | /* key available, use the cached policy */ |
---|
363 | 375 | *policy = ci->ci_policy; |
---|
.. | .. |
---|
377 | 389 | static int set_encryption_policy(struct inode *inode, |
---|
378 | 390 | const union fscrypt_policy *policy) |
---|
379 | 391 | { |
---|
| 392 | + u8 nonce[FSCRYPT_FILE_NONCE_SIZE]; |
---|
380 | 393 | union fscrypt_context ctx; |
---|
381 | 394 | int ctxsize; |
---|
382 | 395 | int err; |
---|
.. | .. |
---|
414 | 427 | return -EINVAL; |
---|
415 | 428 | } |
---|
416 | 429 | |
---|
417 | | - ctxsize = fscrypt_new_context_from_policy(&ctx, policy); |
---|
| 430 | + get_random_bytes(nonce, FSCRYPT_FILE_NONCE_SIZE); |
---|
| 431 | + ctxsize = fscrypt_new_context(&ctx, policy, nonce); |
---|
418 | 432 | |
---|
419 | 433 | return inode->i_sb->s_cop->set_context(inode, &ctx, ctxsize, NULL); |
---|
420 | 434 | } |
---|
.. | .. |
---|
548 | 562 | if (!fscrypt_context_is_valid(&ctx, ret)) |
---|
549 | 563 | return -EINVAL; |
---|
550 | 564 | if (copy_to_user(arg, fscrypt_context_nonce(&ctx), |
---|
551 | | - FS_KEY_DERIVATION_NONCE_SIZE)) |
---|
| 565 | + FSCRYPT_FILE_NONCE_SIZE)) |
---|
552 | 566 | return -EFAULT; |
---|
553 | 567 | return 0; |
---|
554 | 568 | } |
---|
.. | .. |
---|
576 | 590 | int fscrypt_has_permitted_context(struct inode *parent, struct inode *child) |
---|
577 | 591 | { |
---|
578 | 592 | union fscrypt_policy parent_policy, child_policy; |
---|
579 | | - int err; |
---|
| 593 | + int err, err1, err2; |
---|
580 | 594 | |
---|
581 | 595 | /* No restrictions on file types which are never encrypted */ |
---|
582 | 596 | if (!S_ISREG(child->i_mode) && !S_ISDIR(child->i_mode) && |
---|
.. | .. |
---|
606 | 620 | * In any case, if an unexpected error occurs, fall back to "forbidden". |
---|
607 | 621 | */ |
---|
608 | 622 | |
---|
609 | | - err = fscrypt_get_encryption_info(parent); |
---|
| 623 | + err = fscrypt_get_encryption_info(parent, true); |
---|
610 | 624 | if (err) |
---|
611 | 625 | return 0; |
---|
612 | | - err = fscrypt_get_encryption_info(child); |
---|
| 626 | + err = fscrypt_get_encryption_info(child, true); |
---|
613 | 627 | if (err) |
---|
614 | 628 | return 0; |
---|
615 | 629 | |
---|
616 | | - err = fscrypt_get_policy(parent, &parent_policy); |
---|
617 | | - if (err) |
---|
618 | | - return 0; |
---|
| 630 | + err1 = fscrypt_get_policy(parent, &parent_policy); |
---|
| 631 | + err2 = fscrypt_get_policy(child, &child_policy); |
---|
619 | 632 | |
---|
620 | | - err = fscrypt_get_policy(child, &child_policy); |
---|
621 | | - if (err) |
---|
| 633 | + /* |
---|
| 634 | + * Allow the case where the parent and child both have an unrecognized |
---|
| 635 | + * encryption policy, so that files with an unrecognized encryption |
---|
| 636 | + * policy can be deleted. |
---|
| 637 | + */ |
---|
| 638 | + if (err1 == -EINVAL && err2 == -EINVAL) |
---|
| 639 | + return 1; |
---|
| 640 | + |
---|
| 641 | + if (err1 || err2) |
---|
622 | 642 | return 0; |
---|
623 | 643 | |
---|
624 | 644 | return fscrypt_policies_equal(&parent_policy, &child_policy); |
---|
625 | 645 | } |
---|
626 | 646 | EXPORT_SYMBOL(fscrypt_has_permitted_context); |
---|
627 | 647 | |
---|
| 648 | +/* |
---|
| 649 | + * Return the encryption policy that new files in the directory will inherit, or |
---|
| 650 | + * NULL if none, or an ERR_PTR() on error. If the directory is encrypted, also |
---|
| 651 | + * ensure that its key is set up, so that the new filename can be encrypted. |
---|
| 652 | + */ |
---|
| 653 | +const union fscrypt_policy *fscrypt_policy_to_inherit(struct inode *dir) |
---|
| 654 | +{ |
---|
| 655 | + int err; |
---|
| 656 | + |
---|
| 657 | + if (IS_ENCRYPTED(dir)) { |
---|
| 658 | + err = fscrypt_require_key(dir); |
---|
| 659 | + if (err) |
---|
| 660 | + return ERR_PTR(err); |
---|
| 661 | + return &dir->i_crypt_info->ci_policy; |
---|
| 662 | + } |
---|
| 663 | + |
---|
| 664 | + return fscrypt_get_dummy_policy(dir->i_sb); |
---|
| 665 | +} |
---|
| 666 | + |
---|
628 | 667 | /** |
---|
629 | | - * fscrypt_inherit_context() - Sets a child context from its parent |
---|
630 | | - * @parent: Parent inode from which the context is inherited. |
---|
631 | | - * @child: Child inode that inherits the context from @parent. |
---|
632 | | - * @fs_data: private data given by FS. |
---|
633 | | - * @preload: preload child i_crypt_info if true |
---|
| 668 | + * fscrypt_set_context() - Set the fscrypt context of a new inode |
---|
| 669 | + * @inode: a new inode |
---|
| 670 | + * @fs_data: private data given by FS and passed to ->set_context() |
---|
| 671 | + * |
---|
| 672 | + * This should be called after fscrypt_prepare_new_inode(), generally during a |
---|
| 673 | + * filesystem transaction. Everything here must be %GFP_NOFS-safe. |
---|
634 | 674 | * |
---|
635 | 675 | * Return: 0 on success, -errno on failure |
---|
636 | 676 | */ |
---|
637 | | -int fscrypt_inherit_context(struct inode *parent, struct inode *child, |
---|
638 | | - void *fs_data, bool preload) |
---|
| 677 | +int fscrypt_set_context(struct inode *inode, void *fs_data) |
---|
639 | 678 | { |
---|
| 679 | + struct fscrypt_info *ci = inode->i_crypt_info; |
---|
640 | 680 | union fscrypt_context ctx; |
---|
641 | 681 | int ctxsize; |
---|
642 | | - struct fscrypt_info *ci; |
---|
643 | | - int res; |
---|
644 | 682 | |
---|
645 | | - res = fscrypt_get_encryption_info(parent); |
---|
646 | | - if (res < 0) |
---|
647 | | - return res; |
---|
648 | | - |
---|
649 | | - ci = READ_ONCE(parent->i_crypt_info); |
---|
650 | | - if (ci == NULL) |
---|
| 683 | + /* fscrypt_prepare_new_inode() should have set up the key already. */ |
---|
| 684 | + if (WARN_ON_ONCE(!ci)) |
---|
651 | 685 | return -ENOKEY; |
---|
652 | 686 | |
---|
653 | | - ctxsize = fscrypt_new_context_from_policy(&ctx, &ci->ci_policy); |
---|
654 | | - |
---|
655 | 687 | BUILD_BUG_ON(sizeof(ctx) != FSCRYPT_SET_CONTEXT_MAX_SIZE); |
---|
656 | | - res = parent->i_sb->s_cop->set_context(child, &ctx, ctxsize, fs_data); |
---|
657 | | - if (res) |
---|
658 | | - return res; |
---|
659 | | - return preload ? fscrypt_get_encryption_info(child): 0; |
---|
| 688 | + ctxsize = fscrypt_new_context(&ctx, &ci->ci_policy, ci->ci_nonce); |
---|
| 689 | + |
---|
| 690 | + /* |
---|
| 691 | + * This may be the first time the inode number is available, so do any |
---|
| 692 | + * delayed key setup that requires the inode number. |
---|
| 693 | + */ |
---|
| 694 | + if (ci->ci_policy.version == FSCRYPT_POLICY_V2 && |
---|
| 695 | + (ci->ci_policy.v2.flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32)) |
---|
| 696 | + fscrypt_hash_inode_number(ci, ci->ci_master_key); |
---|
| 697 | + |
---|
| 698 | + return inode->i_sb->s_cop->set_context(inode, &ctx, ctxsize, fs_data); |
---|
660 | 699 | } |
---|
661 | | -EXPORT_SYMBOL(fscrypt_inherit_context); |
---|
| 700 | +EXPORT_SYMBOL_GPL(fscrypt_set_context); |
---|
662 | 701 | |
---|
663 | 702 | /** |
---|
664 | 703 | * fscrypt_set_test_dummy_encryption() - handle '-o test_dummy_encryption' |
---|
665 | 704 | * @sb: the filesystem on which test_dummy_encryption is being specified |
---|
666 | | - * @arg: the argument to the test_dummy_encryption option. |
---|
667 | | - * If no argument was specified, then @arg->from == NULL. |
---|
668 | | - * @dummy_ctx: the filesystem's current dummy context (input/output, see below) |
---|
| 705 | + * @arg: the argument to the test_dummy_encryption option. May be NULL. |
---|
| 706 | + * @dummy_policy: the filesystem's current dummy policy (input/output, see |
---|
| 707 | + * below) |
---|
669 | 708 | * |
---|
670 | 709 | * Handle the test_dummy_encryption mount option by creating a dummy encryption |
---|
671 | | - * context, saving it in @dummy_ctx, and adding the corresponding dummy |
---|
672 | | - * encryption key to the filesystem. If the @dummy_ctx is already set, then |
---|
| 710 | + * policy, saving it in @dummy_policy, and adding the corresponding dummy |
---|
| 711 | + * encryption key to the filesystem. If the @dummy_policy is already set, then |
---|
673 | 712 | * instead validate that it matches @arg. Don't support changing it via |
---|
674 | 713 | * remount, as that is difficult to do safely. |
---|
675 | 714 | * |
---|
676 | | - * The reason we use an fscrypt_context rather than an fscrypt_policy is because |
---|
677 | | - * we mustn't generate a new nonce each time we access a dummy-encrypted |
---|
678 | | - * directory, as that would change the way filenames are encrypted. |
---|
679 | | - * |
---|
680 | | - * Return: 0 on success (dummy context set, or the same context is already set); |
---|
681 | | - * -EEXIST if a different dummy context is already set; |
---|
| 715 | + * Return: 0 on success (dummy policy set, or the same policy is already set); |
---|
| 716 | + * -EEXIST if a different dummy policy is already set; |
---|
682 | 717 | * or another -errno value. |
---|
683 | 718 | */ |
---|
684 | | -int fscrypt_set_test_dummy_encryption(struct super_block *sb, |
---|
685 | | - const substring_t *arg, |
---|
686 | | - struct fscrypt_dummy_context *dummy_ctx) |
---|
| 719 | +int fscrypt_set_test_dummy_encryption(struct super_block *sb, const char *arg, |
---|
| 720 | + struct fscrypt_dummy_policy *dummy_policy) |
---|
687 | 721 | { |
---|
688 | | - const char *argstr = "v2"; |
---|
689 | | - const char *argstr_to_free = NULL; |
---|
690 | 722 | struct fscrypt_key_specifier key_spec = { 0 }; |
---|
691 | 723 | int version; |
---|
692 | | - union fscrypt_context *ctx = NULL; |
---|
| 724 | + union fscrypt_policy *policy = NULL; |
---|
693 | 725 | int err; |
---|
694 | 726 | |
---|
695 | | - if (arg->from) { |
---|
696 | | - argstr = argstr_to_free = match_strdup(arg); |
---|
697 | | - if (!argstr) |
---|
698 | | - return -ENOMEM; |
---|
699 | | - } |
---|
| 727 | + if (!arg) |
---|
| 728 | + arg = "v2"; |
---|
700 | 729 | |
---|
701 | | - if (!strcmp(argstr, "v1")) { |
---|
702 | | - version = FSCRYPT_CONTEXT_V1; |
---|
| 730 | + if (!strcmp(arg, "v1")) { |
---|
| 731 | + version = FSCRYPT_POLICY_V1; |
---|
703 | 732 | key_spec.type = FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR; |
---|
704 | 733 | memset(key_spec.u.descriptor, 0x42, |
---|
705 | 734 | FSCRYPT_KEY_DESCRIPTOR_SIZE); |
---|
706 | | - } else if (!strcmp(argstr, "v2")) { |
---|
707 | | - version = FSCRYPT_CONTEXT_V2; |
---|
| 735 | + } else if (!strcmp(arg, "v2")) { |
---|
| 736 | + version = FSCRYPT_POLICY_V2; |
---|
708 | 737 | key_spec.type = FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER; |
---|
709 | 738 | /* key_spec.u.identifier gets filled in when adding the key */ |
---|
710 | 739 | } else { |
---|
.. | .. |
---|
712 | 741 | goto out; |
---|
713 | 742 | } |
---|
714 | 743 | |
---|
715 | | - if (dummy_ctx->ctx) { |
---|
716 | | - /* |
---|
717 | | - * Note: if we ever make test_dummy_encryption support |
---|
718 | | - * specifying other encryption settings, such as the encryption |
---|
719 | | - * modes, we'll need to compare those settings here. |
---|
720 | | - */ |
---|
721 | | - if (dummy_ctx->ctx->version == version) |
---|
722 | | - err = 0; |
---|
723 | | - else |
---|
724 | | - err = -EEXIST; |
---|
725 | | - goto out; |
---|
726 | | - } |
---|
727 | | - |
---|
728 | | - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); |
---|
729 | | - if (!ctx) { |
---|
| 744 | + policy = kzalloc(sizeof(*policy), GFP_KERNEL); |
---|
| 745 | + if (!policy) { |
---|
730 | 746 | err = -ENOMEM; |
---|
731 | 747 | goto out; |
---|
732 | 748 | } |
---|
.. | .. |
---|
735 | 751 | if (err) |
---|
736 | 752 | goto out; |
---|
737 | 753 | |
---|
738 | | - ctx->version = version; |
---|
739 | | - switch (ctx->version) { |
---|
740 | | - case FSCRYPT_CONTEXT_V1: |
---|
741 | | - ctx->v1.contents_encryption_mode = FSCRYPT_MODE_AES_256_XTS; |
---|
742 | | - ctx->v1.filenames_encryption_mode = FSCRYPT_MODE_AES_256_CTS; |
---|
743 | | - memcpy(ctx->v1.master_key_descriptor, key_spec.u.descriptor, |
---|
| 754 | + policy->version = version; |
---|
| 755 | + switch (policy->version) { |
---|
| 756 | + case FSCRYPT_POLICY_V1: |
---|
| 757 | + policy->v1.contents_encryption_mode = FSCRYPT_MODE_AES_256_XTS; |
---|
| 758 | + policy->v1.filenames_encryption_mode = FSCRYPT_MODE_AES_256_CTS; |
---|
| 759 | + memcpy(policy->v1.master_key_descriptor, key_spec.u.descriptor, |
---|
744 | 760 | FSCRYPT_KEY_DESCRIPTOR_SIZE); |
---|
745 | 761 | break; |
---|
746 | | - case FSCRYPT_CONTEXT_V2: |
---|
747 | | - ctx->v2.contents_encryption_mode = FSCRYPT_MODE_AES_256_XTS; |
---|
748 | | - ctx->v2.filenames_encryption_mode = FSCRYPT_MODE_AES_256_CTS; |
---|
749 | | - memcpy(ctx->v2.master_key_identifier, key_spec.u.identifier, |
---|
| 762 | + case FSCRYPT_POLICY_V2: |
---|
| 763 | + policy->v2.contents_encryption_mode = FSCRYPT_MODE_AES_256_XTS; |
---|
| 764 | + policy->v2.filenames_encryption_mode = FSCRYPT_MODE_AES_256_CTS; |
---|
| 765 | + memcpy(policy->v2.master_key_identifier, key_spec.u.identifier, |
---|
750 | 766 | FSCRYPT_KEY_IDENTIFIER_SIZE); |
---|
751 | 767 | break; |
---|
752 | 768 | default: |
---|
.. | .. |
---|
754 | 770 | err = -EINVAL; |
---|
755 | 771 | goto out; |
---|
756 | 772 | } |
---|
757 | | - dummy_ctx->ctx = ctx; |
---|
758 | | - ctx = NULL; |
---|
| 773 | + |
---|
| 774 | + if (dummy_policy->policy) { |
---|
| 775 | + if (fscrypt_policies_equal(policy, dummy_policy->policy)) |
---|
| 776 | + err = 0; |
---|
| 777 | + else |
---|
| 778 | + err = -EEXIST; |
---|
| 779 | + goto out; |
---|
| 780 | + } |
---|
| 781 | + dummy_policy->policy = policy; |
---|
| 782 | + policy = NULL; |
---|
759 | 783 | err = 0; |
---|
760 | 784 | out: |
---|
761 | | - kfree(ctx); |
---|
762 | | - kfree(argstr_to_free); |
---|
| 785 | + kfree(policy); |
---|
763 | 786 | return err; |
---|
764 | 787 | } |
---|
765 | 788 | EXPORT_SYMBOL_GPL(fscrypt_set_test_dummy_encryption); |
---|
.. | .. |
---|
776 | 799 | void fscrypt_show_test_dummy_encryption(struct seq_file *seq, char sep, |
---|
777 | 800 | struct super_block *sb) |
---|
778 | 801 | { |
---|
779 | | - const union fscrypt_context *ctx = fscrypt_get_dummy_context(sb); |
---|
| 802 | + const union fscrypt_policy *policy = fscrypt_get_dummy_policy(sb); |
---|
| 803 | + int vers; |
---|
780 | 804 | |
---|
781 | | - if (!ctx) |
---|
| 805 | + if (!policy) |
---|
782 | 806 | return; |
---|
783 | | - seq_printf(seq, "%ctest_dummy_encryption=v%d", sep, ctx->version); |
---|
| 807 | + |
---|
| 808 | + vers = policy->version; |
---|
| 809 | + if (vers == FSCRYPT_POLICY_V1) /* Handle numbering quirk */ |
---|
| 810 | + vers = 1; |
---|
| 811 | + |
---|
| 812 | + seq_printf(seq, "%ctest_dummy_encryption=v%d", sep, vers); |
---|
784 | 813 | } |
---|
785 | 814 | EXPORT_SYMBOL_GPL(fscrypt_show_test_dummy_encryption); |
---|