disabling FORTIFY_SOURCE

2010-10-23 Thread Kees Cook
Hi,

It seems to me that disabling FORTIFY_SOURCE is a mistake. It offers
a great many protections, and virtually every distribution has very
intentionally turned on this compiler flag by default. Given Wine's
size[1], I would argue the benefits[2] outweigh the hassle of rearranging
the structures and accessors to not trick the compiler into allocating
memory beyond the end of the structure for incoming strings.

It has found, at least in other projects, a lot of potential problems,
and better yet, has repeatedly turned exploitable vulnerabilities into
simple denial of services. I realize it's a bit of a pain to work with
given how you're building some of the structures, but I'd like to ask
that it not be globally disabled.

Thanks,

-Kees

[1] $ find . -type f -name '*.[ch]' | xargs wc -l | grep total
 2678911 total

[2] Some details at https://wiki.ubuntu.com/CompilerFlags#-D_FORTIFY_SOURCE=2
but at least the following...

  Compile time:
- static buffer length checks
- missed return values
- open() checks for missing mode when used with O_CREAT

  Run time:
- dynamic buffer length checks
- dynamic format string safety check
- dynamic format position safety checks

  Functions with buffer length (or other) checks:

asprintf confstr dprintf fgets fgetws fprintf fread fwprintf getcwd
getdomainname getgroups gethostname getlogin_r gets getwd longjmp
mbsnrtowcs mbsrtowcs mbstowcs memcpy memmove mempcpy memset pread64 pread
printf ptsname_r read readlinkat readlink realpath recv recvfrom snprintf
sprintf stpcpy stpncpy strcat strcpy strncat strncpy swprintf syslog
ttyname_r vasprintf vdprintf vfprintf vfwprintf vprintf vsnprintf vsprintf
vswprintf vsyslog vwprintf wcpcpy wcpncpy wcrtomb wcscat wcscpy wcsncat
wcsncpy wcsnrtombs wcsrtombs wcstombs wctomb wmemcpy wmemmove wmempcpy
wmemset wprintf

-- 
Kees Cook
Ubuntu Security Team




question about standalone tests

2005-05-24 Thread Kees Cook
Hi!  My crypt32 protectdata tests were just added to CVS (thanks!) but 
they were added without the #ifndef STANDALONE stuff that exists in the 
recommended example from the lzexpand test code.  The steps here:
http://www.winehq.com/site/docs/wine-devel/testing-windows
don't have a method for doing the build with the free-of-charge windows 
CLI compiler (which the STANDALONE stuff works fine with).

Is there some new way to build standalone tests, or should I send a 
patch for re-including the #ifndef STANDALONE stuff for the tests?

-- 
Kees Cook@outflux.net



Re: crypt32 [4/4]: (un)protectdata test suite

2005-05-20 Thread Kees Cook
On Fri, May 20, 2005 at 09:24:56PM +0200, Alexandre Julliard wrote:
 err:crypt:CryptProtectData CryptAcquireContextW failed

Hm.  This may be related to not have an initial crypt session for the 
user.  I think I built one (on accident?) while playing with various 
test scripts, so I suspect something is in the registry.  I will 
investigate.

-- 
Kees Cook@outflux.net



Re: [crypt32] CryptProtectData/CryptUnprotectData helper functions

2005-05-18 Thread Kees Cook
On Wed, May 18, 2005 at 07:31:03PM +0200, Alexandre Julliard wrote:
  +wine_dbg_printf(%s\n,report);
 
 You should use wine_dbg_sprintf here and return a string.

