4baf0f6949
CVE-2010-3853 - try to connect to an abstract X-socket first to verify we are at real console (#647191)
83 lines
2.7 KiB
Diff
83 lines
2.7 KiB
Diff
diff -up Linux-PAM-1.1.3/modules/pam_console/pam_console.c.abstract Linux-PAM-1.1.3/modules/pam_console/pam_console.c
|
|
--- Linux-PAM-1.1.3/modules/pam_console/pam_console.c.abstract 2008-12-16 13:37:52.000000000 +0100
|
|
+++ Linux-PAM-1.1.3/modules/pam_console/pam_console.c 2010-11-01 17:01:55.000000000 +0100
|
|
@@ -34,6 +34,8 @@
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/param.h>
|
|
+#include <sys/socket.h>
|
|
+#include <sys/un.h>
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
#include <stdio.h>
|
|
@@ -136,6 +138,32 @@ check_one_console_name(const char *name,
|
|
}
|
|
|
|
static int
|
|
+try_xsocket(const char *path, size_t len) {
|
|
+ int fd;
|
|
+ union {
|
|
+ struct sockaddr sa;
|
|
+ struct sockaddr_un su;
|
|
+ } addr;
|
|
+
|
|
+ fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
|
+ if (fd < 0)
|
|
+ return 0;
|
|
+
|
|
+ memset(&addr, 0, sizeof(addr));
|
|
+ addr.su.sun_family = AF_UNIX;
|
|
+
|
|
+ if (len > sizeof(addr.su.sun_path))
|
|
+ return 0;
|
|
+ memcpy(addr.su.sun_path, path, len);
|
|
+ if (connect(fd, &addr.sa, sizeof(addr.su)) == 0) {
|
|
+ close(fd);
|
|
+ return 1;
|
|
+ }
|
|
+ close(fd);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int
|
|
check_console_name(pam_handle_t *pamh, const char *consolename, int nonroot_ok, int on_set) {
|
|
int found = 0;
|
|
int statted = 0;
|
|
@@ -186,22 +214,29 @@ check_console_name(pam_handle_t *pamh, c
|
|
if (!statted && (consolename[0] == ':')) {
|
|
int l;
|
|
char *dot = NULL;
|
|
- strcpy(full_path, "/tmp/.X11-unix/X");
|
|
- l = sizeof(full_path) - 1 - strlen(full_path);
|
|
+ char *path = full_path + 1;
|
|
+
|
|
+ full_path[0] = '\0';
|
|
+ strcpy(path, "/tmp/.X11-unix/X");
|
|
+ l = sizeof(full_path) - 2 - strlen(path);
|
|
dot = strchr(consolename + 1, '.');
|
|
if (dot != NULL) {
|
|
l = (l < dot - consolename - 1) ? l : dot - consolename - 1;
|
|
}
|
|
- strncat(full_path, consolename + 1, l);
|
|
+ strncat(path, consolename + 1, l);
|
|
full_path[sizeof(full_path) - 1] = '\0';
|
|
- _pam_log(pamh, LOG_DEBUG, TRUE, "checking possible console \"%s\"",
|
|
- full_path);
|
|
- if (lstat(full_path, &st) != -1) {
|
|
+ _pam_log(pamh, LOG_DEBUG, TRUE, "checking possible X socket \"%s\"",
|
|
+ path);
|
|
+
|
|
+ /* this will work because st.st_uid is 0 */
|
|
+ if (try_xsocket(full_path, strlen(path)+1)) {
|
|
+ statted = 1;
|
|
+ } else if (try_xsocket(path, strlen(path))) {
|
|
statted = 1;
|
|
}
|
|
else if (!on_set) { /* there is no X11 socket in case of X11 crash */
|
|
_pam_log(pamh, LOG_DEBUG, TRUE, "can't find X11 socket to examine for %s probably due to X crash", consolename);
|
|
- statted = 1; /* this will work because st.st_uid is 0 */
|
|
+ statted = 1;
|
|
}
|
|
}
|
|
|