[2844] in Kerberos-V5-bugs
krb5-appl/516: 'rsh' fails in kcmd() under Red Hat Linux 4.2
daemon@ATHENA.MIT.EDU (kcox@senteinc.com)
Thu Dec 18 15:32:23 1997
Resent-From: gnats@rt-11.MIT.EDU (GNATS Management)
Resent-To: krb5-unassigned@RT-11.MIT.EDU
Resent-Reply-To: krb5-bugs@MIT.EDU, kcox@senteinc.com
Date: Thu, 18 Dec 1997 15:30:55 -0500
From: kcox@senteinc.com
Reply-To: kcox@senteinc.com
To: krb5-bugs@MIT.EDU
>Number: 516
>Category: krb5-appl
>Synopsis: 'rsh' fails in kcmd() under Red Hat Linux 4.2
>Confidential: no
>Severity: critical
>Priority: medium
>Responsible: krb5-unassigned
>State: open
>Class: sw-bug
>Submitter-Id: unknown
>Arrival-Date: Thu Dec 18 15:32:01 EST 1997
>Last-Modified:
>Originator: Ken Cox
>Organization:
Sente, Inc.
>Release: krb5-1.0.4
>Environment:
Linux PC running Red Hat Linux version 4.2.
System: Linux special-sauce 2.0.30 #8 Wed Dec 17 22:12:52 EST 1997 i686 unknown
Architecture: i686
>Description:
Trying 'rsh' dumps core immediately.
I tracked it down to the kcmd() function, line 183:
memcpy((caddr_t)&sin.sin_addr,hp->h_addr, sizeof(sin.sin_addr));
This was happening because hp->h_addr was NULL. It got NULL as a
side-effect of calling gethostbyname() again (which happens inside
krb5_sname_to_principal). Linux seems to reuse static data in calls to
gethostbyname(). A careful reading of the man page suggests that
Solaris does too.
The fix is to save relevant data before calling
krb5_sname_to_principal. Below please find my patch.
>How-To-Repeat:
>Fix:
Apply this patch:
diff -c appl/bsd/kcmd.c.dist appl/bsd/kcmd.c
*** appl/bsd/kcmd.c.dist Thu Dec 4 22:41:51 1997
--- appl/bsd/kcmd.c Thu Dec 18 15:00:43 1997
***************
*** 96,101 ****
--- 96,103 ----
struct hostent *hp;
int rc;
char *host_save;
+ int save_addrtype;
+ unsigned int save_addr;
krb5_error_code status;
krb5_error *err_ret;
krb5_ap_rep_enc_part *rep_ret;
***************
*** 131,136 ****
--- 133,140 ----
}
strcpy(host_save, hp->h_name);
+ save_addrtype = hp->h_addrtype;
+ save_addr = (int) (hp->h_addr);
/* If no service is given set to the default service */
if (!service) service = default_service;
***************
*** 179,186 ****
krb5_free_creds(bsd_context, get_cred);
return (-1);
}
! sin.sin_family = hp->h_addrtype;
! memcpy((caddr_t)&sin.sin_addr,hp->h_addr, sizeof(sin.sin_addr));
sin.sin_port = rport;
if (connect(s, (struct sockaddr *)&sin, sizeof (sin)) >= 0)
break;
--- 183,190 ----
krb5_free_creds(bsd_context, get_cred);
return (-1);
}
! sin.sin_family = save_addrtype;
! memcpy((caddr_t)&sin.sin_addr, (caddr_t)&save_addr, sizeof(sin.sin_addr));
sin.sin_port = rport;
if (connect(s, (struct sockaddr *)&sin, sizeof (sin)) >= 0)
break;
>Audit-Trail:
>Unformatted: