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

Uploading sssd to tpu for security issue



Hi,

sssd/1.2.1-4.1 was NMU'ed by Moritz to sid to fix a security issue, but 
unfortunately in unstable it picked up newer dependencies so it can't migrate 
to testing. I've prepared an upload for tpu with exactly the same changes 
(modulo changelog) but built in a squeeze environment, and would like to get 
your permission to upload it.

Debdiff attached and built packages at http://loeki.tv/~thijs/sssd/

Cheers,
Thijs
diff -u sssd-1.2.1/debian/changelog sssd-1.2.1/debian/changelog
--- sssd-1.2.1/debian/changelog
+++ sssd-1.2.1/debian/changelog
@@ -1,3 +1,10 @@
+sssd (1.2.1-4+squeeze1) testing; urgency=medium
+
+  * Non-maintainer upload by the Security Team
+  * Fix CVE-2010-4341 (Closes: #610032)
+
+ -- Thijs Kinkhorst <thijs@debian.org>  Mon, 31 Jan 2011 20:48:45 +0100
+
 sssd (1.2.1-4) unstable; urgency=low
 
   * Add patch from Stephen Gallagher to ensure LDAP authentication
diff -u sssd-1.2.1/debian/patches/00list sssd-1.2.1/debian/patches/00list
--- sssd-1.2.1/debian/patches/00list
+++ sssd-1.2.1/debian/patches/00list
@@ -2,0 +3 @@
+CVE-2010-4341.dpatch
only in patch2:
unchanged:
--- sssd-1.2.1.orig/debian/patches/CVE-2010-4341.dpatch
+++ sssd-1.2.1/debian/patches/CVE-2010-4341.dpatch
@@ -0,0 +1,261 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+
+@DPATCH@
+From 337fcbc269eb72cf0e093e308df796413bc918d4 Mon Sep 17 00:00:00 2001
+From: Sumit Bose <sbose@redhat.com>
+Date: Mon, 6 Dec 2010 21:18:50 +0100
+Subject: [PATCH] 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>.
+
+Add overflow check to SAFEALIGN_COPY_*_CHECK macros
+
+[Addition to test suite dropped for backport]
+
+---
+ src/responder/pam/pamsrv_cmd.c |  147 ++++++++++++++++++++--------------------
+ src/tests/util-tests.c         |   15 ++++
+ src/util/util.h                |   11 +++-
+ 3 files changed, 97 insertions(+), 76 deletions(-)
+
+diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c
+index fca6cd0032c578779dc9eb744a4d8ac8003c8f9b..e8fb19cd1d7da1fef88972b454a1d949b798854c 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;
++static int extract_uint32_t(uint32_t *var, size_t size, uint8_t *body,
++                            size_t blen, size_t *c) {
+ 
+-    if (blen-(*c) < 2*sizeof(uint32_t)) return EINVAL;
++    if (size != sizeof(uint32_t) || *c+size > blen || SIZE_T_OVERFLOW(*c, size))
++        return EINVAL;
+ 
+-    memcpy(&size, &body[*c], sizeof(uint32_t));
+-    *c += sizeof(uint32_t);
+-
+-    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;
++        SAFEALIGN_COPY_UINT32_CHECK(&type, &body[c], blen, &c);
+ 
+-        switch(type) {
+-            case SSS_PAM_ITEM_USER:
+-                ret = extract_string(&pam_user, body, blen, &c);
+-                if (ret != EOK) return ret;
++        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;
++            }
+ 
+-                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);
++            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/util/util.h b/src/util/util.h
+index 7fcca3a6db046bc69ae901282700d8966f1c208e..2b9faa095657d8f650afd335d195bf3151fd34da 100644
+--- a/src/util/util.h
++++ b/src/util/util.h
+@@ -168,6 +168,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)
+ {
+@@ -195,12 +200,14 @@ safealign_memcpy(void *dest, const void *src, size_t n, size_t *counter)
+     SAFEALIGN_SET_VALUE(dest, value, int32_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.3
+

Attachment: signature.asc
Description: This is a digitally signed message part.


Reply to: