cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ea.c (11696B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 *  linux/fs/hpfs/ea.c
      4 *
      5 *  Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
      6 *
      7 *  handling extended attributes
      8 */
      9
     10#include "hpfs_fn.h"
     11
     12/* Remove external extended attributes. ano specifies whether a is a 
     13   direct sector where eas starts or an anode */
     14
     15void hpfs_ea_ext_remove(struct super_block *s, secno a, int ano, unsigned len)
     16{
     17	unsigned pos = 0;
     18	while (pos < len) {
     19		char ex[4 + 255 + 1 + 8];
     20		struct extended_attribute *ea = (struct extended_attribute *)ex;
     21		if (pos + 4 > len) {
     22			hpfs_error(s, "EAs don't end correctly, %s %08x, len %08x",
     23				ano ? "anode" : "sectors", a, len);
     24			return;
     25		}
     26		if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return;
     27		if (ea_indirect(ea)) {
     28			if (ea_valuelen(ea) != 8) {
     29				hpfs_error(s, "ea_indirect(ea) set while ea->valuelen!=8, %s %08x, pos %08x",
     30					ano ? "anode" : "sectors", a, pos);
     31				return;
     32			}
     33			if (hpfs_ea_read(s, a, ano, pos + 4, ea->namelen + 9, ex+4))
     34				return;
     35			hpfs_ea_remove(s, ea_sec(ea), ea_in_anode(ea), ea_len(ea));
     36		}
     37		pos += ea->namelen + ea_valuelen(ea) + 5;
     38	}
     39	if (!ano) hpfs_free_sectors(s, a, (len+511) >> 9);
     40	else {
     41		struct buffer_head *bh;
     42		struct anode *anode;
     43		if ((anode = hpfs_map_anode(s, a, &bh))) {
     44			hpfs_remove_btree(s, &anode->btree);
     45			brelse(bh);
     46			hpfs_free_sectors(s, a, 1);
     47		}
     48	}
     49}
     50
     51static char *get_indirect_ea(struct super_block *s, int ano, secno a, int size)
     52{
     53	char *ret;
     54	if (!(ret = kmalloc(size + 1, GFP_NOFS))) {
     55		pr_err("out of memory for EA\n");
     56		return NULL;
     57	}
     58	if (hpfs_ea_read(s, a, ano, 0, size, ret)) {
     59		kfree(ret);
     60		return NULL;
     61	}
     62	ret[size] = 0;
     63	return ret;
     64}
     65
     66static void set_indirect_ea(struct super_block *s, int ano, secno a,
     67			    const char *data, int size)
     68{
     69	hpfs_ea_write(s, a, ano, 0, size, data);
     70}
     71
     72/* Read an extended attribute named 'key' into the provided buffer */
     73
     74int hpfs_read_ea(struct super_block *s, struct fnode *fnode, char *key,
     75		char *buf, int size)
     76{
     77	unsigned pos;
     78	int ano, len;
     79	secno a;
     80	char ex[4 + 255 + 1 + 8];
     81	struct extended_attribute *ea;
     82	struct extended_attribute *ea_end = fnode_end_ea(fnode);
     83	for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea))
     84		if (!strcmp(ea->name, key)) {
     85			if (ea_indirect(ea))
     86				goto indirect;
     87			if (ea_valuelen(ea) >= size)
     88				return -EINVAL;
     89			memcpy(buf, ea_data(ea), ea_valuelen(ea));
     90			buf[ea_valuelen(ea)] = 0;
     91			return 0;
     92		}
     93	a = le32_to_cpu(fnode->ea_secno);
     94	len = le32_to_cpu(fnode->ea_size_l);
     95	ano = fnode_in_anode(fnode);
     96	pos = 0;
     97	while (pos < len) {
     98		ea = (struct extended_attribute *)ex;
     99		if (pos + 4 > len) {
    100			hpfs_error(s, "EAs don't end correctly, %s %08x, len %08x",
    101				ano ? "anode" : "sectors", a, len);
    102			return -EIO;
    103		}
    104		if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return -EIO;
    105		if (hpfs_ea_read(s, a, ano, pos + 4, ea->namelen + 1 + (ea_indirect(ea) ? 8 : 0), ex + 4))
    106			return -EIO;
    107		if (!strcmp(ea->name, key)) {
    108			if (ea_indirect(ea))
    109				goto indirect;
    110			if (ea_valuelen(ea) >= size)
    111				return -EINVAL;
    112			if (hpfs_ea_read(s, a, ano, pos + 4 + ea->namelen + 1, ea_valuelen(ea), buf))
    113				return -EIO;
    114			buf[ea_valuelen(ea)] = 0;
    115			return 0;
    116		}
    117		pos += ea->namelen + ea_valuelen(ea) + 5;
    118	}
    119	return -ENOENT;
    120indirect:
    121	if (ea_len(ea) >= size)
    122		return -EINVAL;
    123	if (hpfs_ea_read(s, ea_sec(ea), ea_in_anode(ea), 0, ea_len(ea), buf))
    124		return -EIO;
    125	buf[ea_len(ea)] = 0;
    126	return 0;
    127}
    128
    129/* Read an extended attribute named 'key' */
    130char *hpfs_get_ea(struct super_block *s, struct fnode *fnode, char *key, int *size)
    131{
    132	char *ret;
    133	unsigned pos;
    134	int ano, len;
    135	secno a;
    136	struct extended_attribute *ea;
    137	struct extended_attribute *ea_end = fnode_end_ea(fnode);
    138	for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea))
    139		if (!strcmp(ea->name, key)) {
    140			if (ea_indirect(ea))
    141				return get_indirect_ea(s, ea_in_anode(ea), ea_sec(ea), *size = ea_len(ea));
    142			if (!(ret = kmalloc((*size = ea_valuelen(ea)) + 1, GFP_NOFS))) {
    143				pr_err("out of memory for EA\n");
    144				return NULL;
    145			}
    146			memcpy(ret, ea_data(ea), ea_valuelen(ea));
    147			ret[ea_valuelen(ea)] = 0;
    148			return ret;
    149		}
    150	a = le32_to_cpu(fnode->ea_secno);
    151	len = le32_to_cpu(fnode->ea_size_l);
    152	ano = fnode_in_anode(fnode);
    153	pos = 0;
    154	while (pos < len) {
    155		char ex[4 + 255 + 1 + 8];
    156		ea = (struct extended_attribute *)ex;
    157		if (pos + 4 > len) {
    158			hpfs_error(s, "EAs don't end correctly, %s %08x, len %08x",
    159				ano ? "anode" : "sectors", a, len);
    160			return NULL;
    161		}
    162		if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return NULL;
    163		if (hpfs_ea_read(s, a, ano, pos + 4, ea->namelen + 1 + (ea_indirect(ea) ? 8 : 0), ex + 4))
    164			return NULL;
    165		if (!strcmp(ea->name, key)) {
    166			if (ea_indirect(ea))
    167				return get_indirect_ea(s, ea_in_anode(ea), ea_sec(ea), *size = ea_len(ea));
    168			if (!(ret = kmalloc((*size = ea_valuelen(ea)) + 1, GFP_NOFS))) {
    169				pr_err("out of memory for EA\n");
    170				return NULL;
    171			}
    172			if (hpfs_ea_read(s, a, ano, pos + 4 + ea->namelen + 1, ea_valuelen(ea), ret)) {
    173				kfree(ret);
    174				return NULL;
    175			}
    176			ret[ea_valuelen(ea)] = 0;
    177			return ret;
    178		}
    179		pos += ea->namelen + ea_valuelen(ea) + 5;
    180	}
    181	return NULL;
    182}
    183
    184/* 
    185 * Update or create extended attribute 'key' with value 'data'. Note that
    186 * when this ea exists, it MUST have the same size as size of data.
    187 * This driver can't change sizes of eas ('cause I just don't need it).
    188 */
    189
    190void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key,
    191		 const char *data, int size)
    192{
    193	fnode_secno fno = inode->i_ino;
    194	struct super_block *s = inode->i_sb;
    195	unsigned pos;
    196	int ano, len;
    197	secno a;
    198	unsigned char h[4];
    199	struct extended_attribute *ea;
    200	struct extended_attribute *ea_end = fnode_end_ea(fnode);
    201	for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea))
    202		if (!strcmp(ea->name, key)) {
    203			if (ea_indirect(ea)) {
    204				if (ea_len(ea) == size)
    205					set_indirect_ea(s, ea_in_anode(ea), ea_sec(ea), data, size);
    206			} else if (ea_valuelen(ea) == size) {
    207				memcpy(ea_data(ea), data, size);
    208			}
    209			return;
    210		}
    211	a = le32_to_cpu(fnode->ea_secno);
    212	len = le32_to_cpu(fnode->ea_size_l);
    213	ano = fnode_in_anode(fnode);
    214	pos = 0;
    215	while (pos < len) {
    216		char ex[4 + 255 + 1 + 8];
    217		ea = (struct extended_attribute *)ex;
    218		if (pos + 4 > len) {
    219			hpfs_error(s, "EAs don't end correctly, %s %08x, len %08x",
    220				ano ? "anode" : "sectors", a, len);
    221			return;
    222		}
    223		if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return;
    224		if (hpfs_ea_read(s, a, ano, pos + 4, ea->namelen + 1 + (ea_indirect(ea) ? 8 : 0), ex + 4))
    225			return;
    226		if (!strcmp(ea->name, key)) {
    227			if (ea_indirect(ea)) {
    228				if (ea_len(ea) == size)
    229					set_indirect_ea(s, ea_in_anode(ea), ea_sec(ea), data, size);
    230			}
    231			else {
    232				if (ea_valuelen(ea) == size)
    233					hpfs_ea_write(s, a, ano, pos + 4 + ea->namelen + 1, size, data);
    234			}
    235			return;
    236		}
    237		pos += ea->namelen + ea_valuelen(ea) + 5;
    238	}
    239	if (!le16_to_cpu(fnode->ea_offs)) {
    240		/*if (le16_to_cpu(fnode->ea_size_s)) {
    241			hpfs_error(s, "fnode %08x: ea_size_s == %03x, ea_offs == 0",
    242				inode->i_ino, le16_to_cpu(fnode->ea_size_s));
    243			return;
    244		}*/
    245		fnode->ea_offs = cpu_to_le16(0xc4);
    246	}
    247	if (le16_to_cpu(fnode->ea_offs) < 0xc4 || le16_to_cpu(fnode->ea_offs) + le16_to_cpu(fnode->acl_size_s) + le16_to_cpu(fnode->ea_size_s) > 0x200) {
    248		hpfs_error(s, "fnode %08lx: ea_offs == %03x, ea_size_s == %03x",
    249			(unsigned long)inode->i_ino,
    250			le16_to_cpu(fnode->ea_offs), le16_to_cpu(fnode->ea_size_s));
    251		return;
    252	}
    253	if ((le16_to_cpu(fnode->ea_size_s) || !le32_to_cpu(fnode->ea_size_l)) &&
    254	     le16_to_cpu(fnode->ea_offs) + le16_to_cpu(fnode->acl_size_s) + le16_to_cpu(fnode->ea_size_s) + strlen(key) + size + 5 <= 0x200) {
    255		ea = fnode_end_ea(fnode);
    256		*(char *)ea = 0;
    257		ea->namelen = strlen(key);
    258		ea->valuelen_lo = size;
    259		ea->valuelen_hi = size >> 8;
    260		strcpy(ea->name, key);
    261		memcpy(ea_data(ea), data, size);
    262		fnode->ea_size_s = cpu_to_le16(le16_to_cpu(fnode->ea_size_s) + strlen(key) + size + 5);
    263		goto ret;
    264	}
    265	/* Most the code here is 99.9993422% unused. I hope there are no bugs.
    266	   But what .. HPFS.IFS has also bugs in ea management. */
    267	if (le16_to_cpu(fnode->ea_size_s) && !le32_to_cpu(fnode->ea_size_l)) {
    268		secno n;
    269		struct buffer_head *bh;
    270		char *data;
    271		if (!(n = hpfs_alloc_sector(s, fno, 1, 0))) return;
    272		if (!(data = hpfs_get_sector(s, n, &bh))) {
    273			hpfs_free_sectors(s, n, 1);
    274			return;
    275		}
    276		memcpy(data, fnode_ea(fnode), le16_to_cpu(fnode->ea_size_s));
    277		fnode->ea_size_l = cpu_to_le32(le16_to_cpu(fnode->ea_size_s));
    278		fnode->ea_size_s = cpu_to_le16(0);
    279		fnode->ea_secno = cpu_to_le32(n);
    280		fnode->flags &= ~FNODE_anode;
    281		mark_buffer_dirty(bh);
    282		brelse(bh);
    283	}
    284	pos = le32_to_cpu(fnode->ea_size_l) + 5 + strlen(key) + size;
    285	len = (le32_to_cpu(fnode->ea_size_l) + 511) >> 9;
    286	if (pos >= 30000) goto bail;
    287	while (((pos + 511) >> 9) > len) {
    288		if (!len) {
    289			secno q = hpfs_alloc_sector(s, fno, 1, 0);
    290			if (!q) goto bail;
    291			fnode->ea_secno = cpu_to_le32(q);
    292			fnode->flags &= ~FNODE_anode;
    293			len++;
    294		} else if (!fnode_in_anode(fnode)) {
    295			if (hpfs_alloc_if_possible(s, le32_to_cpu(fnode->ea_secno) + len)) {
    296				len++;
    297			} else {
    298				/* Aargh... don't know how to create ea anodes :-( */
    299				/*struct buffer_head *bh;
    300				struct anode *anode;
    301				anode_secno a_s;
    302				if (!(anode = hpfs_alloc_anode(s, fno, &a_s, &bh)))
    303					goto bail;
    304				anode->up = cpu_to_le32(fno);
    305				anode->btree.fnode_parent = 1;
    306				anode->btree.n_free_nodes--;
    307				anode->btree.n_used_nodes++;
    308				anode->btree.first_free = cpu_to_le16(le16_to_cpu(anode->btree.first_free) + 12);
    309				anode->u.external[0].disk_secno = cpu_to_le32(le32_to_cpu(fnode->ea_secno));
    310				anode->u.external[0].file_secno = cpu_to_le32(0);
    311				anode->u.external[0].length = cpu_to_le32(len);
    312				mark_buffer_dirty(bh);
    313				brelse(bh);
    314				fnode->flags |= FNODE_anode;
    315				fnode->ea_secno = cpu_to_le32(a_s);*/
    316				secno new_sec;
    317				int i;
    318				if (!(new_sec = hpfs_alloc_sector(s, fno, 1, 1 - ((pos + 511) >> 9))))
    319					goto bail;
    320				for (i = 0; i < len; i++) {
    321					struct buffer_head *bh1, *bh2;
    322					void *b1, *b2;
    323					if (!(b1 = hpfs_map_sector(s, le32_to_cpu(fnode->ea_secno) + i, &bh1, len - i - 1))) {
    324						hpfs_free_sectors(s, new_sec, (pos + 511) >> 9);
    325						goto bail;
    326					}
    327					if (!(b2 = hpfs_get_sector(s, new_sec + i, &bh2))) {
    328						brelse(bh1);
    329						hpfs_free_sectors(s, new_sec, (pos + 511) >> 9);
    330						goto bail;
    331					}
    332					memcpy(b2, b1, 512);
    333					brelse(bh1);
    334					mark_buffer_dirty(bh2);
    335					brelse(bh2);
    336				}
    337				hpfs_free_sectors(s, le32_to_cpu(fnode->ea_secno), len);
    338				fnode->ea_secno = cpu_to_le32(new_sec);
    339				len = (pos + 511) >> 9;
    340			}
    341		}
    342		if (fnode_in_anode(fnode)) {
    343			if (hpfs_add_sector_to_btree(s, le32_to_cpu(fnode->ea_secno),
    344						     0, len) != -1) {
    345				len++;
    346			} else {
    347				goto bail;
    348			}
    349		}
    350	}
    351	h[0] = 0;
    352	h[1] = strlen(key);
    353	h[2] = size & 0xff;
    354	h[3] = size >> 8;
    355	if (hpfs_ea_write(s, le32_to_cpu(fnode->ea_secno), fnode_in_anode(fnode), le32_to_cpu(fnode->ea_size_l), 4, h)) goto bail;
    356	if (hpfs_ea_write(s, le32_to_cpu(fnode->ea_secno), fnode_in_anode(fnode), le32_to_cpu(fnode->ea_size_l) + 4, h[1] + 1, key)) goto bail;
    357	if (hpfs_ea_write(s, le32_to_cpu(fnode->ea_secno), fnode_in_anode(fnode), le32_to_cpu(fnode->ea_size_l) + 5 + h[1], size, data)) goto bail;
    358	fnode->ea_size_l = cpu_to_le32(pos);
    359	ret:
    360	hpfs_i(inode)->i_ea_size += 5 + strlen(key) + size;
    361	return;
    362	bail:
    363	if (le32_to_cpu(fnode->ea_secno))
    364		if (fnode_in_anode(fnode)) hpfs_truncate_btree(s, le32_to_cpu(fnode->ea_secno), 1, (le32_to_cpu(fnode->ea_size_l) + 511) >> 9);
    365		else hpfs_free_sectors(s, le32_to_cpu(fnode->ea_secno) + ((le32_to_cpu(fnode->ea_size_l) + 511) >> 9), len - ((le32_to_cpu(fnode->ea_size_l) + 511) >> 9));
    366	else fnode->ea_secno = fnode->ea_size_l = cpu_to_le32(0);
    367}
    368