Okay.

  +static
  +void serialize_dword(DWORD value,BYTE ** ptr)
  +{
  +/*TRACE(called\n);*/
  +
  +*((DWORD*)*ptr)=value;
  +*ptr+=sizeof(DWORD);
 
 This (and other similar things later on) isn't safe for CPUs that
 don't allow unaligned accesses, you have to use memcpy instead.

Ah, whoops.  I will fix these.

  +pInfo-info0.pbData=strdup(crypt_magic_str);
 
 You don't want to use strdup, you should use HeapAlloc and friends
 (especially since you use HeapFree later on).

Is there a HeapAlloc-using version of strdup?  I see a while back 
someone implemented their own in their own code; is there a common batch 
of wine functions, or should I do the same thing?

http://www.winehq.org/hypermail/wine-patches/2004/08/0558.html

StrDup is defined for Windows in .NET and VB, but not for VC, it seems?

  +crypt_report_func_input(DATA_BLOB* pDataIn,
  +DATA_BLOB* pOptionalEntropy,
  +CRYPTPROTECT_PROMPTSTRUCT* pPromptStruct,
  +DWORD dwFlags)
  +{
  +wine_dbg_printf(\tpPromptStruct: 0x%x\n,(unsigned int)pPromptStruct);

  +static void
  +announce_bad_opaque_data()
  +{
  +wine_dbg_printf(CryptUnprotectData received the following pDataIn 
  DATA_BLOB that seems to\n);
  +wine_dbg_printf(have NOT been generated by Wine:\n);
  +}
 
 You should use the TRACE/FIXME macros here, not raw wine_dbg_printf.

FIXME is sane for the announce_bad_opaque_data, but I'd still like to
use something that doesn't prefix the hexdumps with the function name
for easier readability in the crypt_report_func_input, since there is
already a TRACE/FIXME call being made prior to it's call.  Is this okay?
 
-- 
Kees Cook@outflux.net



Re: [crypt32] CryptProtectData/CryptUnprotectData helper functions

2005-05-18 Thread Kees Cook
On Wed, May 18, 2005 at 08:44:17PM +0100, Mike Hearn wrote:
 It's usually OK to use MESSAGE for that, but if it's a message users might
 be seeing often it's best to keep it as a WARN or TRACE.

Ah-ha, yeah.  I should use MESSAGE for that.  It's only going to appear 
if peopl have already turned on trace/warn, or immediately following a 
FIXME that includes a path.  I just want to use it for the readability 
of the structure.

-- 
Kees Cook@outflux.net



Re: [crypt32] CryptProtectData/CryptUnprotectData helper functions

2005-05-18 Thread Kees Cook
On Wed, May 18, 2005 at 12:29:58PM -0700, Kees Cook wrote:
 Take two.

Ignore... this patch is broken, and I need to do an update of 
wine_dbg_printf() - MESSAGE()

-- 
Kees Cook@outflux.net



Re: [crypt32] implementation of CryptProtectData/CryptUnprotectData

2005-05-17 Thread Kees Cook
On Tue, May 17, 2005 at 02:34:53PM +0900, Mike McCormack wrote:
 ChangeLog:
  Implements a best-guess of CryptProtectData/CryptUnprotectData.
 
 Wow. That's alot of work :)

Heh, yeah, it has been.  But, I want it to get accepted, so I'll keep
working on it.  :)

 This patch looks OK to me at a quick glance, but if it's not applied, 
 please consider breaking it up.  At least that way, you'll have less to 
 submit next time round.

Okay, cool.  Alexandre, please let me know if breaking it up is
prefered, or if you want stuff arranged in some other way.  I'm all ears
for suggestions.  :)

-- 
Kees Cook@outflux.net



Re: crypt32: CryptProtectData/CryptUnprotectData

2005-05-04 Thread Kees Cook
On Wed, May 04, 2005 at 10:38:40AM +0200, Michael Jung wrote:
 DATA_BLOB somewhere. He also has to be able to restore in some way the 
 entropy and the description, if he wants to decrypt the DATA_BLOB at some 
 later time.

