at v6.19 605 lines 17 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * The base64 encode/decode code was copied from fscrypt: 4 * Copyright (C) 2015, Google, Inc. 5 * Copyright (C) 2015, Motorola Mobility 6 * Written by Uday Savagaonkar, 2014. 7 * Modified by Jaegeuk Kim, 2015. 8 */ 9#include <linux/ceph/ceph_debug.h> 10#include <linux/xattr.h> 11#include <linux/fscrypt.h> 12#include <linux/ceph/striper.h> 13 14#include "super.h" 15#include "mds_client.h" 16#include "crypto.h" 17 18static int ceph_crypt_get_context(struct inode *inode, void *ctx, size_t len) 19{ 20 struct ceph_inode_info *ci = ceph_inode(inode); 21 struct ceph_fscrypt_auth *cfa = (struct ceph_fscrypt_auth *)ci->fscrypt_auth; 22 u32 ctxlen; 23 24 /* Non existent or too short? */ 25 if (!cfa || (ci->fscrypt_auth_len < (offsetof(struct ceph_fscrypt_auth, cfa_blob) + 1))) 26 return -ENOBUFS; 27 28 /* Some format we don't recognize? */ 29 if (le32_to_cpu(cfa->cfa_version) != CEPH_FSCRYPT_AUTH_VERSION) 30 return -ENOBUFS; 31 32 ctxlen = le32_to_cpu(cfa->cfa_blob_len); 33 if (len < ctxlen) 34 return -ERANGE; 35 36 memcpy(ctx, cfa->cfa_blob, ctxlen); 37 return ctxlen; 38} 39 40static int ceph_crypt_set_context(struct inode *inode, const void *ctx, 41 size_t len, void *fs_data) 42{ 43 int ret; 44 struct iattr attr = { }; 45 struct ceph_iattr cia = { }; 46 struct ceph_fscrypt_auth *cfa; 47 48 WARN_ON_ONCE(fs_data); 49 50 if (len > FSCRYPT_SET_CONTEXT_MAX_SIZE) 51 return -EINVAL; 52 53 cfa = kzalloc(sizeof(*cfa), GFP_KERNEL); 54 if (!cfa) 55 return -ENOMEM; 56 57 cfa->cfa_version = cpu_to_le32(CEPH_FSCRYPT_AUTH_VERSION); 58 cfa->cfa_blob_len = cpu_to_le32(len); 59 memcpy(cfa->cfa_blob, ctx, len); 60 61 cia.fscrypt_auth = cfa; 62 63 ret = __ceph_setattr(&nop_mnt_idmap, inode, &attr, &cia); 64 if (ret == 0) 65 inode_set_flags(inode, S_ENCRYPTED, S_ENCRYPTED); 66 kfree(cia.fscrypt_auth); 67 return ret; 68} 69 70static bool ceph_crypt_empty_dir(struct inode *inode) 71{ 72 struct ceph_inode_info *ci = ceph_inode(inode); 73 74 return ci->i_rsubdirs + ci->i_rfiles == 1; 75} 76 77static const union fscrypt_policy *ceph_get_dummy_policy(struct super_block *sb) 78{ 79 return ceph_sb_to_fs_client(sb)->fsc_dummy_enc_policy.policy; 80} 81 82static struct fscrypt_operations ceph_fscrypt_ops = { 83 .inode_info_offs = (int)offsetof(struct ceph_inode_info, i_crypt_info) - 84 (int)offsetof(struct ceph_inode_info, netfs.inode), 85 .needs_bounce_pages = 1, 86 .get_context = ceph_crypt_get_context, 87 .set_context = ceph_crypt_set_context, 88 .get_dummy_policy = ceph_get_dummy_policy, 89 .empty_dir = ceph_crypt_empty_dir, 90}; 91 92void ceph_fscrypt_set_ops(struct super_block *sb) 93{ 94 fscrypt_set_ops(sb, &ceph_fscrypt_ops); 95} 96 97void ceph_fscrypt_free_dummy_policy(struct ceph_fs_client *fsc) 98{ 99 fscrypt_free_dummy_policy(&fsc->fsc_dummy_enc_policy); 100} 101 102int ceph_fscrypt_prepare_context(struct inode *dir, struct inode *inode, 103 struct ceph_acl_sec_ctx *as) 104{ 105 int ret, ctxsize; 106 bool encrypted = false; 107 struct ceph_inode_info *ci = ceph_inode(inode); 108 109 ret = fscrypt_prepare_new_inode(dir, inode, &encrypted); 110 if (ret) 111 return ret; 112 if (!encrypted) 113 return 0; 114 115 as->fscrypt_auth = kzalloc(sizeof(*as->fscrypt_auth), GFP_KERNEL); 116 if (!as->fscrypt_auth) 117 return -ENOMEM; 118 119 ctxsize = fscrypt_context_for_new_inode(as->fscrypt_auth->cfa_blob, 120 inode); 121 if (ctxsize < 0) 122 return ctxsize; 123 124 as->fscrypt_auth->cfa_version = cpu_to_le32(CEPH_FSCRYPT_AUTH_VERSION); 125 as->fscrypt_auth->cfa_blob_len = cpu_to_le32(ctxsize); 126 127 WARN_ON_ONCE(ci->fscrypt_auth); 128 kfree(ci->fscrypt_auth); 129 ci->fscrypt_auth_len = ceph_fscrypt_auth_len(as->fscrypt_auth); 130 ci->fscrypt_auth = kmemdup(as->fscrypt_auth, ci->fscrypt_auth_len, 131 GFP_KERNEL); 132 if (!ci->fscrypt_auth) 133 return -ENOMEM; 134 135 inode->i_flags |= S_ENCRYPTED; 136 137 return 0; 138} 139 140void ceph_fscrypt_as_ctx_to_req(struct ceph_mds_request *req, 141 struct ceph_acl_sec_ctx *as) 142{ 143 swap(req->r_fscrypt_auth, as->fscrypt_auth); 144} 145 146/* 147 * User-created snapshots can't start with '_'. Snapshots that start with this 148 * character are special (hint: there aren't real snapshots) and use the 149 * following format: 150 * 151 * _<SNAPSHOT-NAME>_<INODE-NUMBER> 152 * 153 * where: 154 * - <SNAPSHOT-NAME> - the real snapshot name that may need to be decrypted, 155 * - <INODE-NUMBER> - the inode number (in decimal) for the actual snapshot 156 * 157 * This function parses these snapshot names and returns the inode 158 * <INODE-NUMBER>. 'name_len' will also bet set with the <SNAPSHOT-NAME> 159 * length. 160 */ 161static struct inode *parse_longname(const struct inode *parent, 162 const char *name, int *name_len) 163{ 164 struct ceph_client *cl = ceph_inode_to_client(parent); 165 struct inode *dir = NULL; 166 struct ceph_vino vino = { .snap = CEPH_NOSNAP }; 167 char *name_end, *inode_number; 168 int ret = -EIO; 169 /* Snapshot name must start with an underscore */ 170 if (*name_len <= 0 || name[0] != '_') 171 return ERR_PTR(-EIO); 172 /* Skip initial '_' and NUL-terminate */ 173 char *str __free(kfree) = kmemdup_nul(name + 1, *name_len - 1, GFP_KERNEL); 174 if (!str) 175 return ERR_PTR(-ENOMEM); 176 name_end = strrchr(str, '_'); 177 if (!name_end) { 178 doutc(cl, "failed to parse long snapshot name: %s\n", str); 179 return ERR_PTR(-EIO); 180 } 181 *name_len = (name_end - str); 182 if (*name_len <= 0) { 183 pr_err_client(cl, "failed to parse long snapshot name\n"); 184 return ERR_PTR(-EIO); 185 } 186 187 /* Get the inode number */ 188 inode_number = name_end + 1; 189 ret = kstrtou64(inode_number, 10, &vino.ino); 190 if (ret) { 191 doutc(cl, "failed to parse inode number: %s\n", str); 192 return ERR_PTR(ret); 193 } 194 195 /* And finally the inode */ 196 dir = ceph_find_inode(parent->i_sb, vino); 197 if (!dir) { 198 /* This can happen if we're not mounting cephfs on the root */ 199 dir = ceph_get_inode(parent->i_sb, vino, NULL); 200 if (IS_ERR(dir)) 201 doutc(cl, "can't find inode %s (%s)\n", inode_number, name); 202 } 203 return dir; 204} 205 206int ceph_encode_encrypted_dname(struct inode *parent, char *buf, int elen) 207{ 208 struct ceph_client *cl = ceph_inode_to_client(parent); 209 struct inode *dir = parent; 210 char *p = buf; 211 u32 len; 212 int name_len = elen; 213 int ret; 214 u8 *cryptbuf = NULL; 215 216 /* Handle the special case of snapshot names that start with '_' */ 217 if (ceph_snap(dir) == CEPH_SNAPDIR && *p == '_') { 218 dir = parse_longname(parent, p, &name_len); 219 if (IS_ERR(dir)) 220 return PTR_ERR(dir); 221 p++; /* skip initial '_' */ 222 } 223 224 if (!fscrypt_has_encryption_key(dir)) 225 goto out; 226 227 /* 228 * Convert cleartext d_name to ciphertext. If result is longer than 229 * CEPH_NOHASH_NAME_MAX, sha256 the remaining bytes 230 * 231 * See: fscrypt_setup_filename 232 */ 233 if (!fscrypt_fname_encrypted_size(dir, name_len, NAME_MAX, &len)) { 234 elen = -ENAMETOOLONG; 235 goto out; 236 } 237 238 /* Allocate a buffer appropriate to hold the result */ 239 cryptbuf = kmalloc(len > CEPH_NOHASH_NAME_MAX ? NAME_MAX : len, 240 GFP_KERNEL); 241 if (!cryptbuf) { 242 elen = -ENOMEM; 243 goto out; 244 } 245 246 ret = fscrypt_fname_encrypt(dir, 247 &(struct qstr)QSTR_INIT(p, name_len), 248 cryptbuf, len); 249 if (ret) { 250 elen = ret; 251 goto out; 252 } 253 254 /* hash the end if the name is long enough */ 255 if (len > CEPH_NOHASH_NAME_MAX) { 256 u8 hash[SHA256_DIGEST_SIZE]; 257 u8 *extra = cryptbuf + CEPH_NOHASH_NAME_MAX; 258 259 /* 260 * hash the extra bytes and overwrite crypttext beyond that 261 * point with it 262 */ 263 sha256(extra, len - CEPH_NOHASH_NAME_MAX, hash); 264 memcpy(extra, hash, SHA256_DIGEST_SIZE); 265 len = CEPH_NOHASH_NAME_MAX + SHA256_DIGEST_SIZE; 266 } 267 268 /* base64 encode the encrypted name */ 269 elen = base64_encode(cryptbuf, len, p, false, BASE64_IMAP); 270 doutc(cl, "base64-encoded ciphertext name = %.*s\n", elen, p); 271 272 /* To understand the 240 limit, see CEPH_NOHASH_NAME_MAX comments */ 273 WARN_ON(elen > 240); 274 if (dir != parent) // leading _ is already there; append _<inum> 275 elen += 1 + sprintf(p + elen, "_%ld", dir->i_ino); 276 277out: 278 kfree(cryptbuf); 279 if (dir != parent) { 280 if ((inode_state_read_once(dir) & I_NEW)) 281 discard_new_inode(dir); 282 else 283 iput(dir); 284 } 285 return elen; 286} 287 288/** 289 * ceph_fname_to_usr - convert a filename for userland presentation 290 * @fname: ceph_fname to be converted 291 * @tname: temporary name buffer to use for conversion (may be NULL) 292 * @oname: where converted name should be placed 293 * @is_nokey: set to true if key wasn't available during conversion (may be NULL) 294 * 295 * Given a filename (usually from the MDS), format it for presentation to 296 * userland. If @parent is not encrypted, just pass it back as-is. 297 * 298 * Otherwise, base64 decode the string, and then ask fscrypt to format it 299 * for userland presentation. 300 * 301 * Returns 0 on success or negative error code on error. 302 */ 303int ceph_fname_to_usr(const struct ceph_fname *fname, struct fscrypt_str *tname, 304 struct fscrypt_str *oname, bool *is_nokey) 305{ 306 struct inode *dir = fname->dir; 307 struct fscrypt_str _tname = FSTR_INIT(NULL, 0); 308 struct fscrypt_str iname; 309 char *name = fname->name; 310 int name_len = fname->name_len; 311 int ret; 312 313 /* Sanity check that the resulting name will fit in the buffer */ 314 if (fname->name_len > NAME_MAX || fname->ctext_len > NAME_MAX) 315 return -EIO; 316 317 /* Handle the special case of snapshot names that start with '_' */ 318 if ((ceph_snap(dir) == CEPH_SNAPDIR) && (name_len > 0) && 319 (name[0] == '_')) { 320 dir = parse_longname(dir, name, &name_len); 321 if (IS_ERR(dir)) 322 return PTR_ERR(dir); 323 name++; /* skip initial '_' */ 324 } 325 326 if (!IS_ENCRYPTED(dir)) { 327 oname->name = fname->name; 328 oname->len = fname->name_len; 329 ret = 0; 330 goto out_inode; 331 } 332 333 ret = ceph_fscrypt_prepare_readdir(dir); 334 if (ret) 335 goto out_inode; 336 337 /* 338 * Use the raw dentry name as sent by the MDS instead of 339 * generating a nokey name via fscrypt. 340 */ 341 if (!fscrypt_has_encryption_key(dir)) { 342 if (fname->no_copy) 343 oname->name = fname->name; 344 else 345 memcpy(oname->name, fname->name, fname->name_len); 346 oname->len = fname->name_len; 347 if (is_nokey) 348 *is_nokey = true; 349 ret = 0; 350 goto out_inode; 351 } 352 353 if (fname->ctext_len == 0) { 354 int declen; 355 356 if (!tname) { 357 ret = fscrypt_fname_alloc_buffer(NAME_MAX, &_tname); 358 if (ret) 359 goto out_inode; 360 tname = &_tname; 361 } 362 363 declen = base64_decode(name, name_len, 364 tname->name, false, BASE64_IMAP); 365 if (declen <= 0) { 366 ret = -EIO; 367 goto out; 368 } 369 iname.name = tname->name; 370 iname.len = declen; 371 } else { 372 iname.name = fname->ctext; 373 iname.len = fname->ctext_len; 374 } 375 376 ret = fscrypt_fname_disk_to_usr(dir, 0, 0, &iname, oname); 377 if (!ret && (dir != fname->dir)) { 378 char tmp_buf[BASE64_CHARS(NAME_MAX)]; 379 380 name_len = snprintf(tmp_buf, sizeof(tmp_buf), "_%.*s_%ld", 381 oname->len, oname->name, dir->i_ino); 382 memcpy(oname->name, tmp_buf, name_len); 383 oname->len = name_len; 384 } 385 386out: 387 fscrypt_fname_free_buffer(&_tname); 388out_inode: 389 if (dir != fname->dir) { 390 if ((inode_state_read_once(dir) & I_NEW)) 391 discard_new_inode(dir); 392 else 393 iput(dir); 394 } 395 return ret; 396} 397 398/** 399 * ceph_fscrypt_prepare_readdir - simple __fscrypt_prepare_readdir() wrapper 400 * @dir: directory inode for readdir prep 401 * 402 * Simple wrapper around __fscrypt_prepare_readdir() that will mark directory as 403 * non-complete if this call results in having the directory unlocked. 404 * 405 * Returns: 406 * 1 - if directory was locked and key is now loaded (i.e. dir is unlocked) 407 * 0 - if directory is still locked 408 * < 0 - if __fscrypt_prepare_readdir() fails 409 */ 410int ceph_fscrypt_prepare_readdir(struct inode *dir) 411{ 412 bool had_key = fscrypt_has_encryption_key(dir); 413 int err; 414 415 if (!IS_ENCRYPTED(dir)) 416 return 0; 417 418 err = __fscrypt_prepare_readdir(dir); 419 if (err) 420 return err; 421 if (!had_key && fscrypt_has_encryption_key(dir)) { 422 /* directory just got unlocked, mark it as not complete */ 423 ceph_dir_clear_complete(dir); 424 return 1; 425 } 426 return 0; 427} 428 429int ceph_fscrypt_decrypt_block_inplace(const struct inode *inode, 430 struct page *page, unsigned int len, 431 unsigned int offs, u64 lblk_num) 432{ 433 struct ceph_client *cl = ceph_inode_to_client(inode); 434 435 doutc(cl, "%p %llx.%llx len %u offs %u blk %llu\n", inode, 436 ceph_vinop(inode), len, offs, lblk_num); 437 return fscrypt_decrypt_block_inplace(inode, page, len, offs, lblk_num); 438} 439 440int ceph_fscrypt_encrypt_block_inplace(const struct inode *inode, 441 struct page *page, unsigned int len, 442 unsigned int offs, u64 lblk_num) 443{ 444 struct ceph_client *cl = ceph_inode_to_client(inode); 445 446 doutc(cl, "%p %llx.%llx len %u offs %u blk %llu\n", inode, 447 ceph_vinop(inode), len, offs, lblk_num); 448 return fscrypt_encrypt_block_inplace(inode, page, len, offs, lblk_num); 449} 450 451/** 452 * ceph_fscrypt_decrypt_pages - decrypt an array of pages 453 * @inode: pointer to inode associated with these pages 454 * @page: pointer to page array 455 * @off: offset into the file that the read data starts 456 * @len: max length to decrypt 457 * 458 * Decrypt an array of fscrypt'ed pages and return the amount of 459 * data decrypted. Any data in the page prior to the start of the 460 * first complete block in the read is ignored. Any incomplete 461 * crypto blocks at the end of the array are ignored (and should 462 * probably be zeroed by the caller). 463 * 464 * Returns the length of the decrypted data or a negative errno. 465 */ 466int ceph_fscrypt_decrypt_pages(struct inode *inode, struct page **page, 467 u64 off, int len) 468{ 469 int i, num_blocks; 470 u64 baseblk = off >> CEPH_FSCRYPT_BLOCK_SHIFT; 471 int ret = 0; 472 473 /* 474 * We can't deal with partial blocks on an encrypted file, so mask off 475 * the last bit. 476 */ 477 num_blocks = ceph_fscrypt_blocks(off, len & CEPH_FSCRYPT_BLOCK_MASK); 478 479 /* Decrypt each block */ 480 for (i = 0; i < num_blocks; ++i) { 481 int blkoff = i << CEPH_FSCRYPT_BLOCK_SHIFT; 482 int pgidx = blkoff >> PAGE_SHIFT; 483 unsigned int pgoffs = offset_in_page(blkoff); 484 int fret; 485 486 fret = ceph_fscrypt_decrypt_block_inplace(inode, page[pgidx], 487 CEPH_FSCRYPT_BLOCK_SIZE, pgoffs, 488 baseblk + i); 489 if (fret < 0) { 490 if (ret == 0) 491 ret = fret; 492 break; 493 } 494 ret += CEPH_FSCRYPT_BLOCK_SIZE; 495 } 496 return ret; 497} 498 499/** 500 * ceph_fscrypt_decrypt_extents: decrypt received extents in given buffer 501 * @inode: inode associated with pages being decrypted 502 * @page: pointer to page array 503 * @off: offset into the file that the data in page[0] starts 504 * @map: pointer to extent array 505 * @ext_cnt: length of extent array 506 * 507 * Given an extent map and a page array, decrypt the received data in-place, 508 * skipping holes. Returns the offset into buffer of end of last decrypted 509 * block. 510 */ 511int ceph_fscrypt_decrypt_extents(struct inode *inode, struct page **page, 512 u64 off, struct ceph_sparse_extent *map, 513 u32 ext_cnt) 514{ 515 struct ceph_client *cl = ceph_inode_to_client(inode); 516 int i, ret = 0; 517 struct ceph_inode_info *ci = ceph_inode(inode); 518 u64 objno, objoff; 519 u32 xlen; 520 521 /* Nothing to do for empty array */ 522 if (ext_cnt == 0) { 523 doutc(cl, "%p %llx.%llx empty array, ret 0\n", inode, 524 ceph_vinop(inode)); 525 return 0; 526 } 527 528 ceph_calc_file_object_mapping(&ci->i_layout, off, map[0].len, 529 &objno, &objoff, &xlen); 530 531 for (i = 0; i < ext_cnt; ++i) { 532 struct ceph_sparse_extent *ext = &map[i]; 533 int pgsoff = ext->off - objoff; 534 int pgidx = pgsoff >> PAGE_SHIFT; 535 int fret; 536 537 if ((ext->off | ext->len) & ~CEPH_FSCRYPT_BLOCK_MASK) { 538 pr_warn_client(cl, 539 "%p %llx.%llx bad encrypted sparse extent " 540 "idx %d off %llx len %llx\n", 541 inode, ceph_vinop(inode), i, ext->off, 542 ext->len); 543 return -EIO; 544 } 545 fret = ceph_fscrypt_decrypt_pages(inode, &page[pgidx], 546 off + pgsoff, ext->len); 547 doutc(cl, "%p %llx.%llx [%d] 0x%llx~0x%llx fret %d\n", inode, 548 ceph_vinop(inode), i, ext->off, ext->len, fret); 549 if (fret < 0) { 550 if (ret == 0) 551 ret = fret; 552 break; 553 } 554 ret = pgsoff + fret; 555 } 556 doutc(cl, "ret %d\n", ret); 557 return ret; 558} 559 560/** 561 * ceph_fscrypt_encrypt_pages - encrypt an array of pages 562 * @inode: pointer to inode associated with these pages 563 * @page: pointer to page array 564 * @off: offset into the file that the data starts 565 * @len: max length to encrypt 566 * 567 * Encrypt an array of cleartext pages and return the amount of 568 * data encrypted. Any data in the page prior to the start of the 569 * first complete block in the read is ignored. Any incomplete 570 * crypto blocks at the end of the array are ignored. 571 * 572 * Returns the length of the encrypted data or a negative errno. 573 */ 574int ceph_fscrypt_encrypt_pages(struct inode *inode, struct page **page, u64 off, 575 int len) 576{ 577 int i, num_blocks; 578 u64 baseblk = off >> CEPH_FSCRYPT_BLOCK_SHIFT; 579 int ret = 0; 580 581 /* 582 * We can't deal with partial blocks on an encrypted file, so mask off 583 * the last bit. 584 */ 585 num_blocks = ceph_fscrypt_blocks(off, len & CEPH_FSCRYPT_BLOCK_MASK); 586 587 /* Encrypt each block */ 588 for (i = 0; i < num_blocks; ++i) { 589 int blkoff = i << CEPH_FSCRYPT_BLOCK_SHIFT; 590 int pgidx = blkoff >> PAGE_SHIFT; 591 unsigned int pgoffs = offset_in_page(blkoff); 592 int fret; 593 594 fret = ceph_fscrypt_encrypt_block_inplace(inode, page[pgidx], 595 CEPH_FSCRYPT_BLOCK_SIZE, pgoffs, 596 baseblk + i); 597 if (fret < 0) { 598 if (ret == 0) 599 ret = fret; 600 break; 601 } 602 ret += CEPH_FSCRYPT_BLOCK_SIZE; 603 } 604 return ret; 605}