Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dist/include/mozilla/plugins/FunctionBrokerIPCUtils.h
Line
Count
Source (jump to first uncovered line)
1
#ifndef dom_plugins_ipc_functionbrokeripcutils_h
2
#define dom_plugins_ipc_functionbrokeripcutils_h 1
3
4
#include "PluginMessageUtils.h"
5
6
#if defined(XP_WIN)
7
8
#define SECURITY_WIN32
9
#include <security.h>
10
#include <wininet.h>
11
#include <schannel.h>
12
#include <commdlg.h>
13
14
#endif // defined(XP_WIN)
15
16
namespace mozilla {
17
namespace plugins {
18
19
/**
20
 * This enum represents all of the methods hooked by the main facility in BrokerClient.
21
 * It is used to allow quick lookup in the sFunctionsToHook structure.
22
 */
23
enum FunctionHookId
24
{
25
#if defined(XP_WIN)
26
    ID_GetWindowInfo = 0
27
  , ID_GetKeyState
28
  , ID_SetCursorPos
29
  , ID_GetSaveFileNameW
30
  , ID_GetOpenFileNameW
31
  , ID_InternetOpenA
32
  , ID_InternetConnectA
33
  , ID_InternetCloseHandle
34
  , ID_InternetQueryDataAvailable
35
  , ID_InternetReadFile
36
  , ID_InternetWriteFile
37
  , ID_InternetSetOptionA
38
  , ID_HttpAddRequestHeadersA
39
  , ID_HttpOpenRequestA
40
  , ID_HttpQueryInfoA
41
  , ID_HttpSendRequestA
42
  , ID_HttpSendRequestExA
43
  , ID_HttpEndRequestA
44
  , ID_InternetQueryOptionA
45
  , ID_InternetErrorDlg
46
  , ID_AcquireCredentialsHandleA
47
  , ID_QueryCredentialsAttributesA
48
  , ID_FreeCredentialsHandle
49
  , ID_PrintDlgW
50
  , ID_CreateMutexW
51
  , ID_FunctionHookCount
52
#else // defined(XP_WIN)
53
    ID_FunctionHookCount
54
#endif // defined(XP_WIN)
55
};
56
57
// Max number of bytes to show when logging a blob of raw memory
58
static const uint32_t MAX_BLOB_CHARS_TO_LOG = 12;
59
60
// Format strings for safe logging despite the fact that they are sometimes
61
// used as raw binary blobs.
62
inline nsCString FormatBlob(const nsACString& aParam)
63
0
{
64
0
  if (aParam.IsVoid() || aParam.IsEmpty()) {
65
0
    return nsCString(aParam.IsVoid() ? "<void>" : "<empty>");
66
0
  }
67
0
68
0
  nsCString str;
69
0
  uint32_t totalLen = std::min(MAX_BLOB_CHARS_TO_LOG, aParam.Length());
70
0
  // If we are printing only a portion of the string then follow it with ellipsis
71
0
  const char* maybeEllipsis = (MAX_BLOB_CHARS_TO_LOG < aParam.Length()) ? "..." : "";
72
0
  for (uint32_t idx = 0; idx < totalLen; ++idx) {
73
0
    // Should be %02x but I've run into a AppendPrintf bug...
74
0
    str.AppendPrintf("0x%2x ", aParam.Data()[idx] & 0xff);
75
0
  }
76
0
  str.AppendPrintf("%s   | '", maybeEllipsis);
77
0
  for (uint32_t idx = 0; idx < totalLen; ++idx) {
78
0
    str.AppendPrintf("%c", (aParam.Data()[idx] > 0) ? aParam.Data()[idx] : '.');
79
0
  }
80
0
  str.AppendPrintf("'%s", maybeEllipsis);
81
0
  return str;
82
0
}
83
84
#if defined(XP_WIN)
85
86
// Values indicate GetOpenFileNameW and GetSaveFileNameW.
87
enum GetFileNameFunc { OPEN_FUNC, SAVE_FUNC };
88
89
typedef nsTArray<nsCString> StringArray;
90
91
// IPC-capable version of the Windows OPENFILENAMEW struct.
92
typedef struct _OpenFileNameIPC
93
{
94
  // Allocates memory for the strings in this object.  This should usually
95
  // be used with a zeroed out OPENFILENAMEW structure.
96
  void AllocateOfnStrings(LPOPENFILENAMEW aLpofn) const;
97
  static void FreeOfnStrings(LPOPENFILENAMEW aLpofn);
98
  void AddToOfn(LPOPENFILENAMEW aLpofn) const;
99
  void CopyFromOfn(LPOPENFILENAMEW aLpofn);
100
  bool operator==(const _OpenFileNameIPC& o) const
101
  {
102
    return (o.mHwndOwner == mHwndOwner) &&
103
           (o.mFilter == mFilter) &&
104
           (o.mHasFilter == mHasFilter) &&
105
           (o.mCustomFilterIn == mCustomFilterIn) &&
106
           (o.mHasCustomFilter == mHasCustomFilter) &&
107
           (o.mNMaxCustFilterOut == mNMaxCustFilterOut) &&
108
           (o.mFilterIndex == mFilterIndex) &&
109
           (o.mFile == mFile) &&
110
           (o.mNMaxFile == mNMaxFile) &&
111
           (o.mNMaxFileTitle == mNMaxFileTitle) &&
112
           (o.mInitialDir == mInitialDir) &&
113
           (o.mHasInitialDir == mHasInitialDir) &&
114
           (o.mTitle == mTitle) &&
115
           (o.mHasTitle == mHasTitle) &&
116
           (o.mFlags == mFlags) &&
117
           (o.mDefExt == mDefExt) &&
118
           (o.mHasDefExt == mHasDefExt) &&
119
           (o.mFlagsEx == mFlagsEx);
120
  }
121
122
  NativeWindowHandle mHwndOwner;
123
  std::wstring mFilter;    // Double-NULL terminated (i.e. L"\0\0") if mHasFilter is true
124
  bool mHasFilter;
125
  std::wstring mCustomFilterIn;
126
  bool mHasCustomFilter;
127
  uint32_t mNMaxCustFilterOut;
128
  uint32_t mFilterIndex;
129
  std::wstring mFile;
130
  uint32_t mNMaxFile;
131
  uint32_t mNMaxFileTitle;
132
  std::wstring mInitialDir;
133
  bool mHasInitialDir;
134
  std::wstring mTitle;
135
  bool mHasTitle;
136
  uint32_t mFlags;
137
  std::wstring mDefExt;
138
  bool mHasDefExt;
139
  uint32_t mFlagsEx;
140
} OpenFileNameIPC;
141
142
// GetOpenFileNameW and GetSaveFileNameW overwrite fields of their OPENFILENAMEW
143
// parameter.  This represents those values so that they can be returned via IPC.
144
typedef struct _OpenFileNameRetIPC
145
{
146
  void CopyFromOfn(LPOPENFILENAMEW aLpofn);
147
  void AddToOfn(LPOPENFILENAMEW aLpofn) const;
148
  bool operator==(const _OpenFileNameRetIPC& o) const
149
  {
150
    return (o.mCustomFilterOut == mCustomFilterOut) &&
151
           (o.mFile == mFile) &&
152
           (o.mFileTitle == mFileTitle) &&
153
           (o.mFileOffset == mFileOffset) &&
154
           (o.mFileExtension == mFileExtension);
155
  }
156
157
  std::wstring mCustomFilterOut;
158
  std::wstring mFile;    // Double-NULL terminated (i.e. L"\0\0")
159
  std::wstring mFileTitle;
160
  uint16_t mFileOffset;
161
  uint16_t mFileExtension;
162
} OpenFileNameRetIPC;
163
164
typedef struct _IPCSchannelCred
165
{
166
  void CopyFrom(const PSCHANNEL_CRED& aSCred);
167
  void CopyTo(PSCHANNEL_CRED& aSCred) const;
168
  bool operator==(const _IPCSchannelCred& o) const
169
  {
170
    return (o.mEnabledProtocols == mEnabledProtocols) &&
171
           (o.mMinStrength == mMinStrength) &&
172
           (o.mMaxStrength == mMaxStrength) &&
173
           (o.mFlags == mFlags);
174
  }
175
176
177
  DWORD mEnabledProtocols;
178
  DWORD mMinStrength;
179
  DWORD mMaxStrength;
180
  DWORD mFlags;
181
} IPCSchannelCred;
182
183
typedef struct _IPCInternetBuffers
184
{
185
  void CopyFrom(const LPINTERNET_BUFFERSA& aBufs);
186
  void CopyTo(LPINTERNET_BUFFERSA& aBufs) const;
187
  bool operator==(const _IPCInternetBuffers& o) const
188
  {
189
    return o.mBuffers == mBuffers;
190
  }
191
  static void FreeBuffers(LPINTERNET_BUFFERSA& aBufs);
192
193
  struct Buffer
194
  {
195
    nsCString mHeader;
196
    uint32_t mHeaderTotal;
197
    nsCString mBuffer;
198
    uint32_t mBufferTotal;
199
    bool operator==(const Buffer& o) const
200
    {
201
      return (o.mHeader == mHeader) && (o.mHeaderTotal == mHeaderTotal) &&
202
             (o.mBuffer == mBuffer) && (o.mBufferTotal == mBufferTotal);
203
    }
204
  };
205
  nsTArray<Buffer> mBuffers;
206
} IPCInternetBuffers;
207
208
typedef struct _IPCPrintDlg
209
{
210
  void CopyFrom(const LPPRINTDLGW& aDlg);
211
  void CopyTo(LPPRINTDLGW& aDlg) const;
212
  bool operator==(const _IPCPrintDlg& o) const
213
  {
214
    MOZ_ASSERT_UNREACHABLE("DLP: TODO:"); return false;
215
  }
216
} IPCPrintDlg;
217
218
#endif // defined(XP_WIN)
219
220
} // namespace plugins
221
} // namespace mozilla
222
223
namespace IPC {
224
225
using mozilla::plugins::FunctionHookId;
226
227
#if defined(XP_WIN)
228
229
using mozilla::plugins::OpenFileNameIPC;
230
using mozilla::plugins::OpenFileNameRetIPC;
231
using mozilla::plugins::IPCSchannelCred;
232
using mozilla::plugins::IPCInternetBuffers;
233
using mozilla::plugins::IPCPrintDlg;
234
using mozilla::plugins::NativeWindowHandle;
235
using mozilla::plugins::StringArray;
236
237
template <>
238
struct ParamTraits<OpenFileNameIPC>
239
{
240
  typedef OpenFileNameIPC paramType;
241
242
  static void Write(Message* aMsg, const paramType& aParam)
243
  {
244
    WriteParam(aMsg, aParam.mHwndOwner);
245
    WriteParam(aMsg, aParam.mFilter);
246
    WriteParam(aMsg, aParam.mHasFilter);
247
    WriteParam(aMsg, aParam.mCustomFilterIn);
248
    WriteParam(aMsg, aParam.mHasCustomFilter);
249
    WriteParam(aMsg, aParam.mNMaxCustFilterOut);
250
    WriteParam(aMsg, aParam.mFilterIndex);
251
    WriteParam(aMsg, aParam.mFile);
252
    WriteParam(aMsg, aParam.mNMaxFile);
253
    WriteParam(aMsg, aParam.mNMaxFileTitle);
254
    WriteParam(aMsg, aParam.mInitialDir);
255
    WriteParam(aMsg, aParam.mHasInitialDir);
256
    WriteParam(aMsg, aParam.mTitle);
257
    WriteParam(aMsg, aParam.mHasTitle);
258
    WriteParam(aMsg, aParam.mFlags);
259
    WriteParam(aMsg, aParam.mDefExt);
260
    WriteParam(aMsg, aParam.mHasDefExt);
261
    WriteParam(aMsg, aParam.mFlagsEx);
262
  }
263
264
  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
265
  {
266
    if (ReadParam(aMsg, aIter, &aResult->mHwndOwner) &&
267
        ReadParam(aMsg, aIter, &aResult->mFilter) &&
268
        ReadParam(aMsg, aIter, &aResult->mHasFilter) &&
269
        ReadParam(aMsg, aIter, &aResult->mCustomFilterIn) &&
270
        ReadParam(aMsg, aIter, &aResult->mHasCustomFilter) &&
271
        ReadParam(aMsg, aIter, &aResult->mNMaxCustFilterOut) &&
272
        ReadParam(aMsg, aIter, &aResult->mFilterIndex) &&
273
        ReadParam(aMsg, aIter, &aResult->mFile) &&
274
        ReadParam(aMsg, aIter, &aResult->mNMaxFile) &&
275
        ReadParam(aMsg, aIter, &aResult->mNMaxFileTitle) &&
276
        ReadParam(aMsg, aIter, &aResult->mInitialDir) &&
277
        ReadParam(aMsg, aIter, &aResult->mHasInitialDir) &&
278
        ReadParam(aMsg, aIter, &aResult->mTitle) &&
279
        ReadParam(aMsg, aIter, &aResult->mHasTitle) &&
280
        ReadParam(aMsg, aIter, &aResult->mFlags) &&
281
        ReadParam(aMsg, aIter, &aResult->mDefExt) &&
282
        ReadParam(aMsg, aIter, &aResult->mHasDefExt) &&
283
        ReadParam(aMsg, aIter, &aResult->mFlagsEx)) {
284
      return true;
285
    }
286
    return false;
287
  }
288
289
  static void Log(const paramType& aParam, std::wstring* aLog)
290
  {
291
    aLog->append(StringPrintf(L"[%ls, %ls, %ls, %ls]", aParam.mFilter.c_str(),
292
                              aParam.mCustomFilterIn.c_str(), aParam.mFile.c_str(),
293
                              aParam.mTitle.c_str()));
294
  }
295
};
296
297
template <>
298
struct ParamTraits<OpenFileNameRetIPC>
299
{
300
  typedef OpenFileNameRetIPC paramType;
301
302
  static void Write(Message* aMsg, const paramType& aParam)
303
  {
304
    WriteParam(aMsg, aParam.mCustomFilterOut);
305
    WriteParam(aMsg, aParam.mFile);
306
    WriteParam(aMsg, aParam.mFileTitle);
307
    WriteParam(aMsg, aParam.mFileOffset);
308
    WriteParam(aMsg, aParam.mFileExtension);
309
  }
310
311
  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
312
  {
313
    if (ReadParam(aMsg, aIter, &aResult->mCustomFilterOut) &&
314
        ReadParam(aMsg, aIter, &aResult->mFile) &&
315
        ReadParam(aMsg, aIter, &aResult->mFileTitle) &&
316
        ReadParam(aMsg, aIter, &aResult->mFileOffset) &&
317
        ReadParam(aMsg, aIter, &aResult->mFileExtension)) {
318
      return true;
319
    }
320
    return false;
321
  }
322
323
  static void Log(const paramType& aParam, std::wstring* aLog)
324
  {
325
    aLog->append(StringPrintf(L"[%ls, %ls, %ls, %d, %d]", aParam.mCustomFilterOut.c_str(),
326
                              aParam.mFile.c_str(), aParam.mFileTitle.c_str(),
327
                              aParam.mFileOffset, aParam.mFileExtension));
328
  }
329
};
330
331
template <>
332
struct ParamTraits<mozilla::plugins::GetFileNameFunc> :
333
  public ContiguousEnumSerializerInclusive<mozilla::plugins::GetFileNameFunc,
334
                                           mozilla::plugins::OPEN_FUNC,
335
                                           mozilla::plugins::SAVE_FUNC>
336
{};
337
338
template <>
339
struct ParamTraits<IPCSchannelCred>
340
{
341
  typedef mozilla::plugins::IPCSchannelCred paramType;
342
343
  static void Write(Message* aMsg, const paramType& aParam)
344
  {
345
    WriteParam(aMsg, static_cast<uint32_t>(aParam.mEnabledProtocols));
346
    WriteParam(aMsg, static_cast<uint32_t>(aParam.mMinStrength));
347
    WriteParam(aMsg, static_cast<uint32_t>(aParam.mMaxStrength));
348
    WriteParam(aMsg, static_cast<uint32_t>(aParam.mFlags));
349
  }
350
351
  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
352
  {
353
    uint32_t proto, minStr, maxStr, flags;
354
    if (!ReadParam(aMsg, aIter, &proto) ||
355
        !ReadParam(aMsg, aIter, &minStr) ||
356
        !ReadParam(aMsg, aIter, &maxStr) ||
357
        !ReadParam(aMsg, aIter, &flags)) {
358
      return false;
359
    }
360
    aResult->mEnabledProtocols = proto;
361
    aResult->mMinStrength = minStr;
362
    aResult->mMaxStrength = maxStr;
363
    aResult->mFlags = flags;
364
    return true;
365
  }
366
367
  static void Log(const paramType& aParam, std::wstring* aLog)
368
  {
369
    aLog->append(StringPrintf(L"[%d,%d,%d,%d]",
370
                              aParam.mEnabledProtocols, aParam.mMinStrength,
371
                              aParam.mMaxStrength, aParam.mFlags));
372
  }
373
};
374
375
template <>
376
struct ParamTraits<IPCInternetBuffers::Buffer>
377
{
378
  typedef mozilla::plugins::IPCInternetBuffers::Buffer paramType;
379
380
  static void Write(Message* aMsg, const paramType& aParam)
381
  {
382
    WriteParam(aMsg, aParam.mHeader);
383
    WriteParam(aMsg, aParam.mHeaderTotal);
384
    WriteParam(aMsg, aParam.mBuffer);
385
    WriteParam(aMsg, aParam.mBufferTotal);
386
  }
387
388
  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
389
  {
390
    return ReadParam(aMsg, aIter, &aResult->mHeader) &&
391
           ReadParam(aMsg, aIter, &aResult->mHeaderTotal) &&
392
           ReadParam(aMsg, aIter, &aResult->mBuffer) &&
393
           ReadParam(aMsg, aIter, &aResult->mBufferTotal);
394
  }
395
396
  static void Log(const paramType& aParam, std::wstring* aLog)
397
  {
398
    nsCString head = mozilla::plugins::FormatBlob(aParam.mHeader);
399
    nsCString buffer = mozilla::plugins::FormatBlob(aParam.mBuffer);
400
    std::string msg = StringPrintf("[%s, %d, %s, %d]",
401
                                   head.Data(), aParam.mHeaderTotal,
402
                                   buffer.Data(), aParam.mBufferTotal);
403
    aLog->append(msg.begin(), msg.end());
404
  }
405
};
406
407
template <>
408
struct ParamTraits<IPCInternetBuffers>
409
{
410
  typedef mozilla::plugins::IPCInternetBuffers paramType;
411
412
  static void Write(Message* aMsg, const paramType& aParam)
413
  {
414
    WriteParam(aMsg, aParam.mBuffers);
415
  }
416
417
  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
418
  {
419
    return ReadParam(aMsg, aIter, &aResult->mBuffers);
420
  }
421
422
  static void Log(const paramType& aParam, std::wstring* aLog)
423
  {
424
    ParamTraits<nsTArray<IPCInternetBuffers::Buffer>>::Log(aParam.mBuffers, aLog);
425
  }
426
};
427
428
template <>
429
struct ParamTraits<IPCPrintDlg>
430
{
431
  typedef mozilla::plugins::IPCPrintDlg paramType;
432
433
  static void Write(Message* aMsg, const paramType& aParam)
434
  {
435
    MOZ_ASSERT_UNREACHABLE("TODO: DLP:");
436
  }
437
438
  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
439
  {
440
    MOZ_ASSERT_UNREACHABLE("TODO: DLP:");
441
    return true;
442
  }
443
444
  static void Log(const paramType& aParam, std::wstring* aLog)
445
  {
446
    MOZ_ASSERT_UNREACHABLE("TODO: DLP:");
447
  }
448
};
449
450
#endif // defined(XP_WIN)
451
452
template <>
453
struct ParamTraits<FunctionHookId> :
454
  public ContiguousEnumSerializer<FunctionHookId,
455
                                  static_cast<FunctionHookId>(0),
456
                                  FunctionHookId::ID_FunctionHookCount>
457
{};
458
459
} // namespace IPC
460
461
#endif /* dom_plugins_ipc_functionbrokeripcutils_h */