Actually, the description is returned by CryptUnprotectData (and is 
stored in the clear in the opaque blob).

 DATA_BLOB's are opaque by nature. Applications should not expect anything of 
 the format. So there is no benefit in trying to mimic the Windows data 
 format. (Sometimes MSDN states that a format should be considered opaque, 

Well, no, applications don't care, but Wine's implementation (and future 
implementation) of Crypt*protectData should attempt a guess at it.  This 
is what I've got so far:

/*
 * The data format returned by CryptProtectData seems to be something like:

 DWORD  count0; - how many info0_*[16] blocks follow (was always 1)
 BYTE   info0_0[16];- unknown information (was the same between calls)
 ...
 DWORD  count1; - how many info1_*[16] blocks follow (was always 1)
 BYTE   info1_0[16];- unknown information (different between calls)
 ...
 DWORD  null0;  - NULL end of records?
 DWORD  str_len;- length of WCHAR string including term
 WCHAR  str[str_len];   - The dataDescription value
 DWORD  unknown0;   - unknown value (seems large, but only WORD large, same)
 DWORD  unknown1;   - unknown value (seems small, less than a BYTE, same)
 DWORD  data_len;   - length of data (was 16 bytes) md5?
 BYTE   data[data_len]; - unknown data (fingerprint? changes)
 DWORD  null1;  - NULL ? (same)
 DWORD  unknown2;   - unknown value (seems large, but only WORD large, same)
 DWORD  unknown3;   - unknown value (seems small, less than a BYTE, same)
 DWORD  salt_len;   - salt length(?) - was 16 bytes==128b md5?
 BYTE   salt[salt_len]; - salt for symmetric encryption (changes)
 DWORD  cipher_len; - length of cipher(?) data - was close to plain 
  len, symmetric block ciphers like 3DES are in 
  40 byte chunks, I think
 BYTE   cipher[cipher_len]; - cipher text? (changes)
 DWORD  fingerprint_len; - length of fingerprint(?) data
 BYTE   fingerprint[fingerprint_len]; - SHA1 fingerprint(?) (20 bytes, changes) 
 */

 Like already said, we don't have access to a hash of the user's login 
 password, so we can't provide real security here. Therefore I think we should 
 not try to pretend it. IMO you should'nt do any encryption. Just pass back 
 the DATA_BLOB.

I think what I'm going to do is use (for now) the uid appended to a 
string that includes the time.  Maybe md5 it for fun.  I really don't 
know yet.  (Before encryption, though, I have to add on the entropy.)
Something like:
sprintf(salt,Wine:%u:%u:,uid,time());

 is accessible by the Crypt* family of API's in advapi32.dll. All that is 
 necessary for this to implement should be available in wine already.

Cool, that's good news.  I haven't had the chance to review that stuff 
yet.

-- 
Kees Cook@outflux.net



short-circuting a dialog box?

2005-05-03 Thread Kees Cook
I'm trying to figure out if there is a way to short-circuit a dialog 
box.  Basically, I want to traps calls to DialogBoxParam, pump calls 
into lpDialogFunc for dialog init, and then clicking of the Ok button, 
and finally trap calls to EndDialog.

It seems that this is ... hard.  :)  There is a lot of resource loading, 
window initialization code, etc that goes on inside DialogBoxParam, and 
I'd need to handle all of that, I think.  There even appears to be 
issues with 16 vs 32 bit handler addresses, etc.  Looks really ugly.

Is there a simpler way to programatically click Ok on a dialog box?  
(The dialog box coming from code that I don't have source for...)

-- 
Kees Cook@outflux.net



Re: short-circuting a dialog box?

2005-05-03 Thread Kees Cook
On Tue, May 03, 2005 at 11:56:35AM +0300, Shachar Shemesh wrote:
 For simple things, merely sending the dialog a WM_COMMAND with the right 
 parameters will do it for you. You can programatically find the dialog 
 using FindWindow.

Ah-ha, yes.  I ended up using EnumWindows (filtering out the HWND from 
GetTopWindow).  Thanks!  WM_COMMAND, IDOK, 0 did the trick.

Now, a final note, is there any way to stop a dialog from 
displaying itself?  (i.e., let dialogs become active, but not draw 
themselves?)  The ttydrv doesn't like trying to open the dialog:

fixme:ttydrv:TTYDRV_GetBitmapBits (0x7d, 0x76d3501c, 128): stub

-- 
Kees Cook@outflux.net



Re: short-circuting a dialog box?

2005-05-03 Thread Kees Cook
On Tue, May 03, 2005 at 07:38:26PM +0200, [EMAIL PROTECTED] wrote:
 YOu could trap it#s onshow event but be careful since most dlgs are  
 created as modal , you could end up hanging your process.

How would I go about capturing that?  (Or, how would I hook the event 
handler?)

-- 
Kees Cook@outflux.net



Re: short-circuting a dialog box?

2005-05-03 Thread Kees Cook
On Tue, May 03, 2005 at 08:29:10PM +0200, [EMAIL PROTECTED] wrote:
 It appears you really have very little knowlege of win32 API programming,  
 I'm not sure this is the place for you to start.

That's true.  I should probably take this off channel.

 Is this a wine problem ? If so in what way.

It's not a Wine problem exactly.  More of a make it work with Linux via
Wine issue.  I've been developing against the Wine libraries (I don't
use Windows natively).  The tool I've been writing loads and runs
DirectShow DLLs via the IFileSourceFilter APIs:
http://outflux.net/software/pkgs/srcfilter/

In the process, I've been writing patches to wine to fully implement
some of the calls made by the DLLs I've tried.  In an effort to make
srcfilter as easy to use as possible, I've been trying to make it as
non-interactive as possible, hence my desire to make the dialogs never 
display, not require X11, etc.  I need the dialog to think it's running, 
though.

-- 
Kees Cook@outflux.net



Re: crypt32: CryptProtectData/CryptUnprotectData

2005-05-03 Thread Kees Cook
On Tue, May 03, 2005 at 01:58:18PM -0700, Juan Lang wrote:
 Someone previously posted pretty good information about the format of
 CryptProtectData on MSDN.  I think it should be possible to implement a
 close facsimile, except that the user's credentials (password) would be
 missing in Wine since there isn't any at the moment.  If you have time to
 do this, it would be ideal.  Failing that, doing any stateless
 transformation (e.g. no change at all, or xor-ing with some magic value)
 would be preferrable to storing this data in the registry, if I understood
 Alexandre's comments correctly.

Okay.  The article (while very good: 
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnsecure/html/windataprotection-dpapi.asp)
doesn't fully address the opaque data blob.  I have taken it apart and 
found some common lengths, etc, so I think I can produce a reasonable 
guess at it, so that the future implementations will have very little to 
change.  The clues in the section Protected data blob is what I'm 
using for the guesses at the data blob format sections.

I should have a new patch ready soon.  Luckily all the tests and 
documentation will remain valid.  :)

 We're trying to avoid proliferation of OpenSSL in Wine.  Relying on
 CryptoAPI is a safer bet.

Is there somewhere I can find details on what's been completed in the 
CryptoAPI?  The http://winehq.com/site/winapi_stats page say it's at 21%.

Thanks for all the clarification.  I appreciate it!

-- 
Kees Cook@outflux.net



Re: crypt32: CryptProtectData/CryptUnprotectData

2005-04-13 Thread Kees Cook
On Wed, Apr 13, 2005 at 12:16:44PM +0200, Alexandre Julliard wrote:
 I don't understand while you come up with such an elaborate scheme of
 storing things in the registry when it's clearly not the way this
 thing is supposed to work. If you can't figure out what Windows does,
 then just xoring the data with 0xdeadbeef or something like this would
 be at least as secure as your solution, and would actually be much
 closer to the proper behavior.

Mostly I did this because there is some optional data (description,
entropy).  I didn't want to have to invent a data format to store all of 
that in, so I used the registry to do it instead.

Another reason I did it this way was so that it was easily to examine
and change the information getting passed back from the Crypt*Data
functions.  But I suppose, I can just use FIXME's for this.

I don't like the ssh-agent idea because not everyone uses ssh-agent.  If 
inventing a data format and XORing stuff is prefered, I can write it 
that way.

What direction should I take this?

-- 
Kees Cook@outflux.net



Re: crypt32: CryptProtectData/CryptUnprotectData take 2

2005-04-06 Thread Kees Cook
On Wed, Apr 06, 2005 at 10:29:37AM +0900, Mike McCormack wrote:
 The best way to write a test is to look at some of the test cases that 
 are there already.  Write and run the test under Windows, and make sure 
 it passes on Windows first.  The test is something like this:

Ah!  Whoops, I didn't think to try that originally.  I was just about to 
send my new patch too.  [time passes...]

 /* try with incorrect parameters */
 ok(!CryptProtectData(NULL,NULL,NULL,NULL,NULL,0,NULL), crypt 
 protect data should fail\n);
 ok(GetLastError() == ERROR_INVALID_PARAMETER, error returned 
 incorrect\n);

Ah-ha, I need to make calls to SetLastError then.  I wasn't doing that 
either.  Okay, 3rd time's the charm.  This patch includes full 
documentation, as well as the test suite which passes both on Wine and 
Windows.

-- 
Kees Cook@outflux.net



Re: crypt32: CryptProtectData/CryptUnprotectData take 3

