Bug 761855 (GLUSTER-123)

Summary: segfault in /usr/bin/attr on gluster path
Product: [Community] GlusterFS Reporter: idadesub
Component: fuseAssignee: Anand Avati <aavati>
Status: CLOSED WORKSFORME QA Contact:
Severity: medium Docs Contact:
Priority: low    
Version: 2.0.3CC: chrisw, gluster-bugs
Target Milestone: ---   
Target Release: ---   
Hardware: x86_64   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:

Description idadesub 2009-07-08 22:56:50 UTC
I'm running into a segfault when I try to use "attr -l /mnt/glusterfs" on a gluster path:

#0  0x00002aaaaad3e887 in strncmp () from /lib64/libc.so.6
#1  0x00002aaaaabc7266 in api_unconvert (name=0x7fff987f1990 "glusterfs.test", linuxname=0x7fff987f5000 <Address 0x7fff987f5000 out of bounds>, irixflags=1) at libattr.c:72
#2  0x00002aaaaabc808f in attr_list (path=0x7fff987f37b3 "/mnt/glusterfs", buffer=0x503000 "\001", buffersize=61440, flags=1, cursor=0x7fff987f1b10) at libattr.c:293
#3  0x0000000000400f05 in main (argc=<value optimized out>, argv=<value optimized out>) at attr.c:225

Maybe something isn't being properly exposed in fuse? This is with attr-2.4.28-1.2. This is happens every time so let me know if you need more info.

The relevant code from attr is calling this:

int
attr_list(const char *path, char *buffer, const int buffersize, int flags,
	  attrlist_cursor_t *cursor)
{
	const char *l;
	int length, count = 0;
	char lbuf[MAXLISTLEN];
	char name[MAXNAMELEN+16];
	unsigned int start_offset, end_offset;

	if (buffersize < sizeof(attrlist_t)) {
		errno = EINVAL;
		return -1;
	}
	bzero(buffer, sizeof(attrlist_t));

	if (flags & ATTR_DONTFOLLOW)
		length = llistxattr(path, lbuf, sizeof(lbuf));
	else
		length = listxattr(path, lbuf, sizeof(lbuf));
	if (length <= 0)
		return length;

	start_offset = sizeof(attrlist_t);
	end_offset = buffersize & ~(8-1);	/* 8 byte align */

	for (l = lbuf; l != lbuf + length; l = strchr(l, '\0') + 1) {
		if (api_unconvert(name, l, flags))
			continue;
		if (flags & ATTR_DONTFOLLOW)
			length = lgetxattr(path, l, NULL, 0);
		else
			length =  getxattr(path, l, NULL, 0);
		if (length < 0 && (errno == ENOATTR || errno == ENOTSUP))
			continue;
		if (count++ < cursor->opaque[0])
			continue;
		if (attr_list_pack(name, length, buffer, buffersize,
				   &start_offset, &end_offset)) {
			cursor->opaque[0] = count;
			break;
		}
	}
	return 0;
}

Comment 1 Anand Avati 2010-01-23 19:50:01 UTC
The code snippet pasted below does not seem to handle the case where the amount of key listing exceeds the buffer size (where it need not be '\0' terminated). Behavior of glusterfs extended attributes listing is exactly like that of ext3 when strace dumps are seen and the same attr -l command works fine. Atleast in 3.0.0 it works fine (should work fine in older versions as well).

If you can give the strace outputs of the attr crashing run and also strace on ext3 on a file with the same extended attributes (maybe from the backend of the glusterfs export) it will confirm whether glusterfs behaves any differently.

Avati