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

unlink.c (14640B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 *  linux/fs/nfs/unlink.c
      4 *
      5 * nfs sillydelete handling
      6 *
      7 */
      8
      9#include <linux/slab.h>
     10#include <linux/string.h>
     11#include <linux/dcache.h>
     12#include <linux/sunrpc/sched.h>
     13#include <linux/sunrpc/clnt.h>
     14#include <linux/nfs_fs.h>
     15#include <linux/sched.h>
     16#include <linux/wait.h>
     17#include <linux/namei.h>
     18#include <linux/fsnotify.h>
     19
     20#include "internal.h"
     21#include "nfs4_fs.h"
     22#include "iostat.h"
     23#include "delegation.h"
     24
     25#include "nfstrace.h"
     26
     27/**
     28 * nfs_free_unlinkdata - release data from a sillydelete operation.
     29 * @data: pointer to unlink structure.
     30 */
     31static void
     32nfs_free_unlinkdata(struct nfs_unlinkdata *data)
     33{
     34	put_cred(data->cred);
     35	kfree(data->args.name.name);
     36	kfree(data);
     37}
     38
     39/**
     40 * nfs_async_unlink_done - Sillydelete post-processing
     41 * @task: rpc_task of the sillydelete
     42 * @calldata: pointer to nfs_unlinkdata
     43 *
     44 * Do the directory attribute update.
     45 */
     46static void nfs_async_unlink_done(struct rpc_task *task, void *calldata)
     47{
     48	struct nfs_unlinkdata *data = calldata;
     49	struct inode *dir = d_inode(data->dentry->d_parent);
     50
     51	trace_nfs_sillyrename_unlink(data, task->tk_status);
     52	if (!NFS_PROTO(dir)->unlink_done(task, dir))
     53		rpc_restart_call_prepare(task);
     54}
     55
     56/**
     57 * nfs_async_unlink_release - Release the sillydelete data.
     58 * @calldata: struct nfs_unlinkdata to release
     59 *
     60 * We need to call nfs_put_unlinkdata as a 'tk_release' task since the
     61 * rpc_task would be freed too.
     62 */
     63static void nfs_async_unlink_release(void *calldata)
     64{
     65	struct nfs_unlinkdata	*data = calldata;
     66	struct dentry *dentry = data->dentry;
     67	struct super_block *sb = dentry->d_sb;
     68
     69	up_read_non_owner(&NFS_I(d_inode(dentry->d_parent))->rmdir_sem);
     70	d_lookup_done(dentry);
     71	nfs_free_unlinkdata(data);
     72	dput(dentry);
     73	nfs_sb_deactive(sb);
     74}
     75
     76static void nfs_unlink_prepare(struct rpc_task *task, void *calldata)
     77{
     78	struct nfs_unlinkdata *data = calldata;
     79	struct inode *dir = d_inode(data->dentry->d_parent);
     80	NFS_PROTO(dir)->unlink_rpc_prepare(task, data);
     81}
     82
     83static const struct rpc_call_ops nfs_unlink_ops = {
     84	.rpc_call_done = nfs_async_unlink_done,
     85	.rpc_release = nfs_async_unlink_release,
     86	.rpc_call_prepare = nfs_unlink_prepare,
     87};
     88
     89static void nfs_do_call_unlink(struct inode *inode, struct nfs_unlinkdata *data)
     90{
     91	struct rpc_message msg = {
     92		.rpc_argp = &data->args,
     93		.rpc_resp = &data->res,
     94		.rpc_cred = data->cred,
     95	};
     96	struct rpc_task_setup task_setup_data = {
     97		.rpc_message = &msg,
     98		.callback_ops = &nfs_unlink_ops,
     99		.callback_data = data,
    100		.workqueue = nfsiod_workqueue,
    101		.flags = RPC_TASK_ASYNC | RPC_TASK_CRED_NOREF,
    102	};
    103	struct rpc_task *task;
    104	struct inode *dir = d_inode(data->dentry->d_parent);
    105
    106	if (nfs_server_capable(inode, NFS_CAP_MOVEABLE))
    107		task_setup_data.flags |= RPC_TASK_MOVEABLE;
    108
    109	nfs_sb_active(dir->i_sb);
    110	data->args.fh = NFS_FH(dir);
    111	nfs_fattr_init(data->res.dir_attr);
    112
    113	NFS_PROTO(dir)->unlink_setup(&msg, data->dentry, inode);
    114
    115	task_setup_data.rpc_client = NFS_CLIENT(dir);
    116	task = rpc_run_task(&task_setup_data);
    117	if (!IS_ERR(task))
    118		rpc_put_task_async(task);
    119}
    120
    121static int nfs_call_unlink(struct dentry *dentry, struct inode *inode, struct nfs_unlinkdata *data)
    122{
    123	struct inode *dir = d_inode(dentry->d_parent);
    124	struct dentry *alias;
    125
    126	down_read_non_owner(&NFS_I(dir)->rmdir_sem);
    127	alias = d_alloc_parallel(dentry->d_parent, &data->args.name, &data->wq);
    128	if (IS_ERR(alias)) {
    129		up_read_non_owner(&NFS_I(dir)->rmdir_sem);
    130		return 0;
    131	}
    132	if (!d_in_lookup(alias)) {
    133		int ret;
    134		void *devname_garbage = NULL;
    135
    136		/*
    137		 * Hey, we raced with lookup... See if we need to transfer
    138		 * the sillyrename information to the aliased dentry.
    139		 */
    140		spin_lock(&alias->d_lock);
    141		if (d_really_is_positive(alias) &&
    142		    !(alias->d_flags & DCACHE_NFSFS_RENAMED)) {
    143			devname_garbage = alias->d_fsdata;
    144			alias->d_fsdata = data;
    145			alias->d_flags |= DCACHE_NFSFS_RENAMED;
    146			ret = 1;
    147		} else
    148			ret = 0;
    149		spin_unlock(&alias->d_lock);
    150		dput(alias);
    151		up_read_non_owner(&NFS_I(dir)->rmdir_sem);
    152		/*
    153		 * If we'd displaced old cached devname, free it.  At that
    154		 * point dentry is definitely not a root, so we won't need
    155		 * that anymore.
    156		 */
    157		kfree(devname_garbage);
    158		return ret;
    159	}
    160	data->dentry = alias;
    161	nfs_do_call_unlink(inode, data);
    162	return 1;
    163}
    164
    165/**
    166 * nfs_async_unlink - asynchronous unlinking of a file
    167 * @dentry: parent directory of dentry
    168 * @name: name of dentry to unlink
    169 */
    170static int
    171nfs_async_unlink(struct dentry *dentry, const struct qstr *name)
    172{
    173	struct nfs_unlinkdata *data;
    174	int status = -ENOMEM;
    175	void *devname_garbage = NULL;
    176
    177	data = kzalloc(sizeof(*data), GFP_KERNEL);
    178	if (data == NULL)
    179		goto out;
    180	data->args.name.name = kstrdup(name->name, GFP_KERNEL);
    181	if (!data->args.name.name)
    182		goto out_free;
    183	data->args.name.len = name->len;
    184
    185	data->cred = get_current_cred();
    186	data->res.dir_attr = &data->dir_attr;
    187	init_waitqueue_head(&data->wq);
    188
    189	status = -EBUSY;
    190	spin_lock(&dentry->d_lock);
    191	if (dentry->d_flags & DCACHE_NFSFS_RENAMED)
    192		goto out_unlock;
    193	dentry->d_flags |= DCACHE_NFSFS_RENAMED;
    194	devname_garbage = dentry->d_fsdata;
    195	dentry->d_fsdata = data;
    196	spin_unlock(&dentry->d_lock);
    197	/*
    198	 * If we'd displaced old cached devname, free it.  At that
    199	 * point dentry is definitely not a root, so we won't need
    200	 * that anymore.
    201	 */
    202	kfree(devname_garbage);
    203	return 0;
    204out_unlock:
    205	spin_unlock(&dentry->d_lock);
    206	put_cred(data->cred);
    207	kfree(data->args.name.name);
    208out_free:
    209	kfree(data);
    210out:
    211	return status;
    212}
    213
    214/**
    215 * nfs_complete_unlink - Initialize completion of the sillydelete
    216 * @dentry: dentry to delete
    217 * @inode: inode
    218 *
    219 * Since we're most likely to be called by dentry_iput(), we
    220 * only use the dentry to find the sillydelete. We then copy the name
    221 * into the qstr.
    222 */
    223void
    224nfs_complete_unlink(struct dentry *dentry, struct inode *inode)
    225{
    226	struct nfs_unlinkdata	*data;
    227
    228	spin_lock(&dentry->d_lock);
    229	dentry->d_flags &= ~DCACHE_NFSFS_RENAMED;
    230	data = dentry->d_fsdata;
    231	dentry->d_fsdata = NULL;
    232	spin_unlock(&dentry->d_lock);
    233
    234	if (NFS_STALE(inode) || !nfs_call_unlink(dentry, inode, data))
    235		nfs_free_unlinkdata(data);
    236}
    237
    238/* Cancel a queued async unlink. Called when a sillyrename run fails. */
    239static void
    240nfs_cancel_async_unlink(struct dentry *dentry)
    241{
    242	spin_lock(&dentry->d_lock);
    243	if (dentry->d_flags & DCACHE_NFSFS_RENAMED) {
    244		struct nfs_unlinkdata *data = dentry->d_fsdata;
    245
    246		dentry->d_flags &= ~DCACHE_NFSFS_RENAMED;
    247		dentry->d_fsdata = NULL;
    248		spin_unlock(&dentry->d_lock);
    249		nfs_free_unlinkdata(data);
    250		return;
    251	}
    252	spin_unlock(&dentry->d_lock);
    253}
    254
    255/**
    256 * nfs_async_rename_done - Sillyrename post-processing
    257 * @task: rpc_task of the sillyrename
    258 * @calldata: nfs_renamedata for the sillyrename
    259 *
    260 * Do the directory attribute updates and the d_move
    261 */
    262static void nfs_async_rename_done(struct rpc_task *task, void *calldata)
    263{
    264	struct nfs_renamedata *data = calldata;
    265	struct inode *old_dir = data->old_dir;
    266	struct inode *new_dir = data->new_dir;
    267	struct dentry *old_dentry = data->old_dentry;
    268
    269	trace_nfs_sillyrename_rename(old_dir, old_dentry,
    270			new_dir, data->new_dentry, task->tk_status);
    271	if (!NFS_PROTO(old_dir)->rename_done(task, old_dir, new_dir)) {
    272		rpc_restart_call_prepare(task);
    273		return;
    274	}
    275
    276	if (data->complete)
    277		data->complete(task, data);
    278}
    279
    280/**
    281 * nfs_async_rename_release - Release the sillyrename data.
    282 * @calldata: the struct nfs_renamedata to be released
    283 */
    284static void nfs_async_rename_release(void *calldata)
    285{
    286	struct nfs_renamedata	*data = calldata;
    287	struct super_block *sb = data->old_dir->i_sb;
    288
    289	if (d_really_is_positive(data->old_dentry))
    290		nfs_mark_for_revalidate(d_inode(data->old_dentry));
    291
    292	/* The result of the rename is unknown. Play it safe by
    293	 * forcing a new lookup */
    294	if (data->cancelled) {
    295		spin_lock(&data->old_dir->i_lock);
    296		nfs_force_lookup_revalidate(data->old_dir);
    297		spin_unlock(&data->old_dir->i_lock);
    298		if (data->new_dir != data->old_dir) {
    299			spin_lock(&data->new_dir->i_lock);
    300			nfs_force_lookup_revalidate(data->new_dir);
    301			spin_unlock(&data->new_dir->i_lock);
    302		}
    303	}
    304
    305	dput(data->old_dentry);
    306	dput(data->new_dentry);
    307	iput(data->old_dir);
    308	iput(data->new_dir);
    309	nfs_sb_deactive(sb);
    310	put_cred(data->cred);
    311	kfree(data);
    312}
    313
    314static void nfs_rename_prepare(struct rpc_task *task, void *calldata)
    315{
    316	struct nfs_renamedata *data = calldata;
    317	NFS_PROTO(data->old_dir)->rename_rpc_prepare(task, data);
    318}
    319
    320static const struct rpc_call_ops nfs_rename_ops = {
    321	.rpc_call_done = nfs_async_rename_done,
    322	.rpc_release = nfs_async_rename_release,
    323	.rpc_call_prepare = nfs_rename_prepare,
    324};
    325
    326/**
    327 * nfs_async_rename - perform an asynchronous rename operation
    328 * @old_dir: directory that currently holds the dentry to be renamed
    329 * @new_dir: target directory for the rename
    330 * @old_dentry: original dentry to be renamed
    331 * @new_dentry: dentry to which the old_dentry should be renamed
    332 * @complete: Function to run on successful completion
    333 *
    334 * It's expected that valid references to the dentries and inodes are held
    335 */
    336struct rpc_task *
    337nfs_async_rename(struct inode *old_dir, struct inode *new_dir,
    338		 struct dentry *old_dentry, struct dentry *new_dentry,
    339		 void (*complete)(struct rpc_task *, struct nfs_renamedata *))
    340{
    341	struct nfs_renamedata *data;
    342	struct rpc_message msg = { };
    343	struct rpc_task_setup task_setup_data = {
    344		.rpc_message = &msg,
    345		.callback_ops = &nfs_rename_ops,
    346		.workqueue = nfsiod_workqueue,
    347		.rpc_client = NFS_CLIENT(old_dir),
    348		.flags = RPC_TASK_ASYNC | RPC_TASK_CRED_NOREF,
    349	};
    350
    351	if (nfs_server_capable(old_dir, NFS_CAP_MOVEABLE) &&
    352	    nfs_server_capable(new_dir, NFS_CAP_MOVEABLE))
    353		task_setup_data.flags |= RPC_TASK_MOVEABLE;
    354
    355	data = kzalloc(sizeof(*data), GFP_KERNEL);
    356	if (data == NULL)
    357		return ERR_PTR(-ENOMEM);
    358	task_setup_data.task = &data->task;
    359	task_setup_data.callback_data = data;
    360
    361	data->cred = get_current_cred();
    362
    363	msg.rpc_argp = &data->args;
    364	msg.rpc_resp = &data->res;
    365	msg.rpc_cred = data->cred;
    366
    367	/* set up nfs_renamedata */
    368	data->old_dir = old_dir;
    369	ihold(old_dir);
    370	data->new_dir = new_dir;
    371	ihold(new_dir);
    372	data->old_dentry = dget(old_dentry);
    373	data->new_dentry = dget(new_dentry);
    374	nfs_fattr_init(&data->old_fattr);
    375	nfs_fattr_init(&data->new_fattr);
    376	data->complete = complete;
    377
    378	/* set up nfs_renameargs */
    379	data->args.old_dir = NFS_FH(old_dir);
    380	data->args.old_name = &old_dentry->d_name;
    381	data->args.new_dir = NFS_FH(new_dir);
    382	data->args.new_name = &new_dentry->d_name;
    383
    384	/* set up nfs_renameres */
    385	data->res.old_fattr = &data->old_fattr;
    386	data->res.new_fattr = &data->new_fattr;
    387
    388	nfs_sb_active(old_dir->i_sb);
    389
    390	NFS_PROTO(data->old_dir)->rename_setup(&msg, old_dentry, new_dentry);
    391
    392	return rpc_run_task(&task_setup_data);
    393}
    394
    395/*
    396 * Perform tasks needed when a sillyrename is done such as cancelling the
    397 * queued async unlink if it failed.
    398 */
    399static void
    400nfs_complete_sillyrename(struct rpc_task *task, struct nfs_renamedata *data)
    401{
    402	struct dentry *dentry = data->old_dentry;
    403
    404	if (task->tk_status != 0) {
    405		nfs_cancel_async_unlink(dentry);
    406		return;
    407	}
    408}
    409
    410#define SILLYNAME_PREFIX ".nfs"
    411#define SILLYNAME_PREFIX_LEN ((unsigned)sizeof(SILLYNAME_PREFIX) - 1)
    412#define SILLYNAME_FILEID_LEN ((unsigned)sizeof(u64) << 1)
    413#define SILLYNAME_COUNTER_LEN ((unsigned)sizeof(unsigned int) << 1)
    414#define SILLYNAME_LEN (SILLYNAME_PREFIX_LEN + \
    415		SILLYNAME_FILEID_LEN + \
    416		SILLYNAME_COUNTER_LEN)
    417
    418/**
    419 * nfs_sillyrename - Perform a silly-rename of a dentry
    420 * @dir: inode of directory that contains dentry
    421 * @dentry: dentry to be sillyrenamed
    422 *
    423 * NFSv2/3 is stateless and the server doesn't know when the client is
    424 * holding a file open. To prevent application problems when a file is
    425 * unlinked while it's still open, the client performs a "silly-rename".
    426 * That is, it renames the file to a hidden file in the same directory,
    427 * and only performs the unlink once the last reference to it is put.
    428 *
    429 * The final cleanup is done during dentry_iput.
    430 *
    431 * (Note: NFSv4 is stateful, and has opens, so in theory an NFSv4 server
    432 * could take responsibility for keeping open files referenced.  The server
    433 * would also need to ensure that opened-but-deleted files were kept over
    434 * reboots.  However, we may not assume a server does so.  (RFC 5661
    435 * does provide an OPEN4_RESULT_PRESERVE_UNLINKED flag that a server can
    436 * use to advertise that it does this; some day we may take advantage of
    437 * it.))
    438 */
    439int
    440nfs_sillyrename(struct inode *dir, struct dentry *dentry)
    441{
    442	static unsigned int sillycounter;
    443	unsigned char silly[SILLYNAME_LEN + 1];
    444	unsigned long long fileid;
    445	struct dentry *sdentry;
    446	struct inode *inode = d_inode(dentry);
    447	struct rpc_task *task;
    448	int            error = -EBUSY;
    449
    450	dfprintk(VFS, "NFS: silly-rename(%pd2, ct=%d)\n",
    451		dentry, d_count(dentry));
    452	nfs_inc_stats(dir, NFSIOS_SILLYRENAME);
    453
    454	/*
    455	 * We don't allow a dentry to be silly-renamed twice.
    456	 */
    457	if (dentry->d_flags & DCACHE_NFSFS_RENAMED)
    458		goto out;
    459
    460	fileid = NFS_FILEID(d_inode(dentry));
    461
    462	sdentry = NULL;
    463	do {
    464		int slen;
    465		dput(sdentry);
    466		sillycounter++;
    467		slen = scnprintf(silly, sizeof(silly),
    468				SILLYNAME_PREFIX "%0*llx%0*x",
    469				SILLYNAME_FILEID_LEN, fileid,
    470				SILLYNAME_COUNTER_LEN, sillycounter);
    471
    472		dfprintk(VFS, "NFS: trying to rename %pd to %s\n",
    473				dentry, silly);
    474
    475		sdentry = lookup_one_len(silly, dentry->d_parent, slen);
    476		/*
    477		 * N.B. Better to return EBUSY here ... it could be
    478		 * dangerous to delete the file while it's in use.
    479		 */
    480		if (IS_ERR(sdentry))
    481			goto out;
    482	} while (d_inode(sdentry) != NULL); /* need negative lookup */
    483
    484	ihold(inode);
    485
    486	/* queue unlink first. Can't do this from rpc_release as it
    487	 * has to allocate memory
    488	 */
    489	error = nfs_async_unlink(dentry, &sdentry->d_name);
    490	if (error)
    491		goto out_dput;
    492
    493	/* run the rename task, undo unlink if it fails */
    494	task = nfs_async_rename(dir, dir, dentry, sdentry,
    495					nfs_complete_sillyrename);
    496	if (IS_ERR(task)) {
    497		error = -EBUSY;
    498		nfs_cancel_async_unlink(dentry);
    499		goto out_dput;
    500	}
    501
    502	/* wait for the RPC task to complete, unless a SIGKILL intervenes */
    503	error = rpc_wait_for_completion_task(task);
    504	if (error == 0)
    505		error = task->tk_status;
    506	switch (error) {
    507	case 0:
    508		/* The rename succeeded */
    509		nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
    510		spin_lock(&inode->i_lock);
    511		NFS_I(inode)->attr_gencount = nfs_inc_attr_generation_counter();
    512		nfs_set_cache_invalid(inode, NFS_INO_INVALID_CHANGE |
    513						     NFS_INO_INVALID_CTIME |
    514						     NFS_INO_REVAL_FORCED);
    515		spin_unlock(&inode->i_lock);
    516		d_move(dentry, sdentry);
    517		break;
    518	case -ERESTARTSYS:
    519		/* The result of the rename is unknown. Play it safe by
    520		 * forcing a new lookup */
    521		d_drop(dentry);
    522		d_drop(sdentry);
    523	}
    524	rpc_put_task(task);
    525out_dput:
    526	iput(inode);
    527	dput(sdentry);
    528out:
    529	return error;
    530}