Changes in 4.9.326 Bluetooth: L2CAP: Fix use-after-free caused by l2cap_chan_put ntfs: fix use-after-free in ntfs_ucsncmp() scsi: ufs: host: Hold reference returned by of_parse_phandle() net: ping6: Fix memleak in ipv6_renew_options(). net: sungem_phy: Add of_node_put() for reference returned by of_get_parent() netfilter: nf_queue: do not allow packet truncation below transport header offset ARM: crypto: comment out gcc warning that breaks clang builds mt7601u: add USB device ID for some versions of XiaoDu WiFi Dongle. ion: Make user_ion_handle_put_nolock() a void function selinux: Minor cleanups proc: Pass file mode to proc_pid_make_inode selinux: Clean up initialization of isec->sclass selinux: Convert isec->lock into a spinlock selinux: fix error initialization in inode_doinit_with_dentry() selinux: fix inode_doinit_with_dentry() LABEL_INVALID error handling include/uapi/linux/swab.h: fix userspace breakage, use __BITS_PER_LONG for swap init/main: Fix double "the" in comment init/main: properly align the multi-line comment init: move stack canary initialization after setup_arch init/main.c: extract early boot entropy from the passed cmdline ACPI: video: Force backlight native for some TongFang devices ACPI: video: Shortening quirk list by identifying Clevo by board_name only random: only call boot_init_stack_canary() once macintosh/adb: fix oob read in do_adb_query() function ALSA: bcd2000: Fix a UAF bug on the error path of probing add barriers to buffer_uptodate and set_buffer_uptodate KVM: SVM: Don't BUG if userspace injects an interrupt with GIF=0 KVM: x86: Mark TSS busy during LTR emulation _after_ all fault checks ALSA: hda/conexant: Add quirk for LENOVO 20149 Notebook model ALSA: hda/cirrus - support for iMac 12,1 model vfs: Check the truncate maximum size in inode_newsize_ok() usbnet: Fix linkwatch use-after-free on disconnect parisc: Fix device names in /proc/iomem drm/nouveau: fix another off-by-one in nvbios_addr bpf: fix overflow in prog accounting fuse: limit nsec md-raid10: fix KASAN warning ia64, processor: fix -Wincompatible-pointer-types in ia64_get_irr() PCI: Add defines for normal and subtractive PCI bridges powerpc/fsl-pci: Fix Class Code of PCIe Root Port powerpc/powernv: Avoid crashing if rng is NULL MIPS: cpuinfo: Fix a warning for CONFIG_CPUMASK_OFFSTACK USB: HCD: Fix URB giveback issue in tasklet function netfilter: nf_tables: fix null deref due to zeroed list head scsi: zfcp: Fix missing auto port scan and thus missing target ports x86/olpc: fix 'logical not is only applied to the left hand side' spmi: trace: fix stack-out-of-bound access in SPMI tracing functions ext4: add EXT4_INODE_HAS_XATTR_SPACE macro in xattr.h ext4: make sure ext4_append() always allocates new block ext4: fix use-after-free in ext4_xattr_set_entry ext4: update s_overhead_clusters in the superblock during an on-line resize ext4: fix extent status tree race in writeback error recovery path ext4: correct max_inline_xattr_value_size computing dm raid: fix address sanitizer warning in raid_status net_sched: cls_route: remove from list when handle is 0 btrfs: reject log replay if there is unsupported RO compat flag tcp: fix over estimation in sk_forced_mem_schedule() scsi: sg: Allow waiting for commands to complete on removed device Revert "net: usb: ax88179_178a needs FLAG_SEND_ZLP" Bluetooth: L2CAP: Fix l2cap_global_chan_by_psm regression nios2: time: Read timer in get_cycles only if initialized net/9p: Initialize the iounit field during fid creation net_sched: cls_route: disallow handle of 0 ALSA: info: Fix llseek return value when using callback rds: add missing barrier to release_refill ata: libata-eh: Add missing command name btrfs: fix lost error handling when looking up extended ref on log replay can: ems_usb: fix clang's -Wunaligned-access warning NFSv4.1: RECLAIM_COMPLETE must handle EACCES SUNRPC: Reinitialise the backchannel request buffers before reuse pinctrl: nomadik: Fix refcount leak in nmk_pinctrl_dt_subnode_to_map pinctrl: qcom: msm8916: Allow CAMSS GP clocks to be muxed vsock: Fix memory leak in vsock_connect() xen/xenbus: fix return type in xenbus_file_read() atm: idt77252: fix use-after-free bugs caused by tst_timer nios2: page fault et.al. are *not* restartable syscalls... nios2: don't leave NULLs in sys_call_table[] nios2: traced syscall does need to check the syscall number nios2: fix syscall restart checks nios2: restarts apply only to the first sigframe we build... nios2: add force_successful_syscall_return() netfilter: nf_tables: really skip inactive sets when allocating name fec: Fix timer capture timing in `fec_ptp_enable_pps()` irqchip/tegra: Fix overflow implicit truncation warnings usb: host: ohci-ppc-of: Fix refcount leak bug gadgetfs: ep_io - wait until IRQ finishes cxl: Fix a memory leak in an error handling path drivers:md:fix a potential use-after-free bug ext4: avoid remove directory when directory is corrupted ext4: avoid resizing to a partial cluster size tty: serial: Fix refcount leak bug in ucc_uart.c vfio: Clear the caps->buf to NULL after free mips: cavium-octeon: Fix missing of_node_put() in octeon2_usb_clocks_start ALSA: core: Add async signal helpers ALSA: timer: Use deferred fasync helper powerpc/64: Init jump labels before parse_early_param() video: fbdev: i740fb: Check the argument of i740_calc_vclk() MIPS: tlbex: Explicitly compare _PAGE_NO_EXEC against 0 Linux 4.9.326 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: I3ca17af58cd0c61bd81028c496849592cfd22f0f
185 lines
6.2 KiB
C
185 lines
6.2 KiB
C
/*
|
|
File: fs/ext4/xattr.h
|
|
|
|
On-disk format of extended attributes for the ext4 filesystem.
|
|
|
|
(C) 2001 Andreas Gruenbacher, <a.gruenbacher@computer.org>
|
|
*/
|
|
|
|
#include <linux/xattr.h>
|
|
|
|
/* Magic value in attribute blocks */
|
|
#define EXT4_XATTR_MAGIC 0xEA020000
|
|
|
|
/* Maximum number of references to one attribute block */
|
|
#define EXT4_XATTR_REFCOUNT_MAX 1024
|
|
|
|
/* Name indexes */
|
|
#define EXT4_XATTR_INDEX_USER 1
|
|
#define EXT4_XATTR_INDEX_POSIX_ACL_ACCESS 2
|
|
#define EXT4_XATTR_INDEX_POSIX_ACL_DEFAULT 3
|
|
#define EXT4_XATTR_INDEX_TRUSTED 4
|
|
#define EXT4_XATTR_INDEX_LUSTRE 5
|
|
#define EXT4_XATTR_INDEX_SECURITY 6
|
|
#define EXT4_XATTR_INDEX_SYSTEM 7
|
|
#define EXT4_XATTR_INDEX_RICHACL 8
|
|
#define EXT4_XATTR_INDEX_ENCRYPTION 9
|
|
#define EXT4_XATTR_INDEX_HURD 10 /* Reserved for Hurd */
|
|
|
|
struct ext4_xattr_header {
|
|
__le32 h_magic; /* magic number for identification */
|
|
__le32 h_refcount; /* reference count */
|
|
__le32 h_blocks; /* number of disk blocks used */
|
|
__le32 h_hash; /* hash value of all attributes */
|
|
__le32 h_checksum; /* crc32c(uuid+id+xattrblock) */
|
|
/* id = inum if refcount=1, blknum otherwise */
|
|
__u32 h_reserved[3]; /* zero right now */
|
|
};
|
|
|
|
struct ext4_xattr_ibody_header {
|
|
__le32 h_magic; /* magic number for identification */
|
|
};
|
|
|
|
struct ext4_xattr_entry {
|
|
__u8 e_name_len; /* length of name */
|
|
__u8 e_name_index; /* attribute name index */
|
|
__le16 e_value_offs; /* offset in disk block of value */
|
|
__le32 e_value_block; /* disk block attribute is stored on (n/i) */
|
|
__le32 e_value_size; /* size of attribute value */
|
|
__le32 e_hash; /* hash value of name and value */
|
|
char e_name[0]; /* attribute name */
|
|
};
|
|
|
|
#define EXT4_XATTR_PAD_BITS 2
|
|
#define EXT4_XATTR_PAD (1<<EXT4_XATTR_PAD_BITS)
|
|
#define EXT4_XATTR_ROUND (EXT4_XATTR_PAD-1)
|
|
#define EXT4_XATTR_LEN(name_len) \
|
|
(((name_len) + EXT4_XATTR_ROUND + \
|
|
sizeof(struct ext4_xattr_entry)) & ~EXT4_XATTR_ROUND)
|
|
#define EXT4_XATTR_NEXT(entry) \
|
|
((struct ext4_xattr_entry *)( \
|
|
(char *)(entry) + EXT4_XATTR_LEN((entry)->e_name_len)))
|
|
#define EXT4_XATTR_SIZE(size) \
|
|
(((size) + EXT4_XATTR_ROUND) & ~EXT4_XATTR_ROUND)
|
|
|
|
#define IHDR(inode, raw_inode) \
|
|
((struct ext4_xattr_ibody_header *) \
|
|
((void *)raw_inode + \
|
|
EXT4_GOOD_OLD_INODE_SIZE + \
|
|
EXT4_I(inode)->i_extra_isize))
|
|
#define IFIRST(hdr) ((struct ext4_xattr_entry *)((hdr)+1))
|
|
|
|
#define BHDR(bh) ((struct ext4_xattr_header *)((bh)->b_data))
|
|
#define ENTRY(ptr) ((struct ext4_xattr_entry *)(ptr))
|
|
#define BFIRST(bh) ENTRY(BHDR(bh)+1)
|
|
#define IS_LAST_ENTRY(entry) (*(__u32 *)(entry) == 0)
|
|
|
|
#define EXT4_ZERO_XATTR_VALUE ((void *)-1)
|
|
|
|
/*
|
|
* If we want to add an xattr to the inode, we should make sure that
|
|
* i_extra_isize is not 0 and that the inode size is not less than
|
|
* EXT4_GOOD_OLD_INODE_SIZE + extra_isize + pad.
|
|
* EXT4_GOOD_OLD_INODE_SIZE extra_isize header entry pad data
|
|
* |--------------------------|------------|------|---------|---|-------|
|
|
*/
|
|
#define EXT4_INODE_HAS_XATTR_SPACE(inode) \
|
|
((EXT4_I(inode)->i_extra_isize != 0) && \
|
|
(EXT4_GOOD_OLD_INODE_SIZE + EXT4_I(inode)->i_extra_isize + \
|
|
sizeof(struct ext4_xattr_ibody_header) + EXT4_XATTR_PAD <= \
|
|
EXT4_INODE_SIZE((inode)->i_sb)))
|
|
|
|
struct ext4_xattr_info {
|
|
int name_index;
|
|
const char *name;
|
|
const void *value;
|
|
size_t value_len;
|
|
};
|
|
|
|
struct ext4_xattr_search {
|
|
struct ext4_xattr_entry *first;
|
|
void *base;
|
|
void *end;
|
|
struct ext4_xattr_entry *here;
|
|
int not_found;
|
|
};
|
|
|
|
struct ext4_xattr_ibody_find {
|
|
struct ext4_xattr_search s;
|
|
struct ext4_iloc iloc;
|
|
};
|
|
|
|
extern const struct xattr_handler ext4_xattr_user_handler;
|
|
extern const struct xattr_handler ext4_xattr_trusted_handler;
|
|
extern const struct xattr_handler ext4_xattr_security_handler;
|
|
|
|
#define EXT4_XATTR_NAME_ENCRYPTION_CONTEXT "c"
|
|
|
|
/*
|
|
* The EXT4_STATE_NO_EXPAND is overloaded and used for two purposes.
|
|
* The first is to signal that there the inline xattrs and data are
|
|
* taking up so much space that we might as well not keep trying to
|
|
* expand it. The second is that xattr_sem is taken for writing, so
|
|
* we shouldn't try to recurse into the inode expansion. For this
|
|
* second case, we need to make sure that we take save and restore the
|
|
* NO_EXPAND state flag appropriately.
|
|
*/
|
|
static inline void ext4_write_lock_xattr(struct inode *inode, int *save)
|
|
{
|
|
down_write(&EXT4_I(inode)->xattr_sem);
|
|
*save = ext4_test_inode_state(inode, EXT4_STATE_NO_EXPAND);
|
|
ext4_set_inode_state(inode, EXT4_STATE_NO_EXPAND);
|
|
}
|
|
|
|
static inline int ext4_write_trylock_xattr(struct inode *inode, int *save)
|
|
{
|
|
if (down_write_trylock(&EXT4_I(inode)->xattr_sem) == 0)
|
|
return 0;
|
|
*save = ext4_test_inode_state(inode, EXT4_STATE_NO_EXPAND);
|
|
ext4_set_inode_state(inode, EXT4_STATE_NO_EXPAND);
|
|
return 1;
|
|
}
|
|
|
|
static inline void ext4_write_unlock_xattr(struct inode *inode, int *save)
|
|
{
|
|
if (*save == 0)
|
|
ext4_clear_inode_state(inode, EXT4_STATE_NO_EXPAND);
|
|
up_write(&EXT4_I(inode)->xattr_sem);
|
|
}
|
|
|
|
extern ssize_t ext4_listxattr(struct dentry *, char *, size_t);
|
|
|
|
extern int ext4_xattr_get(struct inode *, int, const char *, void *, size_t);
|
|
extern int ext4_xattr_set(struct inode *, int, const char *, const void *, size_t, int);
|
|
extern int ext4_xattr_set_handle(handle_t *, struct inode *, int, const char *, const void *, size_t, int);
|
|
|
|
extern void ext4_xattr_delete_inode(handle_t *, struct inode *);
|
|
|
|
extern int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
|
|
struct ext4_inode *raw_inode, handle_t *handle);
|
|
|
|
extern const struct xattr_handler *ext4_xattr_handlers[];
|
|
|
|
extern int ext4_xattr_ibody_find(struct inode *inode, struct ext4_xattr_info *i,
|
|
struct ext4_xattr_ibody_find *is);
|
|
extern int ext4_xattr_ibody_get(struct inode *inode, int name_index,
|
|
const char *name,
|
|
void *buffer, size_t buffer_size);
|
|
extern int ext4_xattr_ibody_inline_set(handle_t *handle, struct inode *inode,
|
|
struct ext4_xattr_info *i,
|
|
struct ext4_xattr_ibody_find *is);
|
|
|
|
extern struct mb_cache *ext4_xattr_create_cache(void);
|
|
extern void ext4_xattr_destroy_cache(struct mb_cache *);
|
|
|
|
#ifdef CONFIG_EXT4_FS_SECURITY
|
|
extern int ext4_init_security(handle_t *handle, struct inode *inode,
|
|
struct inode *dir, const struct qstr *qstr);
|
|
#else
|
|
static inline int ext4_init_security(handle_t *handle, struct inode *inode,
|
|
struct inode *dir, const struct qstr *qstr)
|
|
{
|
|
return 0;
|
|
}
|
|
#endif
|