diff options
Diffstat (limited to 'fs/proc/generic.c')
| -rw-r--r-- | fs/proc/generic.c | 32 | 
1 files changed, 16 insertions, 16 deletions
diff --git a/fs/proc/generic.c b/fs/proc/generic.c index b7f268eb5f45..317b72641ebf 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c @@ -27,7 +27,7 @@  #include "internal.h" -DEFINE_SPINLOCK(proc_subdir_lock); +static DEFINE_SPINLOCK(proc_subdir_lock);  static int proc_match(unsigned int len, const char *name, struct proc_dir_entry *de)  { @@ -330,28 +330,28 @@ static struct proc_dir_entry *__proc_create(struct proc_dir_entry **parent,  					  nlink_t nlink)  {  	struct proc_dir_entry *ent = NULL; -	const char *fn = name; -	unsigned int len; - -	/* make sure name is valid */ -	if (!name || !strlen(name)) -		goto out; +	const char *fn; +	struct qstr qstr;  	if (xlate_proc_name(name, parent, &fn) != 0)  		goto out; +	qstr.name = fn; +	qstr.len = strlen(fn); +	if (qstr.len == 0 || qstr.len >= 256) { +		WARN(1, "name len %u\n", qstr.len); +		return NULL; +	} +	if (*parent == &proc_root && name_to_int(&qstr) != ~0U) { +		WARN(1, "create '/proc/%s' by hand\n", qstr.name); +		return NULL; +	} -	/* At this point there must not be any '/' characters beyond *fn */ -	if (strchr(fn, '/')) -		goto out; - -	len = strlen(fn); - -	ent = kzalloc(sizeof(struct proc_dir_entry) + len + 1, GFP_KERNEL); +	ent = kzalloc(sizeof(struct proc_dir_entry) + qstr.len + 1, GFP_KERNEL);  	if (!ent)  		goto out; -	memcpy(ent->name, fn, len + 1); -	ent->namelen = len; +	memcpy(ent->name, fn, qstr.len + 1); +	ent->namelen = qstr.len;  	ent->mode = mode;  	ent->nlink = nlink;  	atomic_set(&ent->count, 1);  |