1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Pocessing of EA's
4 *
5 * Part of this file is based on code from the NTFS-3G.
6 *
7 * Copyright (c) 2014-2021 Jean-Pierre Andre
8 * Copyright (c) 2025 LG Electronics Co., Ltd.
9 */
10
11 #include <linux/fs.h>
12 #include <linux/posix_acl.h>
13 #include <linux/posix_acl_xattr.h>
14 #include <linux/xattr.h>
15
16 #include "layout.h"
17 #include "attrib.h"
18 #include "index.h"
19 #include "dir.h"
20 #include "ea.h"
21
ntfs_write_ea(struct ntfs_inode * ni,__le32 type,char * value,s64 ea_off,s64 ea_size,bool need_truncate)22 static int ntfs_write_ea(struct ntfs_inode *ni, __le32 type, char *value, s64 ea_off,
23 s64 ea_size, bool need_truncate)
24 {
25 struct inode *ea_vi;
26 int err = 0;
27 s64 written;
28
29 ea_vi = ntfs_attr_iget(VFS_I(ni), type, AT_UNNAMED, 0);
30 if (IS_ERR(ea_vi))
31 return PTR_ERR(ea_vi);
32
33 written = ntfs_inode_attr_pwrite(ea_vi, ea_off, ea_size, value, false);
34 if (written != ea_size)
35 err = -EIO;
36 else {
37 struct ntfs_inode *ea_ni = NTFS_I(ea_vi);
38
39 if (need_truncate && ea_ni->data_size > ea_off + ea_size)
40 ntfs_attr_truncate(ea_ni, ea_off + ea_size);
41 mark_mft_record_dirty(ni);
42 }
43
44 iput(ea_vi);
45 return err;
46 }
47
ntfs_ea_lookup(char * ea_buf,s64 ea_buf_size,const char * name,int name_len,s64 * ea_offset,s64 * ea_size)48 static int ntfs_ea_lookup(char *ea_buf, s64 ea_buf_size, const char *name,
49 int name_len, s64 *ea_offset, s64 *ea_size)
50 {
51 const struct ea_attr *p_ea;
52 size_t actual_size;
53 loff_t offset, p_ea_size;
54 unsigned int next;
55
56 offset = 0;
57 do {
58 if (ea_buf_size - offset < sizeof(struct ea_attr))
59 break;
60
61 p_ea = (const struct ea_attr *)&ea_buf[offset];
62 next = le32_to_cpu(p_ea->next_entry_offset);
63 p_ea_size = next ? next : (ea_buf_size - offset);
64
65 if (p_ea_size < sizeof(struct ea_attr) ||
66 offset + p_ea_size > ea_buf_size)
67 break;
68
69 if ((s64)p_ea->ea_name_length + 1 >
70 p_ea_size - offsetof(struct ea_attr, ea_name))
71 break;
72
73 actual_size = ALIGN(struct_size(p_ea, ea_name, 1 + p_ea->ea_name_length +
74 le16_to_cpu(p_ea->ea_value_length)), 4);
75 if (actual_size > p_ea_size)
76 break;
77
78 if (p_ea->ea_name_length == name_len &&
79 !memcmp(p_ea->ea_name, name, name_len)) {
80 *ea_offset = offset;
81 *ea_size = next ? next : actual_size;
82
83 if (ea_buf_size < *ea_offset + *ea_size)
84 goto out;
85
86 return 0;
87 }
88 offset += next;
89 } while (next > 0 && offset < ea_buf_size);
90
91 out:
92 return -ENOENT;
93 }
94
95 /*
96 * Return the existing EA
97 *
98 * The EA_INFORMATION is not examined and the consistency of the
99 * existing EA is not checked.
100 *
101 * If successful, the full attribute is returned unchanged
102 * and its size is returned.
103 * If the designated buffer is too small, the needed size is
104 * returned, and the buffer is left unchanged.
105 * If there is an error, a negative value is returned and errno
106 * is set according to the error.
107 */
ntfs_get_ea(struct inode * inode,const char * name,size_t name_len,void * buffer,size_t size)108 static int ntfs_get_ea(struct inode *inode, const char *name, size_t name_len,
109 void *buffer, size_t size)
110 {
111 struct ntfs_inode *ni = NTFS_I(inode);
112 const struct ea_attr *p_ea;
113 char *ea_buf;
114 s64 ea_off, ea_size, all_ea_size, ea_info_size;
115 int err;
116 u32 ea_info_qlen;
117 u16 ea_value_len;
118 struct ea_information *p_ea_info;
119
120 if (!NInoHasEA(ni))
121 return -ENODATA;
122
123 p_ea_info = ntfs_attr_readall(ni, AT_EA_INFORMATION, NULL, 0,
124 &ea_info_size);
125 if (IS_ERR(p_ea_info))
126 return PTR_ERR(p_ea_info);
127 if (ea_info_size != sizeof(struct ea_information)) {
128 kvfree(p_ea_info);
129 return -EIO;
130 }
131
132 ea_info_qlen = le32_to_cpu(p_ea_info->ea_query_length);
133 kvfree(p_ea_info);
134
135 ea_buf = ntfs_attr_readall(ni, AT_EA, NULL, 0, &all_ea_size);
136 if (IS_ERR(ea_buf))
137 return PTR_ERR(ea_buf);
138
139 if (ea_info_qlen > all_ea_size) {
140 err = -EIO;
141 goto free_ea_buf;
142 }
143
144 err = ntfs_ea_lookup(ea_buf, ea_info_qlen, name, name_len, &ea_off,
145 &ea_size);
146 if (!err) {
147 p_ea = (struct ea_attr *)&ea_buf[ea_off];
148 ea_value_len = le16_to_cpu(p_ea->ea_value_length);
149 if (!buffer) {
150 kvfree(ea_buf);
151 return ea_value_len;
152 }
153
154 if (ea_value_len > size) {
155 err = -ERANGE;
156 goto free_ea_buf;
157 }
158
159 memcpy(buffer, &p_ea->ea_name[p_ea->ea_name_length + 1],
160 ea_value_len);
161 kvfree(ea_buf);
162 return ea_value_len;
163 }
164
165 err = -ENODATA;
166 free_ea_buf:
167 kvfree(ea_buf);
168 return err;
169 }
170
ea_packed_size(const struct ea_attr * p_ea)171 static inline int ea_packed_size(const struct ea_attr *p_ea)
172 {
173 /*
174 * 4 bytes for header (flags and lengths) + name length + 1 +
175 * value length.
176 */
177 return 5 + p_ea->ea_name_length + le16_to_cpu(p_ea->ea_value_length);
178 }
179
180 /*
181 * Set a new EA, and set EA_INFORMATION accordingly
182 *
183 * This is roughly the same as ZwSetEaFile() on Windows, however
184 * the "offset to next" of the last EA should not be cleared.
185 *
186 * Consistency of the new EA is first checked.
187 *
188 * EA_INFORMATION is set first, and it is restored to its former
189 * state if setting EA fails.
190 */
ntfs_set_ea(struct inode * inode,const char * name,size_t name_len,const void * value,size_t val_size,int flags,__le16 * packed_ea_size)191 static int ntfs_set_ea(struct inode *inode, const char *name, size_t name_len,
192 const void *value, size_t val_size, int flags,
193 __le16 *packed_ea_size)
194 {
195 struct ntfs_inode *ni = NTFS_I(inode);
196 struct ea_information *p_ea_info = NULL;
197 int ea_packed, err = 0;
198 struct ea_attr *p_ea;
199 u32 ea_info_qsize = 0;
200 char *ea_buf = NULL;
201 char *new_ea_buf;
202 char *old_ea_buf = NULL;
203 struct ea_information old_ea_info;
204 size_t new_ea_size = ALIGN(struct_size(p_ea, ea_name, 1 + name_len + val_size), 4);
205 s64 ea_off, ea_info_size, all_ea_size, ea_size;
206
207 if (name_len > 255)
208 return -ENAMETOOLONG;
209
210 if (ntfs_attr_exist(ni, AT_EA_INFORMATION, AT_UNNAMED, 0)) {
211 p_ea_info = ntfs_attr_readall(ni, AT_EA_INFORMATION, NULL, 0,
212 &ea_info_size);
213 if (IS_ERR(p_ea_info)) {
214 err = PTR_ERR(p_ea_info);
215 p_ea_info = NULL;
216 goto out;
217 }
218 if (ea_info_size != sizeof(struct ea_information)) {
219 err = -EIO;
220 goto out;
221 }
222
223 ea_buf = ntfs_attr_readall(ni, AT_EA, NULL, 0, &all_ea_size);
224 if (IS_ERR(ea_buf)) {
225 err = PTR_ERR(ea_buf);
226 ea_buf = NULL;
227 goto out;
228 }
229 if (!ea_buf) {
230 ea_info_qsize = 0;
231 kvfree(p_ea_info);
232 goto create_ea_info;
233 }
234
235 ea_info_qsize = le32_to_cpu(p_ea_info->ea_query_length);
236 } else {
237 create_ea_info:
238 p_ea_info = kzalloc_obj(struct ea_information, GFP_NOFS);
239 if (!p_ea_info)
240 return -ENOMEM;
241
242 ea_info_qsize = 0;
243 err = ntfs_attr_add(ni, AT_EA_INFORMATION, AT_UNNAMED, 0,
244 (char *)p_ea_info, sizeof(struct ea_information));
245 if (err)
246 goto out;
247
248 if (ntfs_attr_exist(ni, AT_EA, AT_UNNAMED, 0)) {
249 err = ntfs_attr_remove(ni, AT_EA, AT_UNNAMED, 0);
250 if (err)
251 goto out;
252 }
253
254 goto alloc_new_ea;
255 }
256
257 if (ea_info_qsize > all_ea_size) {
258 err = -EIO;
259 goto out;
260 }
261
262 err = ntfs_ea_lookup(ea_buf, ea_info_qsize, name, name_len, &ea_off,
263 &ea_size);
264 if (ea_info_qsize && !err) {
265 if (flags & XATTR_CREATE) {
266 err = -EEXIST;
267 goto out;
268 }
269 if ((flags & XATTR_REPLACE) && !val_size) {
270 old_ea_info = *p_ea_info;
271 old_ea_buf = kvmemdup(ea_buf, all_ea_size, GFP_NOFS);
272 if (!old_ea_buf) {
273 err = -ENOMEM;
274 goto out;
275 }
276 }
277
278 /* Check the final $EA size before removing the old entry. */
279 if (val_size &&
280 ntfs_attr_size_bounds_check(ni->vol, AT_EA,
281 ea_info_qsize - ea_size + new_ea_size)) {
282 err = -EFBIG;
283 goto out;
284 }
285
286 p_ea = (struct ea_attr *)(ea_buf + ea_off);
287
288 if (val_size &&
289 le16_to_cpu(p_ea->ea_value_length) == val_size &&
290 !memcmp(p_ea->ea_name + p_ea->ea_name_length + 1, value,
291 val_size))
292 goto out;
293
294 le16_add_cpu(&p_ea_info->ea_length, 0 - ea_packed_size(p_ea));
295
296 if (p_ea->flags & NEED_EA)
297 le16_add_cpu(&p_ea_info->need_ea_count, -1);
298
299 memmove((char *)p_ea, (char *)p_ea + ea_size, ea_info_qsize - (ea_off + ea_size));
300 ea_info_qsize -= ea_size;
301 p_ea_info->ea_query_length = cpu_to_le32(ea_info_qsize);
302
303 if ((flags & XATTR_REPLACE) && !val_size && !ea_info_qsize) {
304 err = ntfs_attr_remove(ni, AT_EA, AT_UNNAMED, 0);
305 if (err)
306 goto out;
307
308 err = ntfs_attr_remove(ni, AT_EA_INFORMATION, AT_UNNAMED, 0);
309 if (err) {
310 /* Restore the original $EA if $EA_INFORMATION removal failed. */
311 ntfs_attr_add(ni, AT_EA, AT_UNNAMED, 0, old_ea_buf,
312 all_ea_size);
313 ea_info_qsize = le32_to_cpu(old_ea_info.ea_query_length);
314 }
315 goto out;
316 }
317
318 if ((flags & XATTR_REPLACE) && !val_size) {
319 err = ntfs_write_ea(ni, AT_EA, ea_buf, 0, ea_info_qsize,
320 true);
321 if (err) {
322 ntfs_write_ea(ni, AT_EA, old_ea_buf, 0,
323 all_ea_size, false);
324 goto out;
325 }
326
327 err = ntfs_write_ea(ni, AT_EA_INFORMATION, (char *)p_ea_info,
328 0, sizeof(struct ea_information), false);
329 if (err) {
330 ntfs_write_ea(ni, AT_EA, old_ea_buf, 0,
331 all_ea_size, false);
332 ntfs_write_ea(ni, AT_EA_INFORMATION,
333 (char *)&old_ea_info, 0,
334 sizeof(old_ea_info), false);
335 }
336 goto out;
337 }
338 } else {
339 if (flags & XATTR_REPLACE) {
340 err = -ENODATA;
341 goto out;
342 }
343
344 if (ntfs_attr_size_bounds_check(ni->vol, AT_EA,
345 ea_info_qsize + new_ea_size)) {
346 err = -EFBIG;
347 goto out;
348 }
349 }
350 alloc_new_ea:
351 new_ea_buf = kvzalloc(ea_info_qsize + new_ea_size, GFP_NOFS);
352 if (!new_ea_buf) {
353 err = -ENOMEM;
354 goto out;
355 }
356 if (ea_info_qsize)
357 memcpy(new_ea_buf, ea_buf, ea_info_qsize);
358 kvfree(ea_buf);
359 ea_buf = new_ea_buf;
360 p_ea = (struct ea_attr *)(ea_buf + ea_info_qsize);
361
362 /*
363 * EA and REPARSE_POINT compatibility not checked any more,
364 * required by Windows 10, but having both may lead to
365 * problems with earlier versions.
366 */
367 memcpy(p_ea->ea_name, name, name_len);
368 p_ea->ea_name_length = name_len;
369 p_ea->ea_name[name_len] = 0;
370 memcpy(p_ea->ea_name + name_len + 1, value, val_size);
371 p_ea->ea_value_length = cpu_to_le16(val_size);
372 p_ea->next_entry_offset = cpu_to_le32(new_ea_size);
373
374 ea_packed = le16_to_cpu(p_ea_info->ea_length) + ea_packed_size(p_ea);
375 p_ea_info->ea_length = cpu_to_le16(ea_packed);
376 p_ea_info->ea_query_length = cpu_to_le32(ea_info_qsize + new_ea_size);
377
378 if (ea_packed > 0xffff) {
379 err = -EFBIG;
380 goto out;
381 }
382
383 /*
384 * no EA or EA_INFORMATION : add them
385 */
386 if (!ntfs_attr_exist(ni, AT_EA, AT_UNNAMED, 0)) {
387 err = ntfs_attr_add(ni, AT_EA, AT_UNNAMED, 0, ea_buf,
388 ea_info_qsize + new_ea_size);
389 if (err)
390 goto out;
391 } else {
392 err = ntfs_write_ea(ni, AT_EA, ea_buf, 0,
393 ea_info_qsize + new_ea_size, true);
394 if (err)
395 goto out;
396 }
397
398 err = ntfs_write_ea(ni, AT_EA_INFORMATION, (char *)p_ea_info, 0,
399 sizeof(struct ea_information), false);
400 if (err)
401 goto out;
402
403 if (packed_ea_size)
404 *packed_ea_size = p_ea_info->ea_length;
405 mark_mft_record_dirty(ni);
406 out:
407 if (!err) {
408 if (ea_info_qsize > 0)
409 NInoSetHasEA(ni);
410 else
411 NInoClearHasEA(ni);
412 }
413
414 kvfree(ea_buf);
415 kvfree(old_ea_buf);
416 kvfree(p_ea_info);
417
418 return err;
419 }
420
421 /*
422 * Check for the presence of an EA "$LXDEV" (used by WSL)
423 * and return its value as a device address
424 */
ntfs_ea_get_wsl_inode(struct inode * inode,dev_t * rdevp,unsigned int flags,bool * has_lxmod)425 int ntfs_ea_get_wsl_inode(struct inode *inode, dev_t *rdevp, unsigned int flags,
426 bool *has_lxmod)
427 {
428 int err;
429 __le32 v;
430
431 *has_lxmod = false;
432
433 if (!(flags & NTFS_VOL_UID)) {
434 /* Load uid to lxuid EA */
435 err = ntfs_get_ea(inode, "$LXUID", sizeof("$LXUID") - 1, &v,
436 sizeof(v));
437 if (err == sizeof(v))
438 i_uid_write(inode, le32_to_cpu(v));
439 }
440
441 if (!(flags & NTFS_VOL_GID)) {
442 /* Load gid to lxgid EA */
443 err = ntfs_get_ea(inode, "$LXGID", sizeof("$LXGID") - 1, &v,
444 sizeof(v));
445 if (err == sizeof(v))
446 i_gid_write(inode, le32_to_cpu(v));
447 }
448
449 /* Load mode to lxmod EA */
450 err = ntfs_get_ea(inode, "$LXMOD", sizeof("$LXMOD") - 1, &v, sizeof(v));
451 if (err == sizeof(v)) {
452 inode->i_mode = le32_to_cpu(v);
453 *has_lxmod = true;
454 } else {
455 /* Everyone gets all permissions. */
456 inode->i_mode |= 0777;
457 }
458
459 /* Load mode to lxdev EA */
460 err = ntfs_get_ea(inode, "$LXDEV", sizeof("$LXDEV") - 1, &v, sizeof(v));
461 if (err == sizeof(v))
462 *rdevp = le32_to_cpu(v);
463 err = 0;
464
465 return err;
466 }
467
ntfs_ea_set_wsl_inode(struct inode * inode,dev_t rdev,__le16 * ea_size,unsigned int flags)468 int ntfs_ea_set_wsl_inode(struct inode *inode, dev_t rdev, __le16 *ea_size,
469 unsigned int flags)
470 {
471 __le32 v;
472 int err = 0;
473
474 if (ea_size)
475 *ea_size = 0;
476
477 if (flags & NTFS_EA_UID) {
478 /* Store uid to lxuid EA */
479 v = cpu_to_le32(i_uid_read(inode));
480 err = ntfs_set_ea(inode, "$LXUID", sizeof("$LXUID") - 1, &v,
481 sizeof(v), 0, ea_size);
482 if (err)
483 return err;
484 }
485
486 if (flags & NTFS_EA_GID) {
487 /* Store gid to lxgid EA */
488 v = cpu_to_le32(i_gid_read(inode));
489 err = ntfs_set_ea(inode, "$LXGID", sizeof("$LXGID") - 1, &v,
490 sizeof(v), 0, ea_size);
491 if (err)
492 return err;
493 }
494
495 if (flags & NTFS_EA_MODE) {
496 /* Store mode to lxmod EA */
497 v = cpu_to_le32(inode->i_mode);
498 err = ntfs_set_ea(inode, "$LXMOD", sizeof("$LXMOD") - 1, &v,
499 sizeof(v), 0, ea_size);
500 if (err)
501 return err;
502 }
503
504 if (rdev) {
505 v = cpu_to_le32(rdev);
506 err = ntfs_set_ea(inode, "$LXDEV", sizeof("$LXDEV") - 1, &v, sizeof(v),
507 0, ea_size);
508 }
509
510 return err;
511 }
512
ntfs_listxattr(struct dentry * dentry,char * buffer,size_t size)513 ssize_t ntfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
514 {
515 struct inode *inode = d_inode(dentry);
516 struct ntfs_inode *ni = NTFS_I(inode);
517 const struct ea_attr *p_ea;
518 s64 offset, ea_buf_size, ea_info_size;
519 s64 ea_size;
520 u32 next;
521 int err = 0;
522 u32 ea_info_qsize;
523 char *ea_buf = NULL;
524 ssize_t ret = 0;
525 struct ea_information *ea_info;
526
527 if (!NInoHasEA(ni))
528 return 0;
529
530 mutex_lock(&NTFS_I(inode)->mrec_lock);
531 ea_info = ntfs_attr_readall(ni, AT_EA_INFORMATION, NULL, 0,
532 &ea_info_size);
533 if (IS_ERR(ea_info)) {
534 err = PTR_ERR(ea_info);
535 ea_info = NULL;
536 goto out;
537 }
538 if (ea_info_size != sizeof(struct ea_information)) {
539 err = -EIO;
540 goto out;
541 }
542
543 ea_info_qsize = le32_to_cpu(ea_info->ea_query_length);
544
545 ea_buf = ntfs_attr_readall(ni, AT_EA, NULL, 0, &ea_buf_size);
546 if (IS_ERR(ea_buf)) {
547 err = PTR_ERR(ea_buf);
548 ea_buf = NULL;
549 goto out;
550 }
551
552 if (ea_info_qsize > ea_buf_size || ea_info_qsize == 0)
553 goto out;
554
555 offset = 0;
556 do {
557 if (ea_info_qsize - offset < sizeof(struct ea_attr)) {
558 err = -EIO;
559 goto out;
560 }
561
562 p_ea = (const struct ea_attr *)&ea_buf[offset];
563 next = le32_to_cpu(p_ea->next_entry_offset);
564 ea_size = next ? next : (ea_info_qsize - offset);
565
566 if (ea_size < sizeof(struct ea_attr) ||
567 offset + ea_size > ea_info_qsize) {
568 err = -EIO;
569 goto out;
570 }
571
572 if ((int)p_ea->ea_name_length + 1 >
573 ea_size - offsetof(struct ea_attr, ea_name)) {
574 err = -EIO;
575 goto out;
576 }
577
578 if (buffer) {
579 if (ret + p_ea->ea_name_length + 1 > size) {
580 err = -ERANGE;
581 goto out;
582 }
583
584 memcpy(buffer + ret, p_ea->ea_name, p_ea->ea_name_length);
585 buffer[ret + p_ea->ea_name_length] = 0;
586 }
587
588 ret += p_ea->ea_name_length + 1;
589 offset += ea_size;
590 } while (next > 0 && offset < ea_info_qsize);
591
592 out:
593 mutex_unlock(&NTFS_I(inode)->mrec_lock);
594 kvfree(ea_info);
595 kvfree(ea_buf);
596
597 return err ? err : ret;
598 }
599
600 // clang-format off
601 #define SYSTEM_DOS_ATTRIB "system.dos_attrib"
602 #define SYSTEM_NTFS_ATTRIB "system.ntfs_attrib"
603 #define SYSTEM_NTFS_ATTRIB_BE "system.ntfs_attrib_be"
604 // clang-format on
605
ntfs_getxattr(const struct xattr_handler * handler,struct dentry * unused,struct inode * inode,const char * name,void * buffer,size_t size)606 static int ntfs_getxattr(const struct xattr_handler *handler,
607 struct dentry *unused, struct inode *inode, const char *name,
608 void *buffer, size_t size)
609 {
610 struct ntfs_inode *ni = NTFS_I(inode);
611 int err;
612
613 if (NVolShutdown(ni->vol))
614 return -EIO;
615
616 if (!strcmp(name, SYSTEM_DOS_ATTRIB)) {
617 if (!buffer) {
618 err = sizeof(u8);
619 } else if (size < sizeof(u8)) {
620 err = -ERANGE;
621 } else {
622 err = sizeof(u8);
623 *(u8 *)buffer = (u8)(le32_to_cpu(ni->flags) & 0x3F);
624 }
625 goto out;
626 }
627
628 if (!strcmp(name, SYSTEM_NTFS_ATTRIB) ||
629 !strcmp(name, SYSTEM_NTFS_ATTRIB_BE)) {
630 if (!buffer) {
631 err = sizeof(u32);
632 } else if (size < sizeof(u32)) {
633 err = -ERANGE;
634 } else {
635 err = sizeof(u32);
636 *(u32 *)buffer = le32_to_cpu(ni->flags);
637 if (!strcmp(name, SYSTEM_NTFS_ATTRIB_BE))
638 *(__be32 *)buffer = cpu_to_be32(*(u32 *)buffer);
639 }
640 goto out;
641 }
642
643 mutex_lock(&ni->mrec_lock);
644 err = ntfs_get_ea(inode, name, strlen(name), buffer, size);
645 mutex_unlock(&ni->mrec_lock);
646
647 out:
648 return err;
649 }
650
ntfs_new_attr_flags(struct ntfs_inode * ni,__le32 fattr)651 static int ntfs_new_attr_flags(struct ntfs_inode *ni, __le32 fattr)
652 {
653 struct ntfs_attr_search_ctx *ctx;
654 struct mft_record *m;
655 struct attr_record *a;
656 __le16 new_aflags;
657 u16 old_name_ofs, old_mp_ofs;
658 int mp_size, mp_ofs, name_ofs, old_arec_size, arec_size, err;
659
660 m = map_mft_record(ni);
661 if (IS_ERR(m))
662 return PTR_ERR(m);
663
664 ctx = ntfs_attr_get_search_ctx(ni, m);
665 if (!ctx) {
666 err = -ENOMEM;
667 goto err_out;
668 }
669
670 err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
671 CASE_SENSITIVE, 0, NULL, 0, ctx);
672 if (err) {
673 err = -EINVAL;
674 goto err_out;
675 }
676
677 a = ctx->attr;
678 new_aflags = ctx->attr->flags;
679
680 if (fattr & FILE_ATTR_SPARSE_FILE)
681 new_aflags |= ATTR_IS_SPARSE;
682 else
683 new_aflags &= ~ATTR_IS_SPARSE;
684
685 if (fattr & FILE_ATTR_COMPRESSED)
686 new_aflags |= ATTR_IS_COMPRESSED;
687 else
688 new_aflags &= ~ATTR_IS_COMPRESSED;
689
690 if (new_aflags == a->flags) {
691 err = 0;
692 goto err_out;
693 }
694
695 if ((new_aflags & (ATTR_IS_SPARSE | ATTR_IS_COMPRESSED)) ==
696 (ATTR_IS_SPARSE | ATTR_IS_COMPRESSED)) {
697 pr_err("file can't be sparsed and compressed\n");
698 err = -EOPNOTSUPP;
699 goto err_out;
700 }
701
702 if (!a->non_resident) {
703 if (!(new_aflags & (ATTR_IS_SPARSE | ATTR_IS_COMPRESSED))) {
704 err = 0;
705 goto err_out;
706 }
707
708 if (le32_to_cpu(a->data.resident.value_length)) {
709 pr_err("Can't change sparse/compressed for non-empty file");
710 err = -EOPNOTSUPP;
711 goto err_out;
712 }
713
714 err = ntfs_attr_make_non_resident(ni, 0);
715 if (err)
716 goto err_out;
717
718 ntfs_attr_reinit_search_ctx(ctx);
719 err = ntfs_attr_lookup(ni->type, ni->name,
720 ni->name_len, CASE_SENSITIVE,
721 0, NULL, 0, ctx);
722 if (err) {
723 err = -EINVAL;
724 goto err_out;
725 }
726 a = ctx->attr;
727 } else {
728 if (a->data.non_resident.data_size) {
729 pr_err("Can't change sparsed/compressed for non-empty file");
730 err = -EOPNOTSUPP;
731 goto err_out;
732 }
733 }
734
735 old_name_ofs = le16_to_cpu(a->name_offset);
736 old_mp_ofs = le16_to_cpu(a->data.non_resident.mapping_pairs_offset);
737
738 if (new_aflags & (ATTR_IS_SPARSE | ATTR_IS_COMPRESSED))
739 name_ofs = (offsetof(struct attr_record,
740 data.non_resident.compressed_size) +
741 sizeof(a->data.non_resident.compressed_size) + 7) & ~7;
742 else
743 name_ofs = (offsetof(struct attr_record,
744 data.non_resident.compressed_size) + 7) & ~7;
745
746 mp_size = ntfs_get_size_for_mapping_pairs(ni->vol, ni->runlist.rl, 0, -1, -1);
747 if (unlikely(mp_size < 0)) {
748 err = mp_size;
749 ntfs_debug("Failed to get size for mapping pairs array, error code %i.\n", err);
750 goto err_out;
751 }
752
753 mp_ofs = (name_ofs + a->name_length * sizeof(__le16) + 7) & ~7;
754 arec_size = (mp_ofs + mp_size + 7) & ~7;
755 old_arec_size = le32_to_cpu(a->length);
756
757 /*
758 * Move payloads before shrinking the record. Otherwise resizing moves
759 * the following attribute over the old payload before it can be copied.
760 *
761 * When offsets increase, move mapping_pairs first to avoid name
762 * overwriting the start of mapping_pairs.
763 */
764 if (arec_size < old_arec_size) {
765 if (name_ofs > old_name_ofs) {
766 /* Payload offsets increased: move mapping pairs first. */
767 if (mp_ofs != old_mp_ofs)
768 memmove((u8 *)a + mp_ofs,
769 (u8 *)a + old_mp_ofs,
770 mp_size);
771 if (a->name_length && name_ofs != old_name_ofs)
772 memmove((u8 *)a + name_ofs,
773 (u8 *)a + old_name_ofs,
774 a->name_length *
775 sizeof(__le16));
776 } else {
777 /* Payload offsets decreased or unchanged: move name first. */
778 if (a->name_length && name_ofs != old_name_ofs)
779 memmove((u8 *)a + name_ofs,
780 (u8 *)a + old_name_ofs,
781 a->name_length *
782 sizeof(__le16));
783 if (mp_ofs != old_mp_ofs)
784 memmove((u8 *)a + mp_ofs,
785 (u8 *)a + old_mp_ofs,
786 mp_size);
787 }
788 }
789
790 err = ntfs_attr_record_resize(ctx->mrec, a, arec_size);
791 if (unlikely(err))
792 goto err_out;
793
794 /*
795 * When compressed/sparse state changes, the non-resident header grows or
796 * shrinks by the compressed_size field. Update the in-record payload layout
797 * to match the new offsets before exposing the new mapping_pairs_offset.
798 */
799 if (arec_size > old_arec_size) {
800 if (mp_ofs != old_mp_ofs)
801 memmove((u8 *)a + mp_ofs, (u8 *)a + old_mp_ofs, mp_size);
802 if (a->name_length)
803 memmove((u8 *)a + name_ofs, (u8 *)a + old_name_ofs,
804 a->name_length * sizeof(__le16));
805 }
806
807 if (new_aflags & (ATTR_IS_SPARSE | ATTR_IS_COMPRESSED)) {
808 a->data.non_resident.compression_unit = 0;
809 if (new_aflags & ATTR_IS_COMPRESSED || ni->vol->major_ver < 3)
810 a->data.non_resident.compression_unit = 4;
811 a->data.non_resident.compressed_size = 0;
812 ni->itype.compressed.size = 0;
813 if (a->data.non_resident.compression_unit) {
814 ni->itype.compressed.block_size = 1U <<
815 (a->data.non_resident.compression_unit +
816 ni->vol->cluster_size_bits);
817 ni->itype.compressed.block_size_bits =
818 ffs(ni->itype.compressed.block_size) -
819 1;
820 ni->itype.compressed.block_clusters = 1U <<
821 a->data.non_resident.compression_unit;
822 } else {
823 ni->itype.compressed.block_size = 0;
824 ni->itype.compressed.block_size_bits = 0;
825 ni->itype.compressed.block_clusters = 0;
826 }
827 } else {
828 a->data.non_resident.compression_unit = 0;
829 }
830
831 a->name_offset = cpu_to_le16(name_ofs);
832 a->data.non_resident.mapping_pairs_offset = cpu_to_le16(mp_ofs);
833
834 a->flags = new_aflags;
835
836 if (new_aflags & ATTR_IS_SPARSE) {
837 NInoSetSparse(ni);
838 ni->flags |= FILE_ATTR_SPARSE_FILE;
839 } else {
840 NInoClearSparse(ni);
841 ni->flags &= ~FILE_ATTR_SPARSE_FILE;
842 }
843
844 if (new_aflags & ATTR_IS_COMPRESSED) {
845 NInoSetCompressed(ni);
846 ni->flags |= FILE_ATTR_COMPRESSED;
847 } else {
848 NInoClearCompressed(ni);
849 ni->flags &= ~FILE_ATTR_COMPRESSED;
850 }
851
852 mark_mft_record_dirty(ctx->ntfs_ino);
853 err_out:
854 if (ctx)
855 ntfs_attr_put_search_ctx(ctx);
856 unmap_mft_record(ni);
857 return err;
858 }
859
ntfs_is_reserved_lxattr(const char * name)860 static bool ntfs_is_reserved_lxattr(const char *name)
861 {
862 return !strcmp(name, "$LXUID") || !strcmp(name, "$LXGID") ||
863 !strcmp(name, "$LXMOD") || !strcmp(name, "$LXDEV");
864 }
865
ntfs_validate_fattr(struct ntfs_inode * ni,__le32 fattr)866 static int ntfs_validate_fattr(struct ntfs_inode *ni, __le32 fattr)
867 {
868 const __le32 wof_flags = FILE_ATTR_SPARSE_FILE |
869 FILE_ATTR_REPARSE_POINT;
870
871 if (NInoWofCompressed(ni) && ((ni->flags ^ fattr) & wof_flags))
872 return -EPERM;
873
874 return 0;
875 }
876
ntfs_setxattr(const struct xattr_handler * handler,struct mnt_idmap * idmap,struct dentry * unused,struct inode * inode,const char * name,const void * value,size_t size,int flags)877 static int ntfs_setxattr(const struct xattr_handler *handler,
878 struct mnt_idmap *idmap, struct dentry *unused,
879 struct inode *inode, const char *name, const void *value,
880 size_t size, int flags)
881 {
882 struct ntfs_inode *ni = NTFS_I(inode);
883 int err;
884 __le32 fattr;
885
886 if (NVolShutdown(ni->vol))
887 return -EIO;
888
889 if (ntfs_is_reserved_lxattr(name) && !capable(CAP_SYS_ADMIN))
890 return -EPERM;
891
892 if (!strcmp(name, SYSTEM_DOS_ATTRIB)) {
893 if (sizeof(u8) != size) {
894 err = -EINVAL;
895 goto out;
896 }
897 fattr = cpu_to_le32((le32_to_cpu(ni->flags) & ~0xffU) |
898 *(u8 *)value);
899 goto set_fattr;
900 }
901
902 if (!strcmp(name, SYSTEM_NTFS_ATTRIB) ||
903 !strcmp(name, SYSTEM_NTFS_ATTRIB_BE)) {
904 if (size != sizeof(u32)) {
905 err = -EINVAL;
906 goto out;
907 }
908 if (!strcmp(name, SYSTEM_NTFS_ATTRIB_BE))
909 fattr = cpu_to_le32(be32_to_cpu(*(__be32 *)value));
910 else
911 fattr = cpu_to_le32(*(u32 *)value);
912
913 err = ntfs_validate_fattr(ni, fattr);
914 if (err)
915 goto out;
916
917 if (S_ISREG(inode->i_mode)) {
918 mutex_lock(&ni->mrec_lock);
919 err = ntfs_new_attr_flags(ni, fattr);
920 mutex_unlock(&ni->mrec_lock);
921 if (err)
922 goto out;
923 }
924
925 set_fattr:
926 if (S_ISDIR(inode->i_mode))
927 fattr |= FILE_ATTR_DIRECTORY;
928 else
929 fattr &= ~FILE_ATTR_DIRECTORY;
930
931 err = ntfs_validate_fattr(ni, fattr);
932 if (err)
933 goto out;
934
935 if (ni->flags != fattr) {
936 ni->flags = fattr;
937 if (fattr & FILE_ATTR_READONLY)
938 inode->i_mode &= ~0222;
939 else
940 inode->i_mode |= 0222;
941 NInoSetFileNameDirty(ni);
942 mark_inode_dirty(inode);
943 }
944 err = 0;
945 goto out;
946 }
947
948 mutex_lock(&ni->mrec_lock);
949 err = ntfs_set_ea(inode, name, strlen(name), value, size, flags, NULL);
950 mutex_unlock(&ni->mrec_lock);
951
952 out:
953 if (!err) {
954 inode_set_ctime_current(inode);
955 mark_inode_dirty(inode);
956 }
957 return err;
958 }
959
ntfs_xattr_user_list(struct dentry * dentry)960 static bool ntfs_xattr_user_list(struct dentry *dentry)
961 {
962 return true;
963 }
964
965 // clang-format off
966 static const struct xattr_handler ntfs_other_xattr_handler = {
967 .prefix = "",
968 .get = ntfs_getxattr,
969 .set = ntfs_setxattr,
970 .list = ntfs_xattr_user_list,
971 };
972
973 const struct xattr_handler * const ntfs_xattr_handlers[] = {
974 &ntfs_other_xattr_handler,
975 NULL,
976 };
977 // clang-format on
978
979 #ifdef CONFIG_NTFS_FS_POSIX_ACL
ntfs_get_acl(struct mnt_idmap * idmap,struct dentry * dentry,int type)980 struct posix_acl *ntfs_get_acl(struct mnt_idmap *idmap, struct dentry *dentry,
981 int type)
982 {
983 struct inode *inode = d_inode(dentry);
984 struct ntfs_inode *ni = NTFS_I(inode);
985 const char *name;
986 size_t name_len;
987 struct posix_acl *acl;
988 int err;
989 void *buf;
990
991 buf = kmalloc(PATH_MAX, GFP_KERNEL);
992 if (!buf)
993 return ERR_PTR(-ENOMEM);
994
995 /* Possible values of 'type' was already checked above. */
996 if (type == ACL_TYPE_ACCESS) {
997 name = XATTR_NAME_POSIX_ACL_ACCESS;
998 name_len = sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1;
999 } else {
1000 name = XATTR_NAME_POSIX_ACL_DEFAULT;
1001 name_len = sizeof(XATTR_NAME_POSIX_ACL_DEFAULT) - 1;
1002 }
1003
1004 mutex_lock(&ni->mrec_lock);
1005 err = ntfs_get_ea(inode, name, name_len, buf, PATH_MAX);
1006 mutex_unlock(&ni->mrec_lock);
1007
1008 /* Translate extended attribute to acl. */
1009 if (err >= 0)
1010 acl = posix_acl_from_xattr(&init_user_ns, buf, err);
1011 else if (err == -ENODATA)
1012 acl = NULL;
1013 else
1014 acl = ERR_PTR(err);
1015
1016 if (!IS_ERR(acl))
1017 set_cached_acl(inode, type, acl);
1018
1019 kfree(buf);
1020
1021 return acl;
1022 }
1023
ntfs_set_acl_ex(struct mnt_idmap * idmap,struct inode * inode,struct posix_acl * acl,int type,bool init_acl)1024 static noinline int ntfs_set_acl_ex(struct mnt_idmap *idmap,
1025 struct inode *inode, struct posix_acl *acl,
1026 int type, bool init_acl)
1027 {
1028 const char *name;
1029 size_t size, name_len;
1030 void *value;
1031 int err;
1032 int flags;
1033 umode_t mode;
1034
1035 if (S_ISLNK(inode->i_mode))
1036 return -EOPNOTSUPP;
1037
1038 mode = inode->i_mode;
1039 switch (type) {
1040 case ACL_TYPE_ACCESS:
1041 /* Do not change i_mode if we are in init_acl */
1042 if (acl && !init_acl) {
1043 err = posix_acl_update_mode(idmap, inode, &mode, &acl);
1044 if (err)
1045 return err;
1046 }
1047 name = XATTR_NAME_POSIX_ACL_ACCESS;
1048 name_len = sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1;
1049 break;
1050
1051 case ACL_TYPE_DEFAULT:
1052 if (!S_ISDIR(inode->i_mode))
1053 return acl ? -EACCES : 0;
1054 name = XATTR_NAME_POSIX_ACL_DEFAULT;
1055 name_len = sizeof(XATTR_NAME_POSIX_ACL_DEFAULT) - 1;
1056 break;
1057
1058 default:
1059 return -EINVAL;
1060 }
1061
1062 if (!acl) {
1063 /* Remove xattr if it can be presented via mode. */
1064 size = 0;
1065 value = NULL;
1066 flags = XATTR_REPLACE;
1067 } else {
1068 value = posix_acl_to_xattr(&init_user_ns, acl, &size, GFP_NOFS);
1069 if (!value)
1070 return -ENOMEM;
1071 flags = 0;
1072 }
1073
1074 mutex_lock(&NTFS_I(inode)->mrec_lock);
1075 err = ntfs_set_ea(inode, name, name_len, value, size, flags, NULL);
1076 mutex_unlock(&NTFS_I(inode)->mrec_lock);
1077 if (err == -ENODATA && !size)
1078 err = 0; /* Removing non existed xattr. */
1079 if (!err) {
1080 __le16 ea_size = 0;
1081 umode_t old_mode = inode->i_mode;
1082
1083 inode->i_mode = mode;
1084 mutex_lock(&NTFS_I(inode)->mrec_lock);
1085 err = ntfs_ea_set_wsl_inode(inode, 0, &ea_size, NTFS_EA_MODE);
1086 if (err) {
1087 ntfs_set_ea(inode, name, name_len, NULL, 0,
1088 XATTR_REPLACE, NULL);
1089 mutex_unlock(&NTFS_I(inode)->mrec_lock);
1090 inode->i_mode = old_mode;
1091 goto out;
1092 }
1093 mutex_unlock(&NTFS_I(inode)->mrec_lock);
1094
1095 set_cached_acl(inode, type, acl);
1096 inode_set_ctime_current(inode);
1097 mark_inode_dirty(inode);
1098 }
1099
1100 out:
1101 kfree(value);
1102
1103 return err;
1104 }
1105
ntfs_set_acl(struct mnt_idmap * idmap,struct dentry * dentry,struct posix_acl * acl,int type)1106 int ntfs_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
1107 struct posix_acl *acl, int type)
1108 {
1109 return ntfs_set_acl_ex(idmap, d_inode(dentry), acl, type, false);
1110 }
1111
ntfs_init_acl(struct mnt_idmap * idmap,struct inode * inode,struct inode * dir)1112 int ntfs_init_acl(struct mnt_idmap *idmap, struct inode *inode,
1113 struct inode *dir)
1114 {
1115 struct posix_acl *default_acl, *acl;
1116 int err;
1117
1118 err = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl);
1119 if (err)
1120 return err;
1121
1122 if (default_acl) {
1123 err = ntfs_set_acl_ex(idmap, inode, default_acl,
1124 ACL_TYPE_DEFAULT, true);
1125 posix_acl_release(default_acl);
1126 } else {
1127 inode->i_default_acl = NULL;
1128 }
1129
1130 if (acl) {
1131 if (!err)
1132 err = ntfs_set_acl_ex(idmap, inode, acl,
1133 ACL_TYPE_ACCESS, true);
1134 posix_acl_release(acl);
1135 } else {
1136 inode->i_acl = NULL;
1137 }
1138
1139 return err;
1140 }
1141 #endif
1142