Bug 1380 - incorrect check for strlen(fwd->connect_host) in parse_forward()
Summary: incorrect check for strlen(fwd->connect_host) in parse_forward()
Status: CLOSED FIXED
Alias: None
Product: Portable OpenSSH
Classification: Unclassified
Component: ssh (show other bugs)
Version: 4.7p1
Hardware: All All
: P3 normal
Assignee: Assigned to nobody
URL:
Keywords:
Depends on:
Blocks: V_5_2
  Show dependency treegraph
 
Reported: 2007-10-23 04:25 AEST by Jan Pechanec
Modified: 2009-02-23 13:35 AEDT (History)
4 users (show)

See Also:


Attachments
fix for the bug (797 bytes, patch)
2007-10-23 04:27 AEST, Jan Pechanec
no flags Details | Diff
revised patch (5.56 KB, patch)
2008-07-04 14:14 AEST, Damien Miller
no flags Details | Diff
revised revised patch (6.06 KB, patch)
2008-07-04 16:48 AEST, Damien Miller
no flags Details | Diff
make c->path dynamic and nuke SSH_CHANNEL_PATH_LEN (5.43 KB, patch)
2009-01-14 12:58 AEDT, Damien Miller
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Jan Pechanec 2007-10-23 04:25:36 AEST
there are 2 issues for hostname len check in parse_forward()

(a) the len is checked against NI_MAXHOST while it should be checked against (SSH_CHANNEL_PATH_LEN - 1).

(b) the check should be also performed against listen_host when in remote fwd mode; otherwise hostname of any length is sent over

The check against connect_host is already in channel_setup_fwd_listener(). I think that correct way is to remove the check from parse_forward() completely and put a new check against listen_host to channel_request_remote_forwarding().

patch attached.
Comment 1 Jan Pechanec 2007-10-23 04:27:25 AEST
Created attachment 1367 [details]
fix for the bug
Comment 2 Damien Miller 2007-11-03 11:12:08 AEDT
I think it is best to perform the checks in parse_forward too, as this is called before the connection is established. It is annoying to have to authenticate before you find out the errors in your configuration or commandline.
Comment 3 Jan Pechanec 2007-11-04 05:13:12 AEDT
a good point. It might be worth to do more changes then.

parse_forward() doesn't know whether it processes a local or remote spec so it doesn't know which one of the two address strings is going to be sent over. However, it doesn't matter because maximum domain name length is 255 octets (RFC 2181) and the macro SSH_CHANNEL_PATH_LEN is already defined as 256. Maybe, channels.h could define:

#define MAX_DOMAIN_NAME_LEN     255
#define SSH_CHANNEL_PATH_LEN    MAX_DOMAIN_NAME_LEN

and then use MAX_DOMAIN_NAME_LEN in parse_forward() on both strings because it's not about setting a channel path there yet but use SSH_CHANNEL_PATH_LEN in both forward functions where the string is actually sent over; in theory the channel path length could be shorter than MAX_DOMAIN_NAME_LEN.

and use +1 for '\0' rather than -1 were it defined as 256.
Comment 4 Darren Tucker 2008-06-14 10:29:37 AEST
Target 5.1 release.
Comment 5 Damien Miller 2008-07-04 14:14:06 AEST
Created attachment 1539 [details]
revised patch

I think this would be better. btw, there was a bug in your change to channels.c:channel_request_remote_forwarding() - it returned 0 (success) instead of -1 (failure) when a too-long listen_host was supplied.
Comment 6 Damien Miller 2008-07-04 16:48:52 AEST
Created attachment 1540 [details]
revised revised patch

my last patch has a bug: listen_host may be NULL in channel_request_remote_forwarding()
Comment 7 Jan Pechanec 2008-07-04 20:19:10 AEST
I'm wondering, after reading the forwarding section of 4254 again, is it worth to have SSH_CHANNEL_PATH_LEN at all? 4254 talks about domain name only, not mentioning any limitation, which implies that one should rely on the existing spec, RFC 2181. Unless there is any need to limit the domain name length further, which I doubt, there is no need for 2 macros.

that way, SSH_MAX_DOMAIN_LEN may be the only macro defined and used (in the last revision of the patch, both macros are used which might be confusing for the reader of the code).

I would also vote for defining it to 255, use str[SSH_MAX_DOMAIN_LEN + 1] for definition, and "strlen(xxx) > SSH_MAX_DOMAIN_LEN)" in comparisons. It seems more logical and mainly, more readable. However, that's already nit picking.
Comment 8 Damien Miller 2008-07-04 22:06:54 AEST
actually, c->path can be used for real pathnames too (e.g. auth sockets) the constant name is wrong too. I think I'll bump this to openssh-5.2, so we can just make it properly dynamic.
Comment 9 Damien Miller 2009-01-13 17:28:14 AEDT
Could you refresh my memory as to why NI_MAXHOST is inappropriate?
Comment 10 Jan Pechanec 2009-01-14 04:26:34 AEDT
(In reply to comment #9)
> Could you refresh my memory as to why NI_MAXHOST is inappropriate?

trying to remember... I'd say it may be the other way around. The point which I hasn't explained was that on one side the hostname length is checked against NI_MAXHOST in parse_forward() while on the other side it's checked against SSH_CHANNEL_PATH_LEN in channel.c's function channel_setup_fwd_listener().

NI_MAXHOST is usually defined as 1025 (RFC 2553, but obsoleted by 3493 that doesn't even define it). SSH_CHANNEL_PATH_LEN is defined as 255 and used just once.

So, I suggest the same value should be used on both sides.
Comment 11 Damien Miller 2009-01-14 12:58:18 AEDT
Created attachment 1591 [details]
make c->path dynamic and nuke SSH_CHANNEL_PATH_LEN

Thanks - that refreshed my memory. This is what I had planned on doing: get rid of SSH_CHANNEL_PATH_LEN entirely by making c->path a dynamic string.
Comment 12 Tim Rice 2009-01-14 16:52:43 AEDT
(In reply to comment #11)
> Created an attachment (id=1591) [details]
> make c->path dynamic and nuke SSH_CHANNEL_PATH_LEN
> 
> Thanks - that refreshed my memory. This is what I had planned on doing:
> get rid of SSH_CHANNEL_PATH_LEN entirely by making c->path a dynamic
> string.

A quick look at the code turned up
+	u_char *p, dest_addr[255+1], ntop[INET6_ADDRSTRLEN];
We'll need to account for machines that don't have INET6_ADDRSTRLEN

Maybe just adding
#ifndef INET6_ADDRSTRLEN                /* for non IPv6 machines */
#define INET6_ADDRSTRLEN 46
#endif
like we do in sshconnect.c
Comment 13 Damien Miller 2009-01-22 20:50:55 AEDT
patch applied - this will be in openssh-5.2
Comment 14 Damien Miller 2009-02-23 13:35:35 AEDT
Close bugs fixed/reviewed for openssh-5.2 release