SHA256
1
0
forked from pool/sssd

Accepting request 63646 from network:ldap

Accepted submit request 63646 from user rhafer

OBS-URL: https://build.opensuse.org/request/show/63646
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/sssd?expand=0&rev=20
This commit is contained in:
Sascha Peilicke 2011-03-09 09:32:53 +00:00 committed by Git OBS Bridge
parent c680f93079
commit 6a2b6b5254
6 changed files with 29 additions and 310 deletions

View File

@ -1,269 +0,0 @@
From af93a65bebb1f007eecbeabd07b7ae8b7cc276c9 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Mon, 6 Dec 2010 21:18:50 +0100
Subject: Validate user supplied size of data items
Specially crafted packages might lead to an integer overflow and the
parsing of the input buffer might not continue as expected. This issue
was identified by Sebastian Krahmer <krahmer@suse.de>.
bnc#660481
CVE-2010-4341
diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c
index 7bfd0f2..f4fe4f7 100644
--- a/src/responder/pam/pamsrv_cmd.c
+++ b/src/responder/pam/pamsrv_cmd.c
@@ -33,18 +33,15 @@
static void pam_reply(struct pam_auth_req *preq);
-static int extract_authtok(uint32_t *type, uint32_t *size, uint8_t **tok, uint8_t *body, size_t blen, size_t *c) {
- uint32_t data_size;
+static int extract_authtok(uint32_t *type, uint32_t *size, uint8_t **tok,
+ size_t data_size, uint8_t *body, size_t blen,
+ size_t *c) {
- if (blen-(*c) < 2*sizeof(uint32_t)) return EINVAL;
-
- memcpy(&data_size, &body[*c], sizeof(uint32_t));
- *c += sizeof(uint32_t);
- if (data_size < sizeof(uint32_t) || (*c)+(data_size) > blen) return EINVAL;
+ if (data_size < sizeof(uint32_t) || *c+data_size > blen ||
+ SIZE_T_OVERFLOW(*c, data_size)) return EINVAL;
*size = data_size - sizeof(uint32_t);
- memcpy(type, &body[*c], sizeof(uint32_t));
- *c += sizeof(uint32_t);
+ SAFEALIGN_COPY_UINT32_CHECK(type, &body[*c], blen, c);
*tok = body+(*c);
@@ -53,15 +50,11 @@ static int extract_authtok(uint32_t *type, uint32_t *size, uint8_t **tok, uint8_
return EOK;
}
-static int extract_string(char **var, uint8_t *body, size_t blen, size_t *c) {
- uint32_t size;
+static int extract_string(char **var, size_t size, uint8_t *body, size_t blen,
+ size_t *c) {
uint8_t *str;
- if (blen-(*c) < sizeof(uint32_t)+1) return EINVAL;
-
- memcpy(&size, &body[*c], sizeof(uint32_t));
- *c += sizeof(uint32_t);
- if (*c+size > blen) return EINVAL;
+ if (*c+size > blen || SIZE_T_OVERFLOW(*c, size)) return EINVAL;
str = body+(*c);
@@ -74,16 +67,13 @@ static int extract_string(char **var, uint8_t *body, size_t blen, size_t *c) {
return EOK;
}
-static int extract_uint32_t(uint32_t *var, uint8_t *body, size_t blen, size_t *c) {
- uint32_t size;
-
- if (blen-(*c) < 2*sizeof(uint32_t)) return EINVAL;
+static int extract_uint32_t(uint32_t *var, size_t size, uint8_t *body,
+ size_t blen, size_t *c) {
- memcpy(&size, &body[*c], sizeof(uint32_t));
- *c += sizeof(uint32_t);
+ if (size != sizeof(uint32_t) || *c+size > blen || SIZE_T_OVERFLOW(*c, size))
+ return EINVAL;
- memcpy(var, &body[*c], sizeof(uint32_t));
- *c += sizeof(uint32_t);
+ SAFEALIGN_COPY_UINT32_CHECK(var, &body[*c], blen, c);
return EOK;
}
@@ -108,59 +98,66 @@ static int pam_parse_in_data_v2(struct sss_names_ctx *snctx,
c = sizeof(uint32_t);
do {
- memcpy(&type, &body[c], sizeof(uint32_t));
- c += sizeof(uint32_t);
- if (c > blen) return EINVAL;
-
- switch(type) {
- case SSS_PAM_ITEM_USER:
- ret = extract_string(&pam_user, body, blen, &c);
- if (ret != EOK) return ret;
-
- ret = sss_parse_name(pd, snctx, pam_user,
- &pd->domain, &pd->user);
- if (ret != EOK) return ret;
- break;
- case SSS_PAM_ITEM_SERVICE:
- ret = extract_string(&pd->service, body, blen, &c);
- if (ret != EOK) return ret;
- break;
- case SSS_PAM_ITEM_TTY:
- ret = extract_string(&pd->tty, body, blen, &c);
- if (ret != EOK) return ret;
- break;
- case SSS_PAM_ITEM_RUSER:
- ret = extract_string(&pd->ruser, body, blen, &c);
- if (ret != EOK) return ret;
- break;
- case SSS_PAM_ITEM_RHOST:
- ret = extract_string(&pd->rhost, body, blen, &c);
- if (ret != EOK) return ret;
- break;
- case SSS_PAM_ITEM_CLI_PID:
- ret = extract_uint32_t(&pd->cli_pid,
- body, blen, &c);
- if (ret != EOK) return ret;
- break;
- case SSS_PAM_ITEM_AUTHTOK:
- ret = extract_authtok(&pd->authtok_type, &pd->authtok_size,
- &pd->authtok, body, blen, &c);
- if (ret != EOK) return ret;
- break;
- case SSS_PAM_ITEM_NEWAUTHTOK:
- ret = extract_authtok(&pd->newauthtok_type,
- &pd->newauthtok_size,
- &pd->newauthtok, body, blen, &c);
- if (ret != EOK) return ret;
- break;
- case SSS_END_OF_PAM_REQUEST:
- if (c != blen) return EINVAL;
- break;
- default:
- DEBUG(1,("Ignoring unknown data type [%d].\n", type));
- size = ((uint32_t *)&body[c])[0];
- c += size+sizeof(uint32_t);
+ SAFEALIGN_COPY_UINT32_CHECK(&type, &body[c], blen, &c);
+
+ if (type == SSS_END_OF_PAM_REQUEST) {
+ if (c != blen) return EINVAL;
+ } else {
+ SAFEALIGN_COPY_UINT32_CHECK(&size, &body[c], blen, &c);
+ /* the uint32_t end maker SSS_END_OF_PAM_REQUEST does not count to
+ * the remaining buffer */
+ if (size > (blen - c - sizeof(uint32_t))) {
+ DEBUG(1, ("Invalid data size.\n"));
+ return EINVAL;
+ }
+
+ switch(type) {
+ case SSS_PAM_ITEM_USER:
+ ret = extract_string(&pam_user, size, body, blen, &c);
+ if (ret != EOK) return ret;
+
+ ret = sss_parse_name(pd, snctx, pam_user,
+ &pd->domain, &pd->user);
+ if (ret != EOK) return ret;
+ break;
+ case SSS_PAM_ITEM_SERVICE:
+ ret = extract_string(&pd->service, size, body, blen, &c);
+ if (ret != EOK) return ret;
+ break;
+ case SSS_PAM_ITEM_TTY:
+ ret = extract_string(&pd->tty, size, body, blen, &c);
+ if (ret != EOK) return ret;
+ break;
+ case SSS_PAM_ITEM_RUSER:
+ ret = extract_string(&pd->ruser, size, body, blen, &c);
+ if (ret != EOK) return ret;
+ break;
+ case SSS_PAM_ITEM_RHOST:
+ ret = extract_string(&pd->rhost, size, body, blen, &c);
+ if (ret != EOK) return ret;
+ break;
+ case SSS_PAM_ITEM_CLI_PID:
+ ret = extract_uint32_t(&pd->cli_pid, size,
+ body, blen, &c);
+ if (ret != EOK) return ret;
+ break;
+ case SSS_PAM_ITEM_AUTHTOK:
+ ret = extract_authtok(&pd->authtok_type, &pd->authtok_size,
+ &pd->authtok, size, body, blen, &c);
+ if (ret != EOK) return ret;
+ break;
+ case SSS_PAM_ITEM_NEWAUTHTOK:
+ ret = extract_authtok(&pd->newauthtok_type,
+ &pd->newauthtok_size,
+ &pd->newauthtok, size, body, blen, &c);
+ if (ret != EOK) return ret;
+ break;
+ default:
+ DEBUG(1,("Ignoring unknown data type [%d].\n", type));
+ c += size;
+ }
}
+
} while(c < blen);
if (pd->user == NULL || *pd->user == '\0') return EINVAL;
@@ -231,6 +228,7 @@ static int pam_parse_in_data(struct sss_names_ctx *snctx,
start += sizeof(uint32_t);
pd->authtok_size = (int) body[start];
+ if (pd->authtok_size >= blen) return EINVAL;
start += sizeof(uint32_t);
end = start + pd->authtok_size;
@@ -250,6 +248,7 @@ static int pam_parse_in_data(struct sss_names_ctx *snctx,
start += sizeof(uint32_t);
pd->newauthtok_size = (int) body[start];
+ if (pd->newauthtok_size >= blen) return EINVAL;
start += sizeof(uint32_t);
end = start + pd->newauthtok_size;
diff --git a/src/tests/util-tests.c b/src/tests/util-tests.c
index bfc48bb..328ae23 100644
--- a/src/tests/util-tests.c
+++ b/src/tests/util-tests.c
@@ -175,6 +175,20 @@ START_TEST(test_diff_string_lists)
}
END_TEST
+START_TEST(test_size_t_overflow)
+{
+ fail_unless(!SIZE_T_OVERFLOW(1, 1), "unexpected overflow");
+ fail_unless(!SIZE_T_OVERFLOW(SIZE_T_MAX, 0), "unexpected overflow");
+ fail_unless(!SIZE_T_OVERFLOW(SIZE_T_MAX-10, 10), "unexpected overflow");
+ fail_unless(SIZE_T_OVERFLOW(SIZE_T_MAX, 1), "overflow not detected");
+ fail_unless(SIZE_T_OVERFLOW(SIZE_T_MAX, SIZE_T_MAX),
+ "overflow not detected");
+ fail_unless(SIZE_T_OVERFLOW(SIZE_T_MAX, ULLONG_MAX),
+ "overflow not detected");
+ fail_unless(SIZE_T_OVERFLOW(SIZE_T_MAX, -10), "overflow not detected");
+}
+END_TEST
+
Suite *util_suite(void)
{
Suite *s = suite_create("util");
@@ -182,6 +196,7 @@ Suite *util_suite(void)
TCase *tc_util = tcase_create("util");
tcase_add_test (tc_util, test_diff_string_lists);
+ tcase_add_test (tc_util, test_size_t_overflow);
tcase_set_timeout(tc_util, 60);
suite_add_tcase (s, tc_util);
diff --git a/src/util/util.h b/src/util/util.h
index e93f6f8..7c35550 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -169,6 +169,11 @@ errno_t set_debug_file_from_fd(const int fd);
#define OUT_OF_ID_RANGE(id, min, max) \
(id == 0 || (min && (id < min)) || (max && (id > max)))
+#define SIZE_T_MAX ((size_t) -1)
+
+#define SIZE_T_OVERFLOW(current, add) \
+ (((size_t)(add)) > (SIZE_T_MAX - ((size_t)(current))))
+
static inline void
safealign_memcpy(void *dest, const void *src, size_t n, size_t *counter)
{
--
1.7.3.2

View File

@ -1,32 +0,0 @@
From bfac6031ab075834183c9f18b28363d11b99e44a Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Tue, 7 Dec 2010 17:01:04 +0100
Subject: Add overflow check to SAFEALIGN_COPY_*_CHECK macros
CVE-2010-4341
bnc#660481
diff --git a/src/util/util.h b/src/util/util.h
index 7c35550..50c5fe2 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -207,12 +207,14 @@ safealign_memcpy(void *dest, const void *src, size_t n, size_t *counter)
SAFEALIGN_SET_VALUE(dest, value, uint16_t, pctr)
#define SAFEALIGN_COPY_UINT32_CHECK(dest, src, len, pctr) do { \
- if ((*(pctr) + sizeof(uint32_t)) > (len)) return EINVAL; \
+ if ((*(pctr) + sizeof(uint32_t)) > (len) || \
+ SIZE_T_OVERFLOW(*(pctr), sizeof(uint32_t))) return EINVAL; \
safealign_memcpy(dest, src, sizeof(uint32_t), pctr); \
} while(0)
#define SAFEALIGN_COPY_INT32_CHECK(dest, src, len, pctr) do { \
- if ((*(pctr) + sizeof(int32_t)) > (len)) return EINVAL; \
+ if ((*(pctr) + sizeof(int32_t)) > (len) || \
+ SIZE_T_OVERFLOW(*(pctr), sizeof(int32_t))) return EINVAL; \
safealign_memcpy(dest, src, sizeof(int32_t), pctr); \
} while(0)
--
1.7.3.2

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:9819769fdbb3003c4c2c3cb2d55cb5ec1de9d1196ee0cbe7e44be4485b6e1fa2
size 796262

3
sssd-1.5.1.tar.bz2 Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:3c39b6749a19a61da74aa4801f332429a27c0604c49d6541e4bd512fad5a9a7f
size 866097

View File

@ -1,3 +1,21 @@
-------------------------------------------------------------------
Tue Mar 8 13:22:58 UTC 2011 - rhafer@suse.de
- Updated to 1.5.1
* Vast performance improvements when enumerate = true
* All PAM actions will now perform a forced initgroups lookup
instead of just a user information lookup This guarantees that
all group information is available to other providers, such as
the simple provider.
* For backwards-compatibility, DNS lookups will also fall back to
trying the SSSD domain name as a DNS discovery domain.
* Support for more password expiration policies in LDAP
- 389 Directory Server
- FreeIPA
- ActiveDirectory
* Support for ldap_tls_{cert,key,cipher_suite} config options
* Assorted bugfixes
-------------------------------------------------------------------
Wed Jan 19 09:32:35 UTC 2011 - rhafer@suse.de

View File

@ -18,7 +18,7 @@
Name: sssd
Version: 1.4.1
Version: 1.5.1
Release: 5
Group: System/Daemons
Summary: System Security Services Daemon
@ -26,8 +26,6 @@ License: GPLv3+ and LGPLv3+
Url: https://fedorahosted.org/sssd/
Source0: %{name}-%{version}.tar.bz2
Source1: baselibs.conf
Patch0: 0001-Validate-user-supplied-size-of-data-items.patch
Patch1: 0002-Add-overflow-check-to-SAFEALIGN_COPY_-_CHECK-macros.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-build
%define servicename sssd
@ -105,8 +103,6 @@ Security Services Daemon (sssd).
%prep
%setup -q
%patch0 -p1
%patch1 -p1
%build
autoreconf
@ -153,7 +149,7 @@ rm -f \
$RPM_BUILD_ROOT/%{_libdir}/sssd/libsss_ipa.la \
$RPM_BUILD_ROOT/%{_libdir}/sssd/libsss_simple.la \
$RPM_BUILD_ROOT/%{_libdir}/krb5/plugins/libkrb5/sssd_krb5_locator_plugin.la
%find_lang sssd
%find_lang %{name} --all-name
%clean
rm -rf $RPM_BUILD_ROOT
@ -211,7 +207,13 @@ rm -rf $RPM_BUILD_ROOT
%files tools
%defattr(-,root,root,-)
%dir %{_mandir}/cs
%dir %{_mandir}/cs/man8
%dir %{_mandir}/uk
%dir %{_mandir}/uk/man8
%{_mandir}/man8/*
%{_mandir}/cs/man8/*
%{_mandir}/uk/man8/*
%{_sbindir}/sss_useradd
%{_sbindir}/sss_userdel
%{_sbindir}/sss_usermod