[PATCH 13/13] ubifs: update implementation from u-boot v2016.03

Renaud Barbier renaud.barbier at ge.com
Tue Jul 19 04:41:49 PDT 2016


I just tested the v2016.07 version.

I noticed that the readlink function returns an empty variable and found
that symlink that used to appear as:
OWBOOT> / ls -l /mnt/
lrwxrwxrwx              7 active -> primary
drwxr-xr-x            472 primary

now appears as:

OWBOOT> / ls -l /mnt/
drwxr-xr-x            472 active
drwxr-xr-x            472 primary

It is due the ubifs_findfile function resolving the symlink as when the
code under "if ((inode->i_mode & S_IFMT) == S_IFLNK) {" is commented
out, the link is resolved by the ubifs_readlink entry point.


In another hand, it looks like ubifs_readlink does not deal with symlink
recursion.






On 17/03/2016 10:00, Alexander Stein wrote:
> -static struct inode *ubifs_findfile(struct super_block *sb, const char *filename)
> +static unsigned long ubifs_findfile(struct super_block *sb, const char *filename)
>  {
>  	int ret;
>  	char *next;
>  	char fpath[128];
> +	char symlinkpath[128];
>  	char *name = fpath;
>  	unsigned long root_inum = 1;
>  	unsigned long inum;
> -	struct inode *inode = 0;
> +	int symlink_count = 0; /* Don't allow symlink recursion */
> +	char link_name[64];
>  
>  	strcpy(fpath, filename);
>  
> @@ -238,9 +514,12 @@ static struct inode *ubifs_findfile(struct super_block *sb, const char *filename
>  	 */
>  	inum = root_inum;
>  	if (!name || *name == '\0')
> -		return ubifs_iget(sb, 1);
> +		return inum;
>  
>  	for (;;) {
> +		struct inode *inode;
> +		struct ubifs_inode *ui;
> +
>  		/* Extract the actual part from the pathname.  */
>  		next = strchr(name, '/');
>  		if (next) {
> @@ -248,13 +527,41 @@ static struct inode *ubifs_findfile(struct super_block *sb, const char *filename
>  			while (*next == '/')
>  				*(next++) = '\0';
>  		}
> +
>  		ret = ubifs_finddir(sb, name, root_inum, &inum);
>  		if (!ret)
> -			break;
> -
> +			return 0;
>  		inode = ubifs_iget(sb, inum);
> +
>  		if (!inode)
> -			break;
> +			return 0;
> +		ui = ubifs_inode(inode);
> +
> +		if ((inode->i_mode & S_IFMT) == S_IFLNK) {
> +			char buf[128];
> +
> +			/* We have some sort of symlink recursion, bail out */
> +			if (symlink_count++ > 8) {
> +				printf("Symlink recursion, aborting\n");
> +				return 0;
> +			}
> +			memcpy(link_name, ui->data, ui->data_len);
> +			link_name[ui->data_len] = '\0';
> +
> +			if (link_name[0] == '/') {
> +				/* Absolute path, redo everything without
> +				 * the leading slash */
> +				next = name = link_name + 1;
> +				root_inum = 1;
> +				continue;
> +			}
> +			/* Relative to cur dir */
> +			sprintf(buf, "%s/%s",
> +					link_name, next == NULL ? "" : next);
> +			memcpy(symlinkpath, buf, sizeof(buf));
> +			next = name = symlinkpath;
> +			continue;
> +		}




More information about the barebox mailing list