-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 In the past pam_selinux would return a bogus login context if the login program was running with the wrong context. If you ran sshd as unconfined_t you might get the login user loggin in as pam_oddjob_mkhomedir_t or some other bogus type. This change fixes the code to return an error if it can not return a good match. This patch looks good to me. acked. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.15 (GNU/Linux) Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iEYEARECAAYFAlJpJqQACgkQrlYvE4MpobOkmQCdGD2YBvJx1vg0VkNgsyni6Y4F WwgAoKAicAI1nPrReds9DLJkSkamj10X =YR4U -----END PGP SIGNATURE-----
>From 6c2bb65797ccc92693f42f9399ee839f1774268a Mon Sep 17 00:00:00 2001 From: Dan Walsh <dwalsh@xxxxxxxxxx> Date: Wed, 9 Oct 2013 15:29:50 -0400 Subject: [PATCH 14/74] Change get_context_list to return an error rather then guess at a match. In the past pam_selinux would return a bogus login context if the login program was running with the wrong context. If you ran sshd as unconfined_t you might get the login user loggin in as pam_oddjob_mkhomedir_t or some other bogus type. This change fixes the code to return an error if it can not return a good match. --- libselinux/src/get_context_list.c | 46 +++++++++++++++------------------------ 1 file changed, 18 insertions(+), 28 deletions(-) diff --git a/libselinux/src/get_context_list.c b/libselinux/src/get_context_list.c index b9e8002..1d91123 100644 --- a/libselinux/src/get_context_list.c +++ b/libselinux/src/get_context_list.c @@ -426,7 +426,7 @@ int get_ordered_context_list(const char *user, /* Initialize ordering array. */ ordering = malloc(nreach * sizeof(unsigned int)); if (!ordering) - goto oom_order; + goto failsafe; for (i = 0; i < nreach; i++) ordering[i] = nreach; @@ -435,7 +435,7 @@ int get_ordered_context_list(const char *user, fname_len = strlen(user_contexts_path) + strlen(user) + 2; fname = malloc(fname_len); if (!fname) - goto oom_order; + goto failsafe; snprintf(fname, fname_len, "%s%s", user_contexts_path, user); fp = fopen(fname, "r"); if (fp) { @@ -463,33 +463,31 @@ int get_ordered_context_list(const char *user, __FUNCTION__, selinux_default_context_path()); /* Fall through */ } + rc = 0; } + if (!nordered) + goto failsafe; + /* Apply the ordering. */ - if (nordered) { - co = malloc(nreach * sizeof(struct context_order)); - if (!co) - goto oom_order; - for (i = 0; i < nreach; i++) { - co[i].con = reachable[i]; - co[i].order = ordering[i]; - } - qsort(co, nreach, sizeof(struct context_order), order_compare); - for (i = 0; i < nreach; i++) - reachable[i] = co[i].con; - free(co); + co = malloc(nreach * sizeof(struct context_order)); + if (!co) + goto failsafe; + for (i = 0; i < nreach; i++) { + co[i].con = reachable[i]; + co[i].order = ordering[i]; } + qsort(co, nreach, sizeof(struct context_order), order_compare); + for (i = 0; i < nreach; i++) + reachable[i] = co[i].con; + free(co); - /* Return the ordered list. - If we successfully ordered it, then only report the ordered entries - to the caller. Otherwise, fall back to the entire reachable list. */ - if (nordered && nordered < nreach) { + /* Only report the ordered entries to the caller. */ + if (nordered <= nreach) { for (i = nordered; i < nreach; i++) free(reachable[i]); reachable[nordered] = NULL; rc = nordered; - } else { - rc = nreach; } out: @@ -523,14 +521,6 @@ int get_ordered_context_list(const char *user, } rc = 1; /* one context in the list */ goto out; - - oom_order: - /* Unable to order context list due to OOM condition. - Fall back to unordered reachable context list. */ - fprintf(stderr, "%s: out of memory, unable to order list\n", - __FUNCTION__); - rc = nreach; - goto out; } hidden_def(get_ordered_context_list) -- 1.8.3.1