2005-04-06 Thread Kees Cook
On Wed, Apr 06, 2005 at 11:08:12PM +0900, Dmitry Timoshkov wrote:
 It's better to keep alphabetical order of .spec file entries.

Oh, whoops.  I just blindly grouped them.  Fixed.

 if you are not going to conditionally include headers using '#ifdef HAVE_xxx'
 there is no need to include config.h.

Good point.  This was copied from elsewhere.  I've cleaned up the header 
files.

 Registry keys should be closed by RegCloseKey, not CloseHandle (here and
 everywhere else).

Whoops.  Okay, fixed.

 If you are going to test last error value after an API call it's a usual 
 practice
 to set the error first to some invalid value, 0xdeadbeef works fine.

Added.

Thanks for all the suggestions from everyone!  I'm glad you're willing 
to put up with me.  :)  Take 4 on it's way.

-- 
Kees Cook@outflux.net



Re: Remove reference to nonexistant strmif.h

2005-04-05 Thread Kees Cook
On Mon, Apr 04, 2005 at 10:24:53PM -0400, Dimitrie O. Paun wrote:
 ChangeLog
 Remove reference to nonexistant strmif.h

 +++ include/Makefile.in   5 Apr 2005 02:23:26 -
 - strmif.h \

/src/wine-cvs/include$ ls strmif.h 
strmif.h

? it's there for me.  :)

-- 
Kees Cook@outflux.net



Re: crypt32: CryptProtectData/CryptUnprotectData take 2

2005-04-05 Thread Kees Cook
On Tue, Apr 05, 2005 at 02:32:11PM +0900, Mike McCormack wrote:
 The new patch looks good.  I should have mentioned before that writing a 
 test case will help your patch be accepted.  Did you have any test code 
 about that you could turn into a test case for your newly implemented 
 functions?

Sure, I can write something.  I'll look around for docs on how to run 
tests -- I didn't find that when I looked around this morning.

Also: I realize I should provide full documentation for the actual 
Windows API calls themselves.  I documented everything BUT those.  :)  
What's the convention for the number after the API name?  I've seen some 
with numbers, and some with just an @ sign?

-- 
Kees Cook@outflux.net



Re: black-box implementation of CryptProtectData/CryptUnprotectData

