1531 lines · 39.4 KB · C
RawDownload
// SPDX-License-Identifier: GPL-2.0/* *  linux/fs/file.c * *  Copyright (C) 1998-1999, Stephen Tweedie and Bill Hawes * *  Manage the dynamic fd arrays in the process files_struct. */ #include <linux/syscalls.h>#include <linux/export.h>#include <linux/fs.h>#include <linux/kernel.h>#include <linux/mm.h>#include <linux/sched/signal.h>#include <linux/slab.h>#include <linux/file.h>#include <linux/fdtable.h>#include <linux/bitops.h>#include <linux/spinlock.h>#include <linux/rcupdate.h>#include <linux/close_range.h>#include <linux/file_ref.h>#include <net/sock.h>#include <linux/init_task.h> #include "internal.h" static noinline bool __file_ref_put_badval(file_ref_t *ref, unsigned long cnt){	/*	 * If the reference count was already in the dead zone, then this	 * put() operation is imbalanced. Warn, put the reference count back to	 * DEAD and tell the caller to not deconstruct the object.	 */	if (WARN_ONCE(cnt >= FILE_REF_RELEASED, "imbalanced put on file reference count")) {		atomic_long_set(&ref->refcnt, FILE_REF_DEAD);		return false;	} 	/*	 * This is a put() operation on a saturated refcount. Restore the	 * mean saturation value and tell the caller to not deconstruct the	 * object.	 */	if (cnt > FILE_REF_MAXREF)		atomic_long_set(&ref->refcnt, FILE_REF_SATURATED);	return false;} /** * __file_ref_put - Slowpath of file_ref_put() * @ref:	Pointer to the reference count * @cnt:	Current reference count * * Invoked when the reference count is outside of the valid zone. * * Return: *	True if this was the last reference with no future references *	possible. This signals the caller that it can safely schedule the *	object, which is protected by the reference counter, for *	deconstruction. * *	False if there are still active references or the put() raced *	with a concurrent get()/put() pair. Caller is not allowed to *	deconstruct the protected object. */bool __file_ref_put(file_ref_t *ref, unsigned long cnt){	/* Did this drop the last reference? */	if (likely(cnt == FILE_REF_NOREF)) {		/*		 * Carefully try to set the reference count to FILE_REF_DEAD.		 *		 * This can fail if a concurrent get() operation has		 * elevated it again or the corresponding put() even marked		 * it dead already. Both are valid situations and do not		 * require a retry. If this fails the caller is not		 * allowed to deconstruct the object.		 */		if (!atomic_long_try_cmpxchg_release(&ref->refcnt, &cnt, FILE_REF_DEAD))			return false; 		/*		 * The caller can safely schedule the object for		 * deconstruction. Provide acquire ordering.		 */		smp_acquire__after_ctrl_dep();		return true;	} 	return __file_ref_put_badval(ref, cnt);}EXPORT_SYMBOL_GPL(__file_ref_put); unsigned int sysctl_nr_open __read_mostly = 1024*1024;unsigned int sysctl_nr_open_min = BITS_PER_LONG;/* our min() is unusable in constant expressions ;-/ */#define __const_min(x, y) ((x) < (y) ? (x) : (y))unsigned int sysctl_nr_open_max =	__const_min(INT_MAX, ~(size_t)0/sizeof(void *)) & -BITS_PER_LONG; static void __free_fdtable(struct fdtable *fdt){	kvfree(fdt->fd);	kvfree(fdt->open_fds);	kfree(fdt);} static void free_fdtable_rcu(struct rcu_head *rcu){	__free_fdtable(container_of(rcu, struct fdtable, rcu));} #define BITBIT_NR(nr)	BITS_TO_LONGS(BITS_TO_LONGS(nr))#define BITBIT_SIZE(nr)	(BITBIT_NR(nr) * sizeof(long)) #define fdt_words(fdt) ((fdt)->max_fds / BITS_PER_LONG) // words in ->open_fds/* * Copy 'count' fd bits from the old table to the new table and clear the extra * space if any.  This does not copy the file pointers.  Called with the files * spinlock held for write. */static inline void copy_fd_bitmaps(struct fdtable *nfdt, struct fdtable *ofdt,			    unsigned int copy_words){	unsigned int nwords = fdt_words(nfdt); 	bitmap_copy_and_extend(nfdt->open_fds, ofdt->open_fds,			copy_words * BITS_PER_LONG, nwords * BITS_PER_LONG);	bitmap_copy_and_extend(nfdt->close_on_exec, ofdt->close_on_exec,			copy_words * BITS_PER_LONG, nwords * BITS_PER_LONG);	bitmap_copy_and_extend(nfdt->full_fds_bits, ofdt->full_fds_bits,			copy_words, nwords);} /* * Copy all file descriptors from the old table to the new, expanded table and * clear the extra space.  Called with the files spinlock held for write. */static void copy_fdtable(struct fdtable *nfdt, struct fdtable *ofdt){	size_t cpy, set; 	BUG_ON(nfdt->max_fds < ofdt->max_fds); 	cpy = ofdt->max_fds * sizeof(struct file *);	set = (nfdt->max_fds - ofdt->max_fds) * sizeof(struct file *);	memcpy(nfdt->fd, ofdt->fd, cpy);	memset((char *)nfdt->fd + cpy, 0, set); 	copy_fd_bitmaps(nfdt, ofdt, fdt_words(ofdt));} /* * Note how the fdtable bitmap allocations very much have to be a multiple of * BITS_PER_LONG. This is not only because we walk those things in chunks of * 'unsigned long' in some places, but simply because that is how the Linux * kernel bitmaps are defined to work: they are not "bits in an array of bytes", * they are very much "bits in an array of unsigned long". */static struct fdtable *alloc_fdtable(unsigned int slots_wanted){	struct fdtable *fdt;	unsigned int nr;	void *data; 	/*	 * Figure out how many fds we actually want to support in this fdtable.	 * Allocation steps are keyed to the size of the fdarray, since it	 * grows far faster than any of the other dynamic data. We try to fit	 * the fdarray into comfortable page-tuned chunks: starting at 1024B	 * and growing in powers of two from there on.  Since we called only	 * with slots_wanted > BITS_PER_LONG (embedded instance in files->fdtab	 * already gives BITS_PER_LONG slots), the above boils down to	 * 1.  use the smallest power of two large enough to give us that many	 * slots.	 * 2.  on 32bit skip 64 and 128 - the minimal capacity we want there is	 * 256 slots (i.e. 1Kb fd array).	 * 3.  on 64bit don't skip anything, 1Kb fd array means 128 slots there	 * and we are never going to be asked for 64 or less.	 */	if (IS_ENABLED(CONFIG_32BIT) && slots_wanted < 256)		nr = 256;	else		nr = roundup_pow_of_two(slots_wanted);	/*	 * Note that this can drive nr *below* what we had passed if sysctl_nr_open	 * had been set lower between the check in expand_files() and here.	 *	 * We make sure that nr remains a multiple of BITS_PER_LONG - otherwise	 * bitmaps handling below becomes unpleasant, to put it mildly...	 */	if (unlikely(nr > sysctl_nr_open)) {		nr = round_down(sysctl_nr_open, BITS_PER_LONG);		if (nr < slots_wanted)			return ERR_PTR(-EMFILE);	} 	/*	 * Check if the allocation size would exceed INT_MAX. kvmalloc_array()	 * and kvmalloc() will warn if the allocation size is greater than	 * INT_MAX, as filp_cache objects are not __GFP_NOWARN.	 *	 * This can happen when sysctl_nr_open is set to a very high value and	 * a process tries to use a file descriptor near that limit. For example,	 * if sysctl_nr_open is set to 1073741816 (0x3ffffff8) - which is what	 * systemd typically sets it to - then trying to use a file descriptor	 * close to that value will require allocating a file descriptor table	 * that exceeds 8GB in size.	 */	if (unlikely(nr > INT_MAX / sizeof(struct file *)))		return ERR_PTR(-EMFILE); 	fdt = kmalloc_obj(struct fdtable, GFP_KERNEL_ACCOUNT);	if (!fdt)		goto out;	fdt->max_fds = nr;	data = kvmalloc_objs(struct file *, nr, GFP_KERNEL_ACCOUNT);	if (!data)		goto out_fdt;	fdt->fd = data; 	data = kvmalloc(max_t(size_t,				 2 * nr / BITS_PER_BYTE + BITBIT_SIZE(nr), L1_CACHE_BYTES),				 GFP_KERNEL_ACCOUNT);	if (!data)		goto out_arr;	fdt->open_fds = data;	data += nr / BITS_PER_BYTE;	fdt->close_on_exec = data;	data += nr / BITS_PER_BYTE;	fdt->full_fds_bits = data; 	return fdt; out_arr:	kvfree(fdt->fd);out_fdt:	kfree(fdt);out:	return ERR_PTR(-ENOMEM);} /* * Expand the file descriptor table. * This function will allocate a new fdtable and both fd array and fdset, of * the given size. * Return <0 error code on error; 0 on successful completion. * The files->file_lock should be held on entry, and will be held on exit. */static int expand_fdtable(struct files_struct *files, unsigned int nr)	__releases(files->file_lock)	__acquires(files->file_lock){	struct fdtable *new_fdt, *cur_fdt; 	spin_unlock(&files->file_lock);	new_fdt = alloc_fdtable(nr + 1); 	/* make sure all fd_install() have seen resize_in_progress	 * or have finished their rcu_read_lock_sched() section.	 */	if (atomic_read(&files->count) > 1)		synchronize_rcu(); 	spin_lock(&files->file_lock);	if (IS_ERR(new_fdt))		return PTR_ERR(new_fdt);	cur_fdt = files_fdtable(files);	BUG_ON(nr < cur_fdt->max_fds);	copy_fdtable(new_fdt, cur_fdt);	rcu_assign_pointer(files->fdt, new_fdt);	if (cur_fdt != &files->fdtab)		call_rcu(&cur_fdt->rcu, free_fdtable_rcu);	/* coupled with smp_rmb() in fd_install() */	smp_wmb();	return 0;} /* * Expand files. * This function will expand the file structures, if the requested size exceeds * the current capacity and there is room for expansion. * Return <0 error code on error; 0 on success. * The files->file_lock should be held on entry, and will be held on exit. */static int expand_files(struct files_struct *files, unsigned int nr)	__releases(files->file_lock)	__acquires(files->file_lock){	struct fdtable *fdt;	int error; repeat:	fdt = files_fdtable(files); 	/* Do we need to expand? */	if (nr < fdt->max_fds)		return 0; 	if (unlikely(files->resize_in_progress)) {		spin_unlock(&files->file_lock);		wait_event(files->resize_wait, !files->resize_in_progress);		spin_lock(&files->file_lock);		goto repeat;	} 	/* Can we expand? */	if (unlikely(nr >= sysctl_nr_open))		return -EMFILE; 	/* All good, so we try */	files->resize_in_progress = true;	error = expand_fdtable(files, nr);	files->resize_in_progress = false; 	wake_up_all(&files->resize_wait);	return error;} static inline void __set_close_on_exec(unsigned int fd, struct fdtable *fdt,				       bool set){	if (set) {		__set_bit(fd, fdt->close_on_exec);	} else {		if (test_bit(fd, fdt->close_on_exec))			__clear_bit(fd, fdt->close_on_exec);	}} static inline void __set_open_fd(unsigned int fd, struct fdtable *fdt, bool set){	__set_bit(fd, fdt->open_fds);	__set_close_on_exec(fd, fdt, set);	fd /= BITS_PER_LONG;	if (!~fdt->open_fds[fd])		__set_bit(fd, fdt->full_fds_bits);} static inline void __clear_open_fd(unsigned int fd, struct fdtable *fdt){	__clear_bit(fd, fdt->open_fds);	fd /= BITS_PER_LONG;	if (test_bit(fd, fdt->full_fds_bits))		__clear_bit(fd, fdt->full_fds_bits);} static inline bool fd_is_open(unsigned int fd, const struct fdtable *fdt){	return test_bit(fd, fdt->open_fds);} /* * Note that a sane fdtable size always has to be a multiple of * BITS_PER_LONG, since we have bitmaps that are sized by this. * * punch_hole is optional - when close_range() is asked to unshare * and close, we don't need to copy descriptors in that range, so * a smaller cloned descriptor table might suffice if the last * currently opened descriptor falls into that range. */static unsigned int sane_fdtable_size(struct fdtable *fdt, struct fd_range *punch_hole){	unsigned int last = find_last_bit(fdt->open_fds, fdt->max_fds); 	if (last == fdt->max_fds)		return NR_OPEN_DEFAULT;	if (punch_hole && punch_hole->to >= last && punch_hole->from <= last) {		last = find_last_bit(fdt->open_fds, punch_hole->from);		if (last == punch_hole->from)			return NR_OPEN_DEFAULT;	}	return ALIGN(last + 1, BITS_PER_LONG);} /* * Allocate a new descriptor table and copy contents from the passed in * instance.  Returns a pointer to cloned table on success, ERR_PTR() * on failure.  For 'punch_hole' see sane_fdtable_size(). */struct files_struct *dup_fd(struct files_struct *oldf, struct fd_range *punch_hole){	struct files_struct *newf;	struct file **old_fds, **new_fds;	unsigned int open_files, i;	struct fdtable *old_fdt, *new_fdt; 	newf = kmem_cache_alloc(files_cachep, GFP_KERNEL);	if (!newf)		return ERR_PTR(-ENOMEM); 	atomic_set(&newf->count, 1); 	spin_lock_init(&newf->file_lock);	newf->resize_in_progress = false;	init_waitqueue_head(&newf->resize_wait);	newf->next_fd = 0;	new_fdt = &newf->fdtab;	new_fdt->max_fds = NR_OPEN_DEFAULT;	new_fdt->close_on_exec = newf->close_on_exec_init;	new_fdt->open_fds = newf->open_fds_init;	new_fdt->full_fds_bits = newf->full_fds_bits_init;	new_fdt->fd = &newf->fd_array[0]; 	spin_lock(&oldf->file_lock);	old_fdt = files_fdtable(oldf);	open_files = sane_fdtable_size(old_fdt, punch_hole); 	/*	 * Check whether we need to allocate a larger fd array and fd set.	 */	while (unlikely(open_files > new_fdt->max_fds)) {		spin_unlock(&oldf->file_lock); 		if (new_fdt != &newf->fdtab)			__free_fdtable(new_fdt); 		new_fdt = alloc_fdtable(open_files);		if (IS_ERR(new_fdt)) {			kmem_cache_free(files_cachep, newf);			return ERR_CAST(new_fdt);		} 		/*		 * Reacquire the oldf lock and a pointer to its fd table		 * who knows it may have a new bigger fd table. We need		 * the latest pointer.		 */		spin_lock(&oldf->file_lock);		old_fdt = files_fdtable(oldf);		open_files = sane_fdtable_size(old_fdt, punch_hole);	} 	copy_fd_bitmaps(new_fdt, old_fdt, open_files / BITS_PER_LONG); 	old_fds = old_fdt->fd;	new_fds = new_fdt->fd; 	/*	 * We may be racing against fd allocation from other threads using this	 * files_struct, despite holding ->file_lock.	 *	 * alloc_fd() might have already claimed a slot, while fd_install()	 * did not populate it yet. Note the latter operates locklessly, so	 * the file can show up as we are walking the array below.	 *	 * At the same time we know no files will disappear as all other	 * operations take the lock.	 *	 * Instead of trying to placate userspace racing with itself, we	 * ref the file if we see it and mark the fd slot as unused otherwise.	 */	for (i = open_files; i != 0; i--) {		struct file *f = rcu_dereference_raw(*old_fds++);		if (f) {			get_file(f);		} else {			__clear_open_fd(open_files - i, new_fdt);		}		rcu_assign_pointer(*new_fds++, f);	}	spin_unlock(&oldf->file_lock); 	/* clear the remainder */	memset(new_fds, 0, (new_fdt->max_fds - open_files) * sizeof(struct file *)); 	rcu_assign_pointer(newf->fdt, new_fdt); 	return newf;} static struct fdtable *close_files(struct files_struct * files){	/*	 * It is safe to dereference the fd table without RCU or	 * ->file_lock because this is the last reference to the	 * files structure.	 */	struct fdtable *fdt = rcu_dereference_raw(files->fdt);	unsigned int i, j = 0; 	for (;;) {		unsigned long set;		i = j * BITS_PER_LONG;		if (i >= fdt->max_fds)			break;		set = fdt->open_fds[j++];		while (set) {			if (set & 1) {				struct file *file = fdt->fd[i];				if (file) {					filp_close(file, files);					cond_resched();				}			}			i++;			set >>= 1;		}

Lines 1–500 of 1531.