diff --git a/sys/netproto/smb/smb_usr.c b/sys/netproto/smb/smb_usr.c --- a/sys/netproto/smb/smb_usr.c +++ b/sys/netproto/smb/smb_usr.c @@ -74,12 +74,29 @@ spec->sap = smb_memdupin(dp->ioc_server, dp->ioc_svlen); if (spec->sap == NULL) return ENOMEM; + /* + * dup_sockaddr() (uipc_socket2.c) trusts sa->sa_len unconditionally + * and bcopy()s that many bytes. smb_memdupin() only allocated + * ioc_svlen bytes, so sa_len > ioc_svlen drives an OOB heap read in + * dup_sockaddr when smb_vc_create() copies the address. Reject any + * sa_len that does not fit in the buffer we actually allocated. + * (DF-0600) + */ + if (spec->sap->sa_len < 2 || spec->sap->sa_len > dp->ioc_svlen) { + smb_usr_vcspec_free(spec); + return EINVAL; + } if (dp->ioc_local) { spec->lap = smb_memdupin(dp->ioc_local, dp->ioc_lolen); if (spec->lap == NULL) { smb_usr_vcspec_free(spec); return ENOMEM; } + if (spec->lap->sa_len < 2 || + spec->lap->sa_len > dp->ioc_lolen) { + smb_usr_vcspec_free(spec); + return EINVAL; + } } spec->srvname = dp->ioc_srvname; spec->pass = dp->ioc_password;