2005-04-04 Thread Kees Cook
On Sun, Apr 03, 2005 at 11:04:53PM -0500, James Hawkins wrote:
 On Apr 3, 2005 10:12 PM, Kees Cook [EMAIL PROTECTED] wrote:
  To store the triplets, these functions use the registry:
  
  Registry Layout:
  HKEY_CURRENT_USER\Software\Wine\Crypt\ProtectData\Map\[index]
  Cipher:  HEX string
  Entropy: HEX string
  DataDescription: WCHAR
  Plain:   HEX string
  
 
 I'll have to be honest that I haven't looked over the code yet, but I
 do have a concern.  Do these values have to be stored under
 Software\Wine?  That location is for wine-specific configuration
 options and not api use, unless I'm mistaken.  Do we know if this data
 is stored in the registry in windows, and if so where is it stored?
 (because I know it's not Software\Wine ;-)

Windows doesn't store the results anywhere: it's just a symmetric crypto 
function.  Since we don't know the function, we have to store the 
original data somewhere so we can return it later.  Since this is 
entirely a Wine-only implementation of the encryption, I wanted to put 
it somewhere in the registry totally separate from all the other keys.  
Within the Wine tree seemed like the best place.

-- 
Kees Cook@outflux.net



Re: black-box implementation of CryptProtectData/CryptUnprotectData

2005-04-04 Thread Kees Cook
On Sun, Apr 03, 2005 at 11:56:34PM -0500, James Hawkins wrote:
 we do it should be encapsulated.  What I'm getting at is that just
 because this implementation is wine-specific doesn't mean some of the
 implementation data should go in Software\Wine.  Software\Wine is
 where the configurations of the wine program itself, not its
 implementation, are contained.  See what I mean?  btw it's great that

Sure, that's fine by me.  I wasn't really sure where to put it, but it's 
easy to change; it's just a path at the top of the file.  In looking 
around at other examples, it seemed the most sensible.  Is there a 
normal implementation-data-storage area for Wine?  I just wanted to 
avoid clashing with any other registry items.

I'm open to any suggestions.  :)

 you wrote this code and submitted it.  Sending the code in is the big
 first step.  I just think we should get a community opinion on this
 matter (ya never know, everyone may disagree with me!).  Keep up the
 good coding.

Thanks!

-- 
Kees Cook@outflux.net



Re: black-box implementation of CryptProtectData/CryptUnprotectData

2005-04-04 Thread Kees Cook
On Mon, Apr 04, 2005 at 03:01:53PM +0900, Mike McCormack wrote:
 Perhaps you could make it work right by using a key stored in ssh-agent?

Well, by working right, it means that taking a cipher/entropy from 
Windows and calling CryptUnprotectData on it in Wine would return the 
plain text.  This isn't going to be possible until we know what Windows 
keys off of to tie it to a machine and user.  I figure the first step is 
to make the functions work within Wine, then if the encryption is ever 
understood, the calls can be replaced.

 You don't need to try patch ChangeLog, because it's going to change alot 
 as patches are applied.  Just write the message you want to put in there.

Okay, cool.

 +hr = HRESULT_FROM_WIN32(RegOpenKeyExW(HKEY_CURRENT_USER, 
 wszProtectDataMap, 0, KEY_READ, hkeyMap));
 +if (!SUCCEEDED(hr))
 
 Why do you convert the error code to a HRESULT here?  Since you don't do 
 it elsewhere in your code, why not compare the returned value to 
 ERROR_SUCCESS, like you do below?

Well, mostly I was copying from other examples I found, especially the 
filtergraph code in dlls/quartz.  I'm happy to change that, of course.  
:)

 Personally, I prefer the following, as it makes the lines shorter, makes 
 it easier to add a printf(%ld\n,r); and makes the comparison more obvious.
 
 r = RegEnumKeyExW(hkeyMap, ...
 if( r != ERROR_SUCCES )
 break;

Okay, I can clean this up.

 You don't need the WINE_TRACE_ON() check, because TRACE already does 
 that for the default debug channel, so the following is the same:

Actually, I did that to avoid the line prefix that TRACE adds.  All 
the stuff where I call the dbg functions directly are part of helper 
functions, and seeing their names is confusing while watching a 
Protect/Unprotect session.

 Sometimes you used KR style brackets and indenting, sometimes you used 
 ANSI C style.  It's better to choose one or the other and stick to it.

Sorry about that.  I tried to stick to what seemed to be the wine style, 
with the braces on separate lines.  However, that's not what I'm used 
to, so a few of mine snuck in.  :)

 +return SUCCEEDED(RegSetValueExW(hkeyOpen,wszName,0,dwType,
 +pData.pbData,pData.cbData));
 
 The SUCCEEDED() macro is only for HRESULT values, so the above is going 
 to succeed in alot of cases where it shouldn't.

Doesn't RegSetValueExW return an HRESULT?

 In an effort to maintain portability, we don't use C99 style variable 
 declarations.

Ah, dang.  I tried to clean those up too when I was reading the Patch 
how-to.  I'll clean all this up, thanks very much!

BTW: what is your opinion on where to store the triplets in the 
Registry?

-- 
Kees Cook@outflux.net



Re: black-box implementation of CryptProtectData/CryptUnprotectData

2005-04-04 Thread Kees Cook
On Tue, Apr 05, 2005 at 01:07:14AM +0900, Mike McCormack wrote:
 It's probably better to keep it consistent with what the rest of Wine does.

I'd really like to push back on this.  The traces become unreadable as 
the various function names change.  I think the debugging as I have it 
is more useful than how it looks with only TRACE calls.  The top-level 
function spits out a TRACE to identify the caller, and then all the 
helper functions report the data structures.

 It seems like you need to investigate what it does on Windows and the 
 MSDN description of the function a bit more.  The description on MSDN 
 indicated that they used a per user key generated when the user logs in.

I already have, and decided it was best to avoid a more detailed 
investigation for fear of DMCA joy.  They key against at least user, 
machine, and time, since multiple calls with the same plain/entropy 
produces different ciphers.  My implementation intentionally avoids any 
encryption at all.  :)

I like to think of it as a good first step to getting the real 
functions.  With what I've got, a program can run normally.

I'll be sending version 2 of my patch in a little while.  It's got 
your suggestions incorporated, and a small bug fix.

-- 
Kees Cook@outflux.net