mirror of
https://github.com/SELinuxProject/selinux
synced 2024-12-24 15:02:44 +00:00
libselinux: move realpath helper to matchpathcon library
Instead of only doing path simplification and symlink following for the matchpathcon helper instead do it in the library potion. This was an issue when in python some called selinux.matchpatchcon("//lib64", 0) and got the wrong answer (because the // wasn't being dealt with) Signed-off-by: Eric Paris <eparis@redhat.com> Acked-by: Dan Walsh <dwalsh@redhat.com>
This commit is contained in:
parent
57c6012f86
commit
7df397d3d9
@ -5,6 +5,7 @@
|
||||
#include "selinux_internal.h"
|
||||
#include "label_internal.h"
|
||||
#include "callbacks.h"
|
||||
#include <limits.h>
|
||||
|
||||
static __thread struct selabel_handle *hnd;
|
||||
|
||||
@ -337,14 +338,82 @@ void matchpathcon_fini(void)
|
||||
}
|
||||
}
|
||||
|
||||
int matchpathcon(const char *name, mode_t mode, security_context_t * con)
|
||||
/*
|
||||
* We do not want to resolve a symlink to a real path if it is the final
|
||||
* component of the name. Thus we split the pathname on the last "/" and
|
||||
* determine a real path component of the first portion. We then have to
|
||||
* copy the last part back on to get the final real path. Wheww.
|
||||
*/
|
||||
static int symlink_realpath(const char *name, char *resolved_path)
|
||||
{
|
||||
char *last_component;
|
||||
char *tmp_path, *p;
|
||||
size_t len = 0;
|
||||
int rc = 0;
|
||||
|
||||
tmp_path = strdup(name);
|
||||
if (!tmp_path) {
|
||||
fprintf(stderr, "symlink_realpath(%s) strdup() failed: %s\n",
|
||||
name, strerror(errno));
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
last_component = strrchr(tmp_path, '/');
|
||||
|
||||
if (last_component == tmp_path) {
|
||||
last_component++;
|
||||
p = strcpy(resolved_path, "/");
|
||||
} else if (last_component) {
|
||||
*last_component = '\0';
|
||||
last_component++;
|
||||
p = realpath(tmp_path, resolved_path);
|
||||
} else {
|
||||
last_component = tmp_path;
|
||||
p = realpath("./", resolved_path);
|
||||
}
|
||||
|
||||
if (!p) {
|
||||
fprintf(stderr, "symlink_realpath(%s) realpath() failed: %s\n",
|
||||
name, strerror(errno));
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
len = strlen(p);
|
||||
if (len + strlen(last_component) + 1 > PATH_MAX) {
|
||||
fprintf(stderr, "symlink_realpath(%s) failed: Filename too long \n",
|
||||
name);
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
resolved_path += len;
|
||||
strcpy(resolved_path, last_component);
|
||||
out:
|
||||
free(tmp_path);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int matchpathcon(const char *path, mode_t mode, security_context_t * con)
|
||||
{
|
||||
char stackpath[PATH_MAX + 1];
|
||||
char *p = NULL;
|
||||
if (!hnd && (matchpathcon_init_prefix(NULL, NULL) < 0))
|
||||
return -1;
|
||||
|
||||
if (S_ISLNK(mode)) {
|
||||
if (!symlink_realpath(path, stackpath))
|
||||
path = stackpath;
|
||||
} else {
|
||||
p = realpath(path, stackpath);
|
||||
if (p)
|
||||
path = p;
|
||||
}
|
||||
|
||||
return notrans ?
|
||||
selabel_lookup_raw(hnd, con, name, mode) :
|
||||
selabel_lookup(hnd, con, name, mode);
|
||||
selabel_lookup_raw(hnd, con, path, mode) :
|
||||
selabel_lookup(hnd, con, path, mode);
|
||||
}
|
||||
|
||||
int matchpathcon_index(const char *name, mode_t mode, security_context_t * con)
|
||||
|
@ -43,63 +43,6 @@ int printmatchpathcon(char *path, int header, int mode)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* We do not want to resolve a symlink to a real path if it is the final
|
||||
* component of the name. Thus we split the pathname on the last "/" and
|
||||
* determine a real path component of the first portion. We then have to
|
||||
* copy the last part back on to get the final real path. Wheww.
|
||||
*/
|
||||
static int symlink_realpath(char *name, char *resolved_path)
|
||||
{
|
||||
char *last_component;
|
||||
char *tmp_path, *p;
|
||||
size_t len = 0;
|
||||
int rc = 0;
|
||||
|
||||
tmp_path = strdup(name);
|
||||
if (!tmp_path) {
|
||||
fprintf(stderr, "symlink_realpath(%s) strdup() failed: %s\n",
|
||||
name, strerror(errno));
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
last_component = strrchr(tmp_path, '/');
|
||||
|
||||
if (last_component == tmp_path) {
|
||||
last_component++;
|
||||
p = strcpy(resolved_path, "/");
|
||||
} else if (last_component) {
|
||||
*last_component = '\0';
|
||||
last_component++;
|
||||
p = realpath(tmp_path, resolved_path);
|
||||
} else {
|
||||
last_component = tmp_path;
|
||||
p = realpath("./", resolved_path);
|
||||
}
|
||||
|
||||
if (!p) {
|
||||
fprintf(stderr, "symlink_realpath(%s) realpath() failed: %s\n",
|
||||
name, strerror(errno));
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
len = strlen(p);
|
||||
if (len + strlen(last_component) + 1 > PATH_MAX) {
|
||||
fprintf(stderr, "symlink_realpath(%s) failed: Filename too long \n",
|
||||
name);
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
resolved_path += len;
|
||||
strcpy(resolved_path, last_component);
|
||||
out:
|
||||
free(tmp_path);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int i, init = 0;
|
||||
@ -166,8 +109,7 @@ int main(int argc, char **argv)
|
||||
for (i = optind; i < argc; i++) {
|
||||
int rc, mode = 0;
|
||||
struct stat buf;
|
||||
char *p, *path = argv[i];
|
||||
char stackpath[PATH_MAX + 1];
|
||||
char *path = argv[i];
|
||||
int len = strlen(path);
|
||||
if (len > 1 && path[len - 1 ] == '/')
|
||||
path[len - 1 ] = '\0';
|
||||
@ -175,16 +117,6 @@ int main(int argc, char **argv)
|
||||
if (lstat(path, &buf) == 0)
|
||||
mode = buf.st_mode;
|
||||
|
||||
if (S_ISLNK(mode)) {
|
||||
rc = symlink_realpath(path, stackpath);
|
||||
if (!rc)
|
||||
path = stackpath;
|
||||
} else {
|
||||
p = realpath(path, stackpath);
|
||||
if (p)
|
||||
path = p;
|
||||
}
|
||||
|
||||
if (verify) {
|
||||
rc = selinux_file_context_verify(path, mode);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user