Re: restorecon and symbolic links

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 01/09/09 15:46, Stephen Smalley wrote:
> On Tue, 2009-09-01 at 15:34 +0100, Martin Orr wrote:
>> Here's a patch that works, and does what I want.
>>
>> It moves most of process_one into process_one_realpath, which assumes that
>> the path it is given requires no further expansion.
>> Now if given a symlink, call symlink_realpath to get the real path ignoring
>> the last component, and give that to process_one_realpath; tell
>> process_one_realpath not to recurse so this acts on the symlink only.
>> Then call process_one_realpath again with the real path of the target, to
>> recurse into it.
> 
> The function naming seems the reverse of what one might expect (the
> function with _realpath in the name doesn't call realpath).   Also, you
> can pass NULL for the resolved path argument to realpath() rather than
> giving it a fixed-size buffer from the stack and let it allocate the
> buffer for you, as we already do elsewhere.

The reason I named the function that way was because the function with
_realpath expects a real path as an argument, but if this is confusing or
goes against a convention used elsewhere then it could be changed.

I copied the symlink_realpath code from what used to be in match.  I assumed
that it needed a buffer on the stack because it then concatenates the last
component of the path on to that buffer, and realpath might not allocate a
long enough buffer.

> > Not sure it is worth warning about the broken symlink case, and that
> > will trigger warnings for your existing users in the
> > restorecon /dev/stdin case, right?

I agree, it is not worth warning about broken symlinks, except maybe if -v
is specified.

>> diff --git a/policycoreutils/setfiles/setfiles.c b/policycoreutils/setfiles/setfiles.c
>> index 4c47f21..c84cd6f 100644
>> --- a/policycoreutils/setfiles/setfiles.c
>> +++ b/policycoreutils/setfiles/setfiles.c
>> @@ -545,7 +545,47 @@ int canoncon(char **contextp)
>>  	return rc;
>>  }
>>  
>> -static int process_one(char *name)
>> +static int symlink_realpath(char *name, char *path)
>> +{
>> +	char *p = NULL, *file_sep;
>> +	char *tmp_path = strdupa(name);
>> +	size_t len = 0;
>> +
>> +	if (!tmp_path) {
>> +		fprintf(stderr, "strdupa on %s failed:  %s\n", name,
>> +			strerror(errno));
>> +		return -1;
>> +	}
>> +	file_sep = strrchr(tmp_path, '/');
>> +	if (file_sep == tmp_path) {
>> +		file_sep++;
>> +		p = strcpy(path, "");
>> +	} else if (file_sep) {
>> +		*file_sep = 0;
>> +		file_sep++;
>> +		p = realpath(tmp_path, path);
>> +	} else {
>> +		file_sep = tmp_path;
>> +		p = realpath("./", path);
>> +	}
>> +	if (p)
>> +		len = strlen(p);
>> +	if (!p || len + strlen(file_sep) + 2 > PATH_MAX) {
>> +		fprintf(stderr, "symlink_realpath(%s) failed %s\n", name,
>> +			strerror(errno));
>> +		return -1;
>> +	}
>> +	p += len;
>> +	/* ensure trailing slash of directory name */
>> +	if (len == 0 || *(p - 1) != '/') {
>> +		*p = '/';
>> +		p++;
>> +	}
>> +	strcpy(p, file_sep);
>> +	return 0;
>> +}
>> +
>> +static int process_one_realpath(char *name, int recurse_this_path)
>>  {
>>  	int rc = 0;
>>  	const char *namelist[2];
>> @@ -553,18 +593,6 @@ static int process_one(char *name)
>>  	FTS *fts_handle;
>>  	FTSENT *ftsent;
>>  
>> -	if (expand_realpath) {
>> -		char *p;
>> -		p = realpath(name, NULL);
>> -		if (!p) {
>> -			fprintf(stderr, "realpath(%s) failed %s\n", name,
>> -				strerror(errno));
>> -			return -1;
>> -		}
>> -		name = p;
>> -	}
>> -
>> -
>>  	if (!strcmp(name, "/"))
>>  		mass_relabel = 1;
>>  
>> @@ -604,7 +632,7 @@ static int process_one(char *name)
>>  			fts_set(fts_handle, ftsent, FTS_SKIP);
>>  		if (rc == ERR)
>>  			goto err;
>> -		if (!recurse)
>> +		if (!recurse_this_path)
>>  			break;
>>  	} while ((ftsent = fts_read(fts_handle)) != NULL);
>>  
>> @@ -619,8 +647,6 @@ out:
>>  	}
>>  	if (fts_handle)
>>  		fts_close(fts_handle);
>> -	if (expand_realpath)
>> -		free(name);
>>  	return rc;
>>  
>>  err:
>> @@ -630,6 +656,55 @@ err:
>>  	goto out;
>>  }
>>  
>> +static int process_one(char *name)
>> +{
>> +	int rc = 0;
>> +	char *p;
>> +	struct stat sb;
>> +
>> +	if (!expand_realpath) {
>> +		return process_one_realpath(name, recurse);
>> +	} else {
>> +		rc = lstat(name, &sb);
>> +		if (rc < 0) {
>> +			fprintf(stderr, "%s:  lstat(%s) failed:  %s\n",
>> +				progname, name,	strerror(errno));
>> +			return -1;
>> +		}
>> +
>> +		if (S_ISLNK(sb.st_mode)) {
>> +			char path[PATH_MAX + 1];
>> +
>> +			rc = symlink_realpath(name, path);
>> +			if (rc < 0)
>> +				return rc;
>> +			rc = process_one_realpath(path, 0);
>> +			if (rc < 0)
>> +				return rc;
>> +
>> +			p = realpath(name, NULL);
>> +			if (!p) {
>> +				fprintf(stderr, "Warning: %s: Broken symlink: %s\n",
>> +					name, strerror(errno));
>> +				return 0;
>> +			}
>> +			rc = process_one_realpath(p, recurse);
>> +			free(p);
>> +			return rc;
>> +		} else {
>> +			p = realpath(name, NULL);
>> +			if (!p) {
>> +				fprintf(stderr, "realpath(%s) failed %s\n", name,
>> +					strerror(errno));
>> +				return -1;
>> +			}
>> +			rc = process_one_realpath(p, recurse);
>> +			free(p);
>> +			return rc;
>> +		}
>> +	}
>> +}
>> +
>>  #ifndef USE_AUDIT
>>  static void maybe_audit_mass_relabel(void)
>>  {
>>


-- 
Martin Orr

--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@xxxxxxxxxxxxx with
the words "unsubscribe selinux" without quotes as the message.

[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux