linux/fs/ntfs3/xattr.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 *
   4 * Copyright (C) 2019-2021 Paragon Software GmbH, All rights reserved.
   5 *
   6 */
   7
   8#include <linux/fs.h>
   9#include <linux/posix_acl.h>
  10#include <linux/posix_acl_xattr.h>
  11#include <linux/xattr.h>
  12
  13#include "debug.h"
  14#include "ntfs.h"
  15#include "ntfs_fs.h"
  16
  17// clang-format off
  18#define SYSTEM_DOS_ATTRIB    "system.dos_attrib"
  19#define SYSTEM_NTFS_ATTRIB   "system.ntfs_attrib"
  20#define SYSTEM_NTFS_SECURITY "system.ntfs_security"
  21// clang-format on
  22
  23static inline size_t unpacked_ea_size(const struct EA_FULL *ea)
  24{
  25        return ea->size ? le32_to_cpu(ea->size)
  26                        : ALIGN(struct_size(ea, name,
  27                                            1 + ea->name_len +
  28                                                    le16_to_cpu(ea->elength)),
  29                                4);
  30}
  31
  32static inline size_t packed_ea_size(const struct EA_FULL *ea)
  33{
  34        return struct_size(ea, name,
  35                           1 + ea->name_len + le16_to_cpu(ea->elength)) -
  36               offsetof(struct EA_FULL, flags);
  37}
  38
  39/*
  40 * find_ea
  41 *
  42 * Assume there is at least one xattr in the list.
  43 */
  44static inline bool find_ea(const struct EA_FULL *ea_all, u32 bytes,
  45                           const char *name, u8 name_len, u32 *off)
  46{
  47        *off = 0;
  48
  49        if (!ea_all || !bytes)
  50                return false;
  51
  52        for (;;) {
  53                const struct EA_FULL *ea = Add2Ptr(ea_all, *off);
  54                u32 next_off = *off + unpacked_ea_size(ea);
  55
  56                if (next_off > bytes)
  57                        return false;
  58
  59                if (ea->name_len == name_len &&
  60                    !memcmp(ea->name, name, name_len))
  61                        return true;
  62
  63                *off = next_off;
  64                if (next_off >= bytes)
  65                        return false;
  66        }
  67}
  68
  69/*
  70 * ntfs_read_ea - Read all extended attributes.
  71 * @ea:         New allocated memory.
  72 * @info:       Pointer into resident data.
  73 */
  74static int ntfs_read_ea(struct ntfs_inode *ni, struct EA_FULL **ea,
  75                        size_t add_bytes, const struct EA_INFO **info)
  76{
  77        int err;
  78        struct ntfs_sb_info *sbi = ni->mi.sbi;
  79        struct ATTR_LIST_ENTRY *le = NULL;
  80        struct ATTRIB *attr_info, *attr_ea;
  81        void *ea_p;
  82        u32 size;
  83
  84        static_assert(le32_to_cpu(ATTR_EA_INFO) < le32_to_cpu(ATTR_EA));
  85
  86        *ea = NULL;
  87        *info = NULL;
  88
  89        attr_info =
  90                ni_find_attr(ni, NULL, &le, ATTR_EA_INFO, NULL, 0, NULL, NULL);
  91        attr_ea =
  92                ni_find_attr(ni, attr_info, &le, ATTR_EA, NULL, 0, NULL, NULL);
  93
  94        if (!attr_ea || !attr_info)
  95                return 0;
  96
  97        *info = resident_data_ex(attr_info, sizeof(struct EA_INFO));
  98        if (!*info)
  99                return -EINVAL;
 100
 101        /* Check Ea limit. */
 102        size = le32_to_cpu((*info)->size);
 103        if (size > sbi->ea_max_size)
 104                return -EFBIG;
 105
 106        if (attr_size(attr_ea) > sbi->ea_max_size)
 107                return -EFBIG;
 108
 109        /* Allocate memory for packed Ea. */
 110        ea_p = kmalloc(size + add_bytes, GFP_NOFS);
 111        if (!ea_p)
 112                return -ENOMEM;
 113
 114        if (!size) {
 115                ;
 116        } else if (attr_ea->non_res) {
 117                struct runs_tree run;
 118
 119                run_init(&run);
 120
 121                err = attr_load_runs(attr_ea, ni, &run, NULL);
 122                if (!err)
 123                        err = ntfs_read_run_nb(sbi, &run, 0, ea_p, size, NULL);
 124                run_close(&run);
 125
 126                if (err)
 127                        goto out;
 128        } else {
 129                void *p = resident_data_ex(attr_ea, size);
 130
 131                if (!p) {
 132                        err = -EINVAL;
 133                        goto out;
 134                }
 135                memcpy(ea_p, p, size);
 136        }
 137
 138        memset(Add2Ptr(ea_p, size), 0, add_bytes);
 139        *ea = ea_p;
 140        return 0;
 141
 142out:
 143        kfree(ea_p);
 144        *ea = NULL;
 145        return err;
 146}
 147
 148/*
 149 * ntfs_list_ea
 150 *
 151 * Copy a list of xattrs names into the buffer
 152 * provided, or compute the buffer size required.
 153 *
 154 * Return:
 155 * * Number of bytes used / required on
 156 * * -ERRNO - on failure
 157 */
 158static ssize_t ntfs_list_ea(struct ntfs_inode *ni, char *buffer,
 159                            size_t bytes_per_buffer)
 160{
 161        const struct EA_INFO *info;
 162        struct EA_FULL *ea_all = NULL;
 163        const struct EA_FULL *ea;
 164        u32 off, size;
 165        int err;
 166        size_t ret;
 167
 168        err = ntfs_read_ea(ni, &ea_all, 0, &info);
 169        if (err)
 170                return err;
 171
 172        if (!info || !ea_all)
 173                return 0;
 174
 175        size = le32_to_cpu(info->size);
 176
 177        /* Enumerate all xattrs. */
 178        for (ret = 0, off = 0; off < size; off += unpacked_ea_size(ea)) {
 179                ea = Add2Ptr(ea_all, off);
 180
 181                if (buffer) {
 182                        if (ret + ea->name_len + 1 > bytes_per_buffer) {
 183                                err = -ERANGE;
 184                                goto out;
 185                        }
 186
 187                        memcpy(buffer + ret, ea->name, ea->name_len);
 188                        buffer[ret + ea->name_len] = 0;
 189                }
 190
 191                ret += ea->name_len + 1;
 192        }
 193
 194out:
 195        kfree(ea_all);
 196        return err ? err : ret;
 197}
 198
 199static int ntfs_get_ea(struct inode *inode, const char *name, size_t name_len,
 200                       void *buffer, size_t size, size_t *required)
 201{
 202        struct ntfs_inode *ni = ntfs_i(inode);
 203        const struct EA_INFO *info;
 204        struct EA_FULL *ea_all = NULL;
 205        const struct EA_FULL *ea;
 206        u32 off, len;
 207        int err;
 208
 209        if (!(ni->ni_flags & NI_FLAG_EA))
 210                return -ENODATA;
 211
 212        if (!required)
 213                ni_lock(ni);
 214
 215        len = 0;
 216
 217        if (name_len > 255) {
 218                err = -ENAMETOOLONG;
 219                goto out;
 220        }
 221
 222        err = ntfs_read_ea(ni, &ea_all, 0, &info);
 223        if (err)
 224                goto out;
 225
 226        if (!info)
 227                goto out;
 228
 229        /* Enumerate all xattrs. */
 230        if (!find_ea(ea_all, le32_to_cpu(info->size), name, name_len, &off)) {
 231                err = -ENODATA;
 232                goto out;
 233        }
 234        ea = Add2Ptr(ea_all, off);
 235
 236        len = le16_to_cpu(ea->elength);
 237        if (!buffer) {
 238                err = 0;
 239                goto out;
 240        }
 241
 242        if (len > size) {
 243                err = -ERANGE;
 244                if (required)
 245                        *required = len;
 246                goto out;
 247        }
 248
 249        memcpy(buffer, ea->name + ea->name_len + 1, len);
 250        err = 0;
 251
 252out:
 253        kfree(ea_all);
 254        if (!required)
 255                ni_unlock(ni);
 256
 257        return err ? err : len;
 258}
 259
 260static noinline int ntfs_set_ea(struct inode *inode, const char *name,
 261                                size_t name_len, const void *value,
 262                                size_t val_size, int flags)
 263{
 264        struct ntfs_inode *ni = ntfs_i(inode);
 265        struct ntfs_sb_info *sbi = ni->mi.sbi;
 266        int err;
 267        struct EA_INFO ea_info;
 268        const struct EA_INFO *info;
 269        struct EA_FULL *new_ea;
 270        struct EA_FULL *ea_all = NULL;
 271        size_t add, new_pack;
 272        u32 off, size;
 273        __le16 size_pack;
 274        struct ATTRIB *attr;
 275        struct ATTR_LIST_ENTRY *le;
 276        struct mft_inode *mi;
 277        struct runs_tree ea_run;
 278        u64 new_sz;
 279        void *p;
 280
 281        ni_lock(ni);
 282
 283        run_init(&ea_run);
 284
 285        if (name_len > 255) {
 286                err = -ENAMETOOLONG;
 287                goto out;
 288        }
 289
 290        add = ALIGN(struct_size(ea_all, name, 1 + name_len + val_size), 4);
 291
 292        err = ntfs_read_ea(ni, &ea_all, add, &info);
 293        if (err)
 294                goto out;
 295
 296        if (!info) {
 297                memset(&ea_info, 0, sizeof(ea_info));
 298                size = 0;
 299                size_pack = 0;
 300        } else {
 301                memcpy(&ea_info, info, sizeof(ea_info));
 302                size = le32_to_cpu(ea_info.size);
 303                size_pack = ea_info.size_pack;
 304        }
 305
 306        if (info && find_ea(ea_all, size, name, name_len, &off)) {
 307                struct EA_FULL *ea;
 308                size_t ea_sz;
 309
 310                if (flags & XATTR_CREATE) {
 311                        err = -EEXIST;
 312                        goto out;
 313                }
 314
 315                ea = Add2Ptr(ea_all, off);
 316
 317                /*
 318                 * Check simple case when we try to insert xattr with the same value
 319                 * e.g. ntfs_save_wsl_perm
 320                 */
 321                if (val_size && le16_to_cpu(ea->elength) == val_size &&
 322                    !memcmp(ea->name + ea->name_len + 1, value, val_size)) {
 323                        /* xattr already contains the required value. */
 324                        goto out;
 325                }
 326
 327                /* Remove current xattr. */
 328                if (ea->flags & FILE_NEED_EA)
 329                        le16_add_cpu(&ea_info.count, -1);
 330
 331                ea_sz = unpacked_ea_size(ea);
 332
 333                le16_add_cpu(&ea_info.size_pack, 0 - packed_ea_size(ea));
 334
 335                memmove(ea, Add2Ptr(ea, ea_sz), size - off - ea_sz);
 336
 337                size -= ea_sz;
 338                memset(Add2Ptr(ea_all, size), 0, ea_sz);
 339
 340                ea_info.size = cpu_to_le32(size);
 341
 342                if ((flags & XATTR_REPLACE) && !val_size) {
 343                        /* Remove xattr. */
 344                        goto update_ea;
 345                }
 346        } else {
 347                if (flags & XATTR_REPLACE) {
 348                        err = -ENODATA;
 349                        goto out;
 350                }
 351
 352                if (!ea_all) {
 353                        ea_all = kzalloc(add, GFP_NOFS);
 354                        if (!ea_all) {
 355                                err = -ENOMEM;
 356                                goto out;
 357                        }
 358                }
 359        }
 360
 361        /* Append new xattr. */
 362        new_ea = Add2Ptr(ea_all, size);
 363        new_ea->size = cpu_to_le32(add);
 364        new_ea->flags = 0;
 365        new_ea->name_len = name_len;
 366        new_ea->elength = cpu_to_le16(val_size);
 367        memcpy(new_ea->name, name, name_len);
 368        new_ea->name[name_len] = 0;
 369        memcpy(new_ea->name + name_len + 1, value, val_size);
 370        new_pack = le16_to_cpu(ea_info.size_pack) + packed_ea_size(new_ea);
 371        ea_info.size_pack = cpu_to_le16(new_pack);
 372        /* New size of ATTR_EA. */
 373        size += add;
 374        ea_info.size = cpu_to_le32(size);
 375
 376        /*
 377         * 1. Check ea_info.size_pack for overflow.
 378         * 2. New attibute size must fit value from $AttrDef
 379         */
 380        if (new_pack > 0xffff || size > sbi->ea_max_size) {
 381                ntfs_inode_warn(
 382                        inode,
 383                        "The size of extended attributes must not exceed 64KiB");
 384                err = -EFBIG; // -EINVAL?
 385                goto out;
 386        }
 387
 388update_ea:
 389
 390        if (!info) {
 391                /* Create xattr. */
 392                if (!size) {
 393                        err = 0;
 394                        goto out;
 395                }
 396
 397                err = ni_insert_resident(ni, sizeof(struct EA_INFO),
 398                                         ATTR_EA_INFO, NULL, 0, NULL, NULL,
 399                                         NULL);
 400                if (err)
 401                        goto out;
 402
 403                err = ni_insert_resident(ni, 0, ATTR_EA, NULL, 0, NULL, NULL,
 404                                         NULL);
 405                if (err)
 406                        goto out;
 407        }
 408
 409        new_sz = size;
 410        err = attr_set_size(ni, ATTR_EA, NULL, 0, &ea_run, new_sz, &new_sz,
 411                            false, NULL);
 412        if (err)
 413                goto out;
 414
 415        le = NULL;
 416        attr = ni_find_attr(ni, NULL, &le, ATTR_EA_INFO, NULL, 0, NULL, &mi);
 417        if (!attr) {
 418                err = -EINVAL;
 419                goto out;
 420        }
 421
 422        if (!size) {
 423                /* Delete xattr, ATTR_EA_INFO */
 424                ni_remove_attr_le(ni, attr, mi, le);
 425        } else {
 426                p = resident_data_ex(attr, sizeof(struct EA_INFO));
 427                if (!p) {
 428                        err = -EINVAL;
 429                        goto out;
 430                }
 431                memcpy(p, &ea_info, sizeof(struct EA_INFO));
 432                mi->dirty = true;
 433        }
 434
 435        le = NULL;
 436        attr = ni_find_attr(ni, NULL, &le, ATTR_EA, NULL, 0, NULL, &mi);
 437        if (!attr) {
 438                err = -EINVAL;
 439                goto out;
 440        }
 441
 442        if (!size) {
 443                /* Delete xattr, ATTR_EA */
 444                ni_remove_attr_le(ni, attr, mi, le);
 445        } else if (attr->non_res) {
 446                err = ntfs_sb_write_run(sbi, &ea_run, 0, ea_all, size, 0);
 447                if (err)
 448                        goto out;
 449        } else {
 450                p = resident_data_ex(attr, size);
 451                if (!p) {
 452                        err = -EINVAL;
 453                        goto out;
 454                }
 455                memcpy(p, ea_all, size);
 456                mi->dirty = true;
 457        }
 458
 459        /* Check if we delete the last xattr. */
 460        if (size)
 461                ni->ni_flags |= NI_FLAG_EA;
 462        else
 463                ni->ni_flags &= ~NI_FLAG_EA;
 464
 465        if (ea_info.size_pack != size_pack)
 466                ni->ni_flags |= NI_FLAG_UPDATE_PARENT;
 467        mark_inode_dirty(&ni->vfs_inode);
 468
 469out:
 470        ni_unlock(ni);
 471
 472        run_close(&ea_run);
 473        kfree(ea_all);
 474
 475        return err;
 476}
 477
 478#ifdef CONFIG_NTFS3_FS_POSIX_ACL
 479static struct posix_acl *ntfs_get_acl_ex(struct user_namespace *mnt_userns,
 480                                         struct inode *inode, int type,
 481                                         int locked)
 482{
 483        struct ntfs_inode *ni = ntfs_i(inode);
 484        const char *name;
 485        size_t name_len;
 486        struct posix_acl *acl;
 487        size_t req;
 488        int err;
 489        void *buf;
 490
 491        /* Allocate PATH_MAX bytes. */
 492        buf = __getname();
 493        if (!buf)
 494                return ERR_PTR(-ENOMEM);
 495
 496        /* Possible values of 'type' was already checked above. */
 497        if (type == ACL_TYPE_ACCESS) {
 498                name = XATTR_NAME_POSIX_ACL_ACCESS;
 499                name_len = sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1;
 500        } else {
 501                name = XATTR_NAME_POSIX_ACL_DEFAULT;
 502                name_len = sizeof(XATTR_NAME_POSIX_ACL_DEFAULT) - 1;
 503        }
 504
 505        if (!locked)
 506                ni_lock(ni);
 507
 508        err = ntfs_get_ea(inode, name, name_len, buf, PATH_MAX, &req);
 509
 510        if (!locked)
 511                ni_unlock(ni);
 512
 513        /* Translate extended attribute to acl. */
 514        if (err >= 0) {
 515                acl = posix_acl_from_xattr(mnt_userns, buf, err);
 516        } else if (err == -ENODATA) {
 517                acl = NULL;
 518        } else {
 519                acl = ERR_PTR(err);
 520        }
 521
 522        if (!IS_ERR(acl))
 523                set_cached_acl(inode, type, acl);
 524
 525        __putname(buf);
 526
 527        return acl;
 528}
 529
 530/*
 531 * ntfs_get_acl - inode_operations::get_acl
 532 */
 533struct posix_acl *ntfs_get_acl(struct inode *inode, int type, bool rcu)
 534{
 535        if (rcu)
 536                return ERR_PTR(-ECHILD);
 537
 538        /* TODO: init_user_ns? */
 539        return ntfs_get_acl_ex(&init_user_ns, inode, type, 0);
 540}
 541
 542static noinline int ntfs_set_acl_ex(struct user_namespace *mnt_userns,
 543                                    struct inode *inode, struct posix_acl *acl,
 544                                    int type)
 545{
 546        const char *name;
 547        size_t size, name_len;
 548        void *value = NULL;
 549        int err = 0;
 550        int flags;
 551
 552        if (S_ISLNK(inode->i_mode))
 553                return -EOPNOTSUPP;
 554
 555        switch (type) {
 556        case ACL_TYPE_ACCESS:
 557                if (acl) {
 558                        umode_t mode = inode->i_mode;
 559
 560                        err = posix_acl_update_mode(mnt_userns, inode, &mode,
 561                                                    &acl);
 562                        if (err)
 563                                goto out;
 564
 565                        if (inode->i_mode != mode) {
 566                                inode->i_mode = mode;
 567                                mark_inode_dirty(inode);
 568                        }
 569                }
 570                name = XATTR_NAME_POSIX_ACL_ACCESS;
 571                name_len = sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1;
 572                break;
 573
 574        case ACL_TYPE_DEFAULT:
 575                if (!S_ISDIR(inode->i_mode))
 576                        return acl ? -EACCES : 0;
 577                name = XATTR_NAME_POSIX_ACL_DEFAULT;
 578                name_len = sizeof(XATTR_NAME_POSIX_ACL_DEFAULT) - 1;
 579                break;
 580
 581        default:
 582                return -EINVAL;
 583        }
 584
 585        if (!acl) {
 586                /* Remove xattr if it can be presented via mode. */
 587                size = 0;
 588                value = NULL;
 589                flags = XATTR_REPLACE;
 590        } else {
 591                size = posix_acl_xattr_size(acl->a_count);
 592                value = kmalloc(size, GFP_NOFS);
 593                if (!value)
 594                        return -ENOMEM;
 595                err = posix_acl_to_xattr(mnt_userns, acl, value, size);
 596                if (err < 0)
 597                        goto out;
 598                flags = 0;
 599        }
 600
 601        err = ntfs_set_ea(inode, name, name_len, value, size, flags);
 602        if (err == -ENODATA && !size)
 603                err = 0; /* Removing non existed xattr. */
 604        if (!err)
 605                set_cached_acl(inode, type, acl);
 606
 607out:
 608        kfree(value);
 609
 610        return err;
 611}
 612
 613/*
 614 * ntfs_set_acl - inode_operations::set_acl
 615 */
 616int ntfs_set_acl(struct user_namespace *mnt_userns, struct inode *inode,
 617                 struct posix_acl *acl, int type)
 618{
 619        return ntfs_set_acl_ex(mnt_userns, inode, acl, type);
 620}
 621
 622/*
 623 * ntfs_init_acl - Initialize the ACLs of a new inode.
 624 *
 625 * Called from ntfs_create_inode().
 626 */
 627int ntfs_init_acl(struct user_namespace *mnt_userns, struct inode *inode,
 628                  struct inode *dir)
 629{
 630        struct posix_acl *default_acl, *acl;
 631        int err;
 632
 633        err = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl);
 634        if (err)
 635                return err;
 636
 637        if (default_acl) {
 638                err = ntfs_set_acl_ex(mnt_userns, inode, default_acl,
 639                                      ACL_TYPE_DEFAULT);
 640                posix_acl_release(default_acl);
 641        } else {
 642                inode->i_default_acl = NULL;
 643        }
 644
 645        if (!acl)
 646                inode->i_acl = NULL;
 647        else {
 648                if (!err)
 649                        err = ntfs_set_acl_ex(mnt_userns, inode, acl,
 650                                              ACL_TYPE_ACCESS);
 651                posix_acl_release(acl);
 652        }
 653
 654        return err;
 655}
 656#endif
 657
 658/*
 659 * ntfs_acl_chmod - Helper for ntfs3_setattr().
 660 */
 661int ntfs_acl_chmod(struct user_namespace *mnt_userns, struct inode *inode)
 662{
 663        struct super_block *sb = inode->i_sb;
 664
 665        if (!(sb->s_flags & SB_POSIXACL))
 666                return 0;
 667
 668        if (S_ISLNK(inode->i_mode))
 669                return -EOPNOTSUPP;
 670
 671        return posix_acl_chmod(mnt_userns, inode, inode->i_mode);
 672}
 673
 674/*
 675 * ntfs_permission - inode_operations::permission
 676 */
 677int ntfs_permission(struct user_namespace *mnt_userns, struct inode *inode,
 678                    int mask)
 679{
 680        if (ntfs_sb(inode->i_sb)->options->noacsrules) {
 681                /* "No access rules" mode - Allow all changes. */
 682                return 0;
 683        }
 684
 685        return generic_permission(mnt_userns, inode, mask);
 686}
 687
 688/*
 689 * ntfs_listxattr - inode_operations::listxattr
 690 */
 691ssize_t ntfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
 692{
 693        struct inode *inode = d_inode(dentry);
 694        struct ntfs_inode *ni = ntfs_i(inode);
 695        ssize_t ret;
 696
 697        if (!(ni->ni_flags & NI_FLAG_EA)) {
 698                /* no xattr in file */
 699                return 0;
 700        }
 701
 702        ni_lock(ni);
 703
 704        ret = ntfs_list_ea(ni, buffer, size);
 705
 706        ni_unlock(ni);
 707
 708        return ret;
 709}
 710
 711static int ntfs_getxattr(const struct xattr_handler *handler, struct dentry *de,
 712                         struct inode *inode, const char *name, void *buffer,
 713                         size_t size)
 714{
 715        int err;
 716        struct ntfs_inode *ni = ntfs_i(inode);
 717        size_t name_len = strlen(name);
 718
 719        /* Dispatch request. */
 720        if (name_len == sizeof(SYSTEM_DOS_ATTRIB) - 1 &&
 721            !memcmp(name, SYSTEM_DOS_ATTRIB, sizeof(SYSTEM_DOS_ATTRIB))) {
 722                /* system.dos_attrib */
 723                if (!buffer) {
 724                        err = sizeof(u8);
 725                } else if (size < sizeof(u8)) {
 726                        err = -ENODATA;
 727                } else {
 728                        err = sizeof(u8);
 729                        *(u8 *)buffer = le32_to_cpu(ni->std_fa);
 730                }
 731                goto out;
 732        }
 733
 734        if (name_len == sizeof(SYSTEM_NTFS_ATTRIB) - 1 &&
 735            !memcmp(name, SYSTEM_NTFS_ATTRIB, sizeof(SYSTEM_NTFS_ATTRIB))) {
 736                /* system.ntfs_attrib */
 737                if (!buffer) {
 738                        err = sizeof(u32);
 739                } else if (size < sizeof(u32)) {
 740                        err = -ENODATA;
 741                } else {
 742                        err = sizeof(u32);
 743                        *(u32 *)buffer = le32_to_cpu(ni->std_fa);
 744                }
 745                goto out;
 746        }
 747
 748        if (name_len == sizeof(SYSTEM_NTFS_SECURITY) - 1 &&
 749            !memcmp(name, SYSTEM_NTFS_SECURITY, sizeof(SYSTEM_NTFS_SECURITY))) {
 750                /* system.ntfs_security*/
 751                struct SECURITY_DESCRIPTOR_RELATIVE *sd = NULL;
 752                size_t sd_size = 0;
 753
 754                if (!is_ntfs3(ni->mi.sbi)) {
 755                        /* We should get nt4 security. */
 756                        err = -EINVAL;
 757                        goto out;
 758                } else if (le32_to_cpu(ni->std_security_id) <
 759                           SECURITY_ID_FIRST) {
 760                        err = -ENOENT;
 761                        goto out;
 762                }
 763
 764                err = ntfs_get_security_by_id(ni->mi.sbi, ni->std_security_id,
 765                                              &sd, &sd_size);
 766                if (err)
 767                        goto out;
 768
 769                if (!is_sd_valid(sd, sd_size)) {
 770                        ntfs_inode_warn(
 771                                inode,
 772                                "looks like you get incorrect security descriptor id=%u",
 773                                ni->std_security_id);
 774                }
 775
 776                if (!buffer) {
 777                        err = sd_size;
 778                } else if (size < sd_size) {
 779                        err = -ENODATA;
 780                } else {
 781                        err = sd_size;
 782                        memcpy(buffer, sd, sd_size);
 783                }
 784                kfree(sd);
 785                goto out;
 786        }
 787
 788        /* Deal with NTFS extended attribute. */
 789        err = ntfs_get_ea(inode, name, name_len, buffer, size, NULL);
 790
 791out:
 792        return err;
 793}
 794
 795/*
 796 * ntfs_setxattr - inode_operations::setxattr
 797 */
 798static noinline int ntfs_setxattr(const struct xattr_handler *handler,
 799                                  struct user_namespace *mnt_userns,
 800                                  struct dentry *de, struct inode *inode,
 801                                  const char *name, const void *value,
 802                                  size_t size, int flags)
 803{
 804        int err = -EINVAL;
 805        struct ntfs_inode *ni = ntfs_i(inode);
 806        size_t name_len = strlen(name);
 807        enum FILE_ATTRIBUTE new_fa;
 808
 809        /* Dispatch request. */
 810        if (name_len == sizeof(SYSTEM_DOS_ATTRIB) - 1 &&
 811            !memcmp(name, SYSTEM_DOS_ATTRIB, sizeof(SYSTEM_DOS_ATTRIB))) {
 812                if (sizeof(u8) != size)
 813                        goto out;
 814                new_fa = cpu_to_le32(*(u8 *)value);
 815                goto set_new_fa;
 816        }
 817
 818        if (name_len == sizeof(SYSTEM_NTFS_ATTRIB) - 1 &&
 819            !memcmp(name, SYSTEM_NTFS_ATTRIB, sizeof(SYSTEM_NTFS_ATTRIB))) {
 820                if (size != sizeof(u32))
 821                        goto out;
 822                new_fa = cpu_to_le32(*(u32 *)value);
 823
 824                if (S_ISREG(inode->i_mode)) {
 825                        /* Process compressed/sparsed in special way. */
 826                        ni_lock(ni);
 827                        err = ni_new_attr_flags(ni, new_fa);
 828                        ni_unlock(ni);
 829                        if (err)
 830                                goto out;
 831                }
 832set_new_fa:
 833                /*
 834                 * Thanks Mark Harmstone:
 835                 * Keep directory bit consistency.
 836                 */
 837                if (S_ISDIR(inode->i_mode))
 838                        new_fa |= FILE_ATTRIBUTE_DIRECTORY;
 839                else
 840                        new_fa &= ~FILE_ATTRIBUTE_DIRECTORY;
 841
 842                if (ni->std_fa != new_fa) {
 843                        ni->std_fa = new_fa;
 844                        if (new_fa & FILE_ATTRIBUTE_READONLY)
 845                                inode->i_mode &= ~0222;
 846                        else
 847                                inode->i_mode |= 0222;
 848                        /* Std attribute always in primary record. */
 849                        ni->mi.dirty = true;
 850                        mark_inode_dirty(inode);
 851                }
 852                err = 0;
 853
 854                goto out;
 855        }
 856
 857        if (name_len == sizeof(SYSTEM_NTFS_SECURITY) - 1 &&
 858            !memcmp(name, SYSTEM_NTFS_SECURITY, sizeof(SYSTEM_NTFS_SECURITY))) {
 859                /* system.ntfs_security*/
 860                __le32 security_id;
 861                bool inserted;
 862                struct ATTR_STD_INFO5 *std;
 863
 864                if (!is_ntfs3(ni->mi.sbi)) {
 865                        /*
 866                         * We should replace ATTR_SECURE.
 867                         * Skip this way cause it is nt4 feature.
 868                         */
 869                        err = -EINVAL;
 870                        goto out;
 871                }
 872
 873                if (!is_sd_valid(value, size)) {
 874                        err = -EINVAL;
 875                        ntfs_inode_warn(
 876                                inode,
 877                                "you try to set invalid security descriptor");
 878                        goto out;
 879                }
 880
 881                err = ntfs_insert_security(ni->mi.sbi, value, size,
 882                                           &security_id, &inserted);
 883                if (err)
 884                        goto out;
 885
 886                ni_lock(ni);
 887                std = ni_std5(ni);
 888                if (!std) {
 889                        err = -EINVAL;
 890                } else if (std->security_id != security_id) {
 891                        std->security_id = ni->std_security_id = security_id;
 892                        /* Std attribute always in primary record. */
 893                        ni->mi.dirty = true;
 894                        mark_inode_dirty(&ni->vfs_inode);
 895                }
 896                ni_unlock(ni);
 897                goto out;
 898        }
 899
 900        /* Deal with NTFS extended attribute. */
 901        err = ntfs_set_ea(inode, name, name_len, value, size, flags);
 902
 903out:
 904        return err;
 905}
 906
 907/*
 908 * ntfs_save_wsl_perm
 909 *
 910 * save uid/gid/mode in xattr
 911 */
 912int ntfs_save_wsl_perm(struct inode *inode)
 913{
 914        int err;
 915        __le32 value;
 916
 917        /* TODO: refactor this, so we don't lock 4 times in ntfs_set_ea */
 918        value = cpu_to_le32(i_uid_read(inode));
 919        err = ntfs_set_ea(inode, "$LXUID", sizeof("$LXUID") - 1, &value,
 920                          sizeof(value), 0);
 921        if (err)
 922                goto out;
 923
 924        value = cpu_to_le32(i_gid_read(inode));
 925        err = ntfs_set_ea(inode, "$LXGID", sizeof("$LXGID") - 1, &value,
 926                          sizeof(value), 0);
 927        if (err)
 928                goto out;
 929
 930        value = cpu_to_le32(inode->i_mode);
 931        err = ntfs_set_ea(inode, "$LXMOD", sizeof("$LXMOD") - 1, &value,
 932                          sizeof(value), 0);
 933        if (err)
 934                goto out;
 935
 936        if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) {
 937                value = cpu_to_le32(inode->i_rdev);
 938                err = ntfs_set_ea(inode, "$LXDEV", sizeof("$LXDEV") - 1, &value,
 939                                  sizeof(value), 0);
 940                if (err)
 941                        goto out;
 942        }
 943
 944out:
 945        /* In case of error should we delete all WSL xattr? */
 946        return err;
 947}
 948
 949/*
 950 * ntfs_get_wsl_perm
 951 *
 952 * get uid/gid/mode from xattr
 953 * it is called from ntfs_iget5->ntfs_read_mft
 954 */
 955void ntfs_get_wsl_perm(struct inode *inode)
 956{
 957        size_t sz;
 958        __le32 value[3];
 959
 960        if (ntfs_get_ea(inode, "$LXUID", sizeof("$LXUID") - 1, &value[0],
 961                        sizeof(value[0]), &sz) == sizeof(value[0]) &&
 962            ntfs_get_ea(inode, "$LXGID", sizeof("$LXGID") - 1, &value[1],
 963                        sizeof(value[1]), &sz) == sizeof(value[1]) &&
 964            ntfs_get_ea(inode, "$LXMOD", sizeof("$LXMOD") - 1, &value[2],
 965                        sizeof(value[2]), &sz) == sizeof(value[2])) {
 966                i_uid_write(inode, (uid_t)le32_to_cpu(value[0]));
 967                i_gid_write(inode, (gid_t)le32_to_cpu(value[1]));
 968                inode->i_mode = le32_to_cpu(value[2]);
 969
 970                if (ntfs_get_ea(inode, "$LXDEV", sizeof("$$LXDEV") - 1,
 971                                &value[0], sizeof(value),
 972                                &sz) == sizeof(value[0])) {
 973                        inode->i_rdev = le32_to_cpu(value[0]);
 974                }
 975        }
 976}
 977
 978static bool ntfs_xattr_user_list(struct dentry *dentry)
 979{
 980        return true;
 981}
 982
 983// clang-format off
 984static const struct xattr_handler ntfs_xattr_handler = {
 985        .prefix = "",
 986        .get    = ntfs_getxattr,
 987        .set    = ntfs_setxattr,
 988        .list   = ntfs_xattr_user_list,
 989};
 990
 991const struct xattr_handler *ntfs_xattr_handlers[] = {
 992        &ntfs_xattr_handler,
 993        NULL,
 994};
 995// clang-format on
 996