Bug 579836 - backport fix for upstream #1809658 from 1.40.4 - libcom_err bug
Summary: backport fix for upstream #1809658 from 1.40.4 - libcom_err bug
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Red Hat Enterprise Linux 5
Classification: Red Hat
Component: e2fsprogs
Version: 5.5
Hardware: x86_64
OS: Linux
low
low
Target Milestone: rc
: ---
Assignee: Eric Sandeen
QA Contact: BaseOS QE - Apps
URL: http://sourceforge.net/tracker/?func=...
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2010-04-06 17:17 UTC by Nalin Dahyabhai
Modified: 2011-07-21 12:38 UTC (History)
2 users (show)

Fixed In Version: e2fsprogs-1.39-28.el5
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2011-07-21 09:07:43 UTC
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)


Links
System ID Private Priority Status Summary Last Updated
Red Hat Product Errata RHBA-2011:1080 0 normal SHIPPED_LIVE e2fsprogs bug fix and enhancement update 2011-07-21 09:04:54 UTC

Description Nalin Dahyabhai 2010-04-06 17:17:58 UTC
Description of problem:
When an unsigned int is passed to the error_message() function, it is sign-extended so that the error_message() function no longer matches the right table.  This happens frequently with error codes returned by gssapi libraries, which are returned in unsigned variables.

Version-Release number of selected component (if applicable):
e2fsprogs-libs-1.39-23.el5

How reproducible:
Always

Steps to Reproduce:
cat > com_err.c << EOF
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <krb5.h>
#include <gssapi/gssapi.h>
int main(int argc, char **argv)
{
    int i;
    unsigned int u;
    krb5_context ctx;
    ctx = NULL;
    krb5_init_context(&ctx);
    if (argc > 1) {
        for (i = 1; i < argc; i++) {
            u = atol(argv[i]);
            printf("Error message (%08x): \"%s\".\n", u, error_message(u));
        }
    } else {
        u = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
        printf("Error message: \"%s\".\n", error_message(u));
    }
    return 0;
}
EOF
cc -Wall -o com_err `krb5-config --cflags` com_err.c `krb5-config --libs`
./com_err

Actual results:
Error message: "Unknown code krb5 7".

Expected results:
Error message: "Server not found in Kerberos database".

Comment 1 Eric Sandeen 2010-04-06 17:45:49 UTC
Straightforward upstream patch is:

http://git.kernel.org/?p=fs/ext2/e2fsprogs.git;a=commitdiff;h=6b6c27fb8a45f264194d8dd637643d8b4898271a

libcom_err: Fix sign-extension problem on 64-bit systems in error_message()

On 64-bit systems (or anything with sizeof(long) > sizeof(int)), we
sometimes get error codes passed to error_message which have been cast
from an (int) to an (unsigned int). This almost always happens if
you're using libgssapi_krb5, which returns an error code which is less
than 0 but is returned in an (unsigned int).

For example, -1765328377L gets cast to 2529638919, which is
0x96c73a07, not 0xffffffff96c73a07, so error_message() fails to find a
matching error table.

When error_message() then calls the error_table_name() function to get a
name to use in the "unknown code" message, it gets a correct value back.

This happens because error_table_name() drops most of the higher bits of
the parameter it's passed before doing anything else with it (& 077777777f,
or & 0xffffff). If we did the same thing in error_message(), we wouldn't
have a problem there, either.

Problem reported and fixed by: Nalin Dahyabhai

Addresses-Sourceforge-Bug: #1809658

Signed-off-by: "Theodore Ts'o" <tytso>
---

diff --git a/lib/et/error_message.c b/lib/et/error_message.c
index 4e84e35..708dd2f 100644
--- a/lib/et/error_message.c
+++ b/lib/et/error_message.c
@@ -69,7 +69,7 @@ const char * error_message (errcode_t code)
 #endif
     }
     for (et = _et_list; et; et = et->next) {
-	if (et->table->base == table_num) {
+	if ((et->table->base & 0xffffffL) == (table_num & 0xffffffL)) {
 	    /* This is the right table */
 	    if (et->table->n_msgs <= offset)
 		goto oops;
@@ -77,7 +77,7 @@ const char * error_message (errcode_t code)
 	}
     }
     for (et = _et_dynamic_list; et; et = et->next) {
-	if (et->table->base == table_num) {
+	if ((et->table->base & 0xffffffL) == (table_num & 0xffffffL)) {
 	    /* This is the right table */
 	    if (et->table->n_msgs <= offset)
 		goto oops;

Comment 4 Eric Sandeen 2011-02-01 22:09:30 UTC
Built & tagged in e2fsprogs-1.39-28.el5

Comment 7 errata-xmlrpc 2011-07-21 09:07:43 UTC
An advisory has been issued which should help the problem
described in this bug report. This report is therefore being
closed with a resolution of ERRATA. For more information
on therefore solution and/or where to find the updated files,
please follow the link below. You may reopen this bug report
if the solution does not work for you.

http://rhn.redhat.com/errata/RHBA-2011-1080.html

Comment 8 errata-xmlrpc 2011-07-21 12:38:24 UTC
An advisory has been issued which should help the problem
described in this bug report. This report is therefore being
closed with a resolution of ERRATA. For more information
on therefore solution and/or where to find the updated files,
please follow the link below. You may reopen this bug report
if the solution does not work for you.

http://rhn.redhat.com/errata/RHBA-2011-1080.html


Note You need to log in before you can comment on or make changes to this bug.