Short read from krb5_rc_io_read
JC Ferguson
jc at f5.com
Fri Mar 14 13:16:33 EDT 2008
line 356 also references "maxlen".
Where is that initialized?
If you set "len2" to zero when you declare
it, does the warning go away?
> -----Original Message-----
> From: krbdev-bounces at mit.edu [mailto:krbdev-bounces at mit.edu]
> On Behalf Of Mike Patnode
> Sent: Friday, March 14, 2008 12:42
> To: Kerberos developers list
> Subject: Short read from krb5_rc_io_read
>
>
> I'm currently running valgrind on code build with 1.4.3, but
> I don't see
> any difference here in the 1.6 source base. I'm getting
> the following
> error:
>
>
> ==7938== Conditional jump or move depends on uninitialised value(s)
> ==7938== at 0x72A8F7: krb5_rc_io_fetch (rc_dfl.c:356)
> ==7938== by 0x72ABE5: krb5_rc_dfl_recover_locked (rc_dfl.c:460)
> ==7938== by 0x72AF19: krb5_rc_dfl_recover_or_init (rc_dfl.c:522)
> ==7938== by 0x6F68B4: krb5_rc_recover_or_initialize (rcfns.c:44)
> ==7938== by 0x6F1671: krb5_get_server_rcache (srv_rcache.c:115)
> ==7938== by 0x6EC4A6: krb5_rd_req (rd_req.c:89)
> ... (my code which looks something like this:
>
> rc = krb5_auth_con_init(m_kcontext, &serverAuthContext);
>
> ...
>
> rc = krb5_rd_req(m_kcontext,
> &serverAuthContext,
> &ticket,
> NULL /* don't check SPN */,
> &ktab,
> NULL /* no options */,
> ret_ticket);
>
> Where we're verifying a user ticket by requesting a service ticket for
> the local host to prevent the classic rogue KDC response attack. In
> anycase, it appears krb5_rc_io_read doesn't protect against a short
> read:
>
> In krb5_rc_io_fetch, we have:
>
> int len2;
> unsigned int len;
> krb5_error_code retval;
>
> rep->client = rep->server = 0;
>
> retval = krb5_rc_io_read(context, &t->d, (krb5_pointer) &len2,
> sizeof(len2));
> if (retval)
> return retval;
>
> if ((len2 <= 0) || (len2 >= maxlen)) // line 356
> return KRB5_RC_IO_EOF;
>
> And krb5_rc_io_read is:
>
> krb5_error_code
> krb5_rc_io_read(krb5_context context, krb5_rc_iostuff *d,
> krb5_pointer buf,
> unsigned int num)
> {
> int count;
> if ((count = read(d->fd, (char *) buf, num)) == -1)
> switch(errno)
> {
> case EIO: return KRB5_RC_IO_IO;
> case EBADF:
> default:
> krb5_set_error_message(context, KRB5_RC_IO_UNKNOWN,
> "Can't read from replay cache: %s",
> strerror(errno));
> return KRB5_RC_IO_UNKNOWN;
> }
> if (count == 0)
> return KRB5_RC_IO_EOF;
> return 0;
> }
>
> So there is no guarantee that we're are going to read 4 bytes. I
> suspect in this case we read 1, 2 or 3, and valgrind
> complained about some of the bytes in len2 not being
> initialized (or fstat() didn't initialize st_size?).
>
> Now I strongly suspect this was a side effect of running
> within valgrind
> due to the performance issues introduced. It only happened once
> during a 24 hour stress test of this code path, but I confess
> to not having a deep understanding of what's happening at
> this point in time.
> We could obviously pacify valgrind by initializing len2 to 0,
> but I don't think that's necessarily the right thing to do...
> Is it possible
> the length value would be less than 4 bytes? Any thoughts on whether
> this is a real-world problem?
>
> mp
>
>
> _______________________________________________
> krbdev mailing list krbdev at mit.edu
> https://mailman.mit.edu/mailman/listinfo/krbdev
>
More information about the krbdev
mailing list