VirtualBox

source: vbox/trunk/src/VBox/HostDrivers/Support/SUPR3HardenedMain.cpp@ 11725

最後變更 在這個檔案從11725是 11725,由 vboxsync 提交於 17 年 前

#3076: Merged in the branch with the alternate driver authentication method. (34468:HEAD)

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 21.0 KB
 
1/* $Id: SUPR3HardenedMain.cpp 11725 2008-08-27 22:21:47Z vboxsync $ */
2/** @file
3 * VirtualBox Support Library - Hardened main().
4 */
5
6/*
7 * Copyright (C) 2006-2008 Sun Microsystems, Inc.
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.alldomusa.eu.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 *
26 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
27 * Clara, CA 95054 USA or visit http://www.sun.com if you need
28 * additional information or have any questions.
29 */
30
31/*******************************************************************************
32* Header Files *
33*******************************************************************************/
34#if defined(RT_OS_OS2)
35# define INCL_BASE
36# define INCL_ERRORS
37# include <os2.h>
38# include <stdio.h>
39
40#elif RT_OS_WINDOWS
41# include <Windows.h>
42# include <stdio.h>
43
44#else /* UNIXes */
45# include <iprt/types.h> /* stdint fun on darwin. */
46
47# include <stdio.h>
48# include <stdlib.h>
49# include <dlfcn.h>
50# include <limits.h>
51# include <errno.h>
52# include <unistd.h>
53# include <sys/stat.h>
54# include <sys/time.h>
55# include <stdio.h>
56# include <sys/types.h>
57# include <pwd.h>
58# ifdef RT_OS_DARWIN
59# include <mach-o/dyld.h>
60# endif
61
62#endif
63
64#include <VBox/sup.h>
65#include <VBox/err.h>
66#include <iprt/string.h>
67#include <iprt/param.h>
68
69#include "SUPLibInternal.h"
70
71
72/*******************************************************************************
73* Defined Constants And Macros *
74*******************************************************************************/
75/** @def SUP_HARDENED_SUID
76 * Whether we're employing set-user-ID-on-execute in the hardening.
77 */
78#if !defined(RT_OS_OS2) && !defined(RT_OS_WINDOWS) && !defined(RT_OS_L4)
79# define SUP_HARDENED_SUID
80#else
81# undef SUP_HARDENED_SUID
82#endif
83
84/** @def SUP_HARDENED_SYM
85 * Decorate a symbol that's resolved dynamically.
86 */
87#ifdef RT_OS_OS2
88# define SUP_HARDENED_SYM(sym) "_" ## sym
89#else
90# define SUP_HARDENED_SYM(sym) sym
91#endif
92
93
94/*******************************************************************************
95* Structures and Typedefs *
96*******************************************************************************/
97typedef DECLCALLBACK(int) FNTRUSTEDMAIN(int argc, char **argv, char **envp);
98typedef FNTRUSTEDMAIN *PFNTRUSTEDMAIN;
99
100typedef DECLCALLBACK(int) FNRTR3INIT(bool fInitSUPLib, size_t cbReserve);
101typedef FNRTR3INIT *PFNRTR3INIT;
102
103
104/*******************************************************************************
105* Global Variables *
106*******************************************************************************/
107/** The pre-init data we pass on to SUPR3 (residing in VBoxRT). */
108static SUPPREINITDATA g_SupPreInitData;
109/** The program path. */
110static char g_szSupLibHardenedProgramPath[RTPATH_MAX];
111
112/** The program name. */
113static const char *g_szSupLibHardenedProgName;
114
115
116/**
117 * @copydoc RTPathStripFilename.
118 */
119static void suplibHardenedPathStripFilename(char *pszPath)
120{
121 char *psz = pszPath;
122 char *pszLastSep = pszPath;
123
124 for (;; psz++)
125 {
126 switch (*psz)
127 {
128 /* handle separators. */
129#if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
130 case ':':
131 pszLastSep = psz + 1;
132 break;
133
134 case '\\':
135#endif
136 case '/':
137 pszLastSep = psz;
138 break;
139
140 /* the end */
141 case '\0':
142 if (pszLastSep == pszPath)
143 *pszLastSep++ = '.';
144 *pszLastSep = '\0';
145 return;
146 }
147 }
148 /* will never get here */
149}
150
151
152/**
153 * @copydoc RTPathFilename
154 */
155DECLHIDDEN(char *) supR3HardenedPathFilename(const char *pszPath)
156{
157 const char *psz = pszPath;
158 const char *pszLastComp = pszPath;
159
160 for (;; psz++)
161 {
162 switch (*psz)
163 {
164 /* handle separators. */
165#if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
166 case ':':
167 pszLastComp = psz + 1;
168 break;
169
170 case '\\':
171#endif
172 case '/':
173 pszLastComp = psz + 1;
174 break;
175
176 /* the end */
177 case '\0':
178 if (*pszLastComp)
179 return (char *)(void *)pszLastComp;
180 return NULL;
181 }
182 }
183
184 /* will never get here */
185 return NULL;
186}
187
188
189/**
190 * @copydoc RTPathAppPrivateNoArch
191 */
192DECLHIDDEN(int) supR3HardenedPathAppPrivateNoArch(char *pszPath, size_t cchPath)
193{
194#if !defined(RT_OS_WINDOWS) && defined(RTPATH_APP_PRIVATE)
195 const char *pszSrcPath = RTPATH_APP_PRIVATE;
196 size_t cchPathPrivateNoArch = strlen(pszSrcPath);
197 if (cchPathPrivateNoArch >= cchPath)
198 supR3HardenedFatal("supR3HardenedPathAppPrivateNoArch: Buffer overflow, %lu >= %lu\n",
199 (unsigned long)cchPathPrivateNoArch, (unsigned long)cchPath);
200 memcpy(pszPath, pszSrcPath, cchPathPrivateNoArch + 1);
201 return VINF_SUCCESS;
202
203#else
204 return supR3HardenedPathProgram(pszPath, cchPath);
205#endif
206}
207
208
209/**
210 * @copydoc RTPathAppPrivateArch
211 */
212DECLHIDDEN(int) supR3HardenedPathAppPrivateArch(char *pszPath, size_t cchPath)
213{
214#if !defined(RT_OS_WINDOWS) && defined(RTPATH_APP_PRIVATE_ARCH)
215 const char *pszSrcPath = RTPATH_APP_PRIVATE_ARCH;
216 size_t cchPathPrivateArch = strlen(pszSrcPath);
217 if (cchPathPrivateArch >= cchPath)
218 supR3HardenedFatal("supR3HardenedPathAppPrivateArch: Buffer overflow, %lu >= %lu\n",
219 (unsigned long)cchPathPrivateArch, (unsigned long)cchPath);
220 memcpy(pszPath, pszSrcPath, cchPathPrivateArch + 1);
221 return VINF_SUCCESS;
222
223#else
224 return supR3HardenedPathProgram(pszPath, cchPath);
225#endif
226}
227
228
229/**
230 * @copydoc RTPathSharedLibs
231 */
232DECLHIDDEN(int) supR3HardenedPathSharedLibs(char *pszPath, size_t cchPath)
233{
234#if !defined(RT_OS_WINDOWS) && defined(RTPATH_SHARED_LIBS)
235 const char *pszSrcPath = RTPATH_SHARED_LIBS;
236 size_t cchPathSharedLibs = strlen(pszSrcPath);
237 if (cchPathSharedLibs >= cchPath)
238 supR3HardenedFatal("supR3HardenedPathSharedLibs: Buffer overflow, %lu >= %lu\n",
239 (unsigned long)cchPathSharedLibs, (unsigned long)cchPath);
240 memcpy(pszPath, pszSrcPath, cchPathSharedLibs + 1);
241 return VINF_SUCCESS;
242
243#else
244 return supR3HardenedPathProgram(pszPath, cchPath);
245#endif
246}
247
248
249/**
250 * @copydoc RTPathAppDocs
251 */
252DECLHIDDEN(int) supR3HardenedPathAppDocs(char *pszPath, size_t cchPath)
253{
254#if !defined(RT_OS_WINDOWS) && defined(RTPATH_APP_DOCS)
255 const char *pszSrcPath = RTPATH_APP_DOCS;
256 size_t cchPathAppDocs = strlen(pszSrcPath);
257 if (cchPathAppDocs >= cchPath)
258 supR3HardenedFatal("supR3HardenedPathAppDocs: Buffer overflow, %lu >= %lu\n",
259 (unsigned long)cchPathAppDocs, (unsigned long)cchPath);
260 memcpy(pszPath, pszSrcPath, cchPathAppDocs + 1);
261 return VINF_SUCCESS;
262
263#else
264 return supR3HardenedPathProgram(pszPath, cchPath);
265#endif
266}
267
268
269/**
270 * @copydoc RTPathProgram
271 */
272DECLHIDDEN(int) supR3HardenedPathProgram(char *pszPath, size_t cchPath)
273{
274 /*
275 * First time only.
276 */
277 if (!g_szSupLibHardenedProgramPath[0])
278 {
279 /*
280 * Get the program filename.
281 *
282 * Most UNIXes have no API for obtaining the executable path, but provides a symbolic
283 * link in the proc file system that tells who was exec'ed. The bad thing about this
284 * is that we have to use readlink, one of the weirder UNIX APIs.
285 *
286 * Darwin, OS/2 and Windows all have proper APIs for getting the program file name.
287 */
288#if defined(RT_OS_LINUX) || defined(RT_OS_FREEBSD) || defined(RT_OS_SOLARIS)
289# ifdef RT_OS_LINUX
290 int cchLink = readlink("/proc/self/exe", &g_szSupLibHardenedProgramPath[0], sizeof(g_szSupLibHardenedProgramPath) - 1);
291# elif defined(RT_OS_SOLARIS)
292 char szFileBuf[PATH_MAX + 1];
293 sprintf(szFileBuf, "/proc/%ld/path/a.out", (long)getpid());
294 int cchLink = readlink(szFileBuf, &g_szSupLibHardenedProgramPath[0], sizeof(g_szSupLibHardenedProgramPath) - 1);
295# else /* RT_OS_FREEBSD: */
296 int cchLink = readlink("/proc/curproc/file", &g_szSupLibHardenedProgramPath[0], sizeof(g_szSupLibHardenedProgramPath) - 1);
297# endif
298 if (cchLink < 0 || cchLink == sizeof(g_szSupLibHardenedProgramPath) - 1)
299 supR3HardenedFatal("supR3HardenedPathProgram: couldn't read \"%s\", errno=%d cchLink=%d\n",
300 g_szSupLibHardenedProgramPath, errno, cchLink);
301 g_szSupLibHardenedProgramPath[cchLink] = '\0';
302
303#elif defined(RT_OS_OS2) || defined(RT_OS_L4)
304 _execname(g_szSupLibHardenedProgramPath, sizeof(g_szSupLibHardenedProgramPath));
305
306#elif defined(RT_OS_DARWIN)
307 const char *pszImageName = _dyld_get_image_name(0);
308 if (!pszImageName)
309 supR3HardenedFatal("supR3HardenedPathProgram: _dyld_get_image_name(0) failed\n");
310 size_t cchImageName = strlen(pszImageName);
311 if (!cchImageName || cchImageName >= sizeof(g_szSupLibHardenedProgramPath))
312 supR3HardenedFatal("supR3HardenedPathProgram: _dyld_get_image_name(0) failed, cchImageName=%d\n", cchImageName);
313 memcpy(g_szSupLibHardenedProgramPath, pszImageName, cchImageName + 1);
314
315#elif defined(RT_OS_WINDOWS)
316 HMODULE hExe = GetModuleHandle(NULL);
317 if (!GetModuleFileName(hExe, &g_szSupLibHardenedProgramPath[0], sizeof(g_szSupLibHardenedProgramPath)))
318 supR3HardenedFatal("supR3HardenedPathProgram: GetModuleFileName failed, rc=%d\n", GetLastError());
319#else
320# error needs porting.
321#endif
322
323 /*
324 * Strip off the filename part (RTPathStripFilename()).
325 */
326 suplibHardenedPathStripFilename(g_szSupLibHardenedProgramPath);
327 }
328
329 /*
330 * Calc the length and check if there is space before copying.
331 */
332 unsigned cch = strlen(g_szSupLibHardenedProgramPath) + 1;
333 if (cch <= cchPath)
334 {
335 memcpy(pszPath, g_szSupLibHardenedProgramPath, cch + 1);
336 return VINF_SUCCESS;
337 }
338
339 supR3HardenedFatal("supR3HardenedPathProgram: Buffer too small (%u < %u)\n", cchPath, cch);
340 return VERR_BUFFER_OVERFLOW;
341}
342
343
344
345DECLHIDDEN(void) supR3HardenedFatalV(const char *pszFormat, va_list va)
346{
347 fprintf(stderr, "%s: ", g_szSupLibHardenedProgName);
348 vfprintf(stderr, pszFormat, va);
349 for (;;)
350#ifdef _MSC_VER
351 exit(1);
352#else
353 _Exit(1);
354#endif
355}
356
357
358DECLHIDDEN(void) supR3HardenedFatal(const char *pszFormat, ...)
359{
360 va_list va;
361 va_start(va, pszFormat);
362 supR3HardenedFatalV(pszFormat, va);
363 va_end(va);
364}
365
366
367DECLHIDDEN(int) supR3HardenedErrorV(int rc, bool fFatal, const char *pszFormat, va_list va)
368{
369 if (fFatal)
370 supR3HardenedFatalV(pszFormat, va);
371
372 fprintf(stderr, "%s: ", g_szSupLibHardenedProgName);
373 vfprintf(stderr, pszFormat, va);
374 return rc;
375}
376
377
378DECLHIDDEN(int) supR3HardenedError(int rc, bool fFatal, const char *pszFormat, ...)
379{
380 va_list va;
381 va_start(va, pszFormat);
382 supR3HardenedErrorV(rc, fFatal, pszFormat, va);
383 va_end(va);
384 return rc;
385}
386
387
388/**
389 * Wrapper around snprintf which will throw a fatal error on buffer overflow.
390 *
391 * @returns Number of chars in the result string.
392 * @param pszDst The destination buffer.
393 * @param cchDst The size of the buffer.
394 * @param pszFormat The format string.
395 * @param ... Format arguments.
396 */
397static size_t supR3HardenedStrPrintf(char *pszDst, size_t cchDst, const char *pszFormat, ...)
398{
399 va_list va;
400 va_start(va, pszFormat);
401#ifdef _MSC_VER
402 int cch = _vsnprintf(pszDst, cchDst, pszFormat, va);
403#else
404 int cch = vsnprintf(pszDst, cchDst, pszFormat, va);
405#endif
406 va_end(va);
407 if ((unsigned)cch >= cchDst || cch < 0)
408 supR3HardenedFatal("supR3HardenedStrPrintf: buffer overflow, %d >= %lu\n", cch, (long)cchDst);
409 return cch;
410}
411
412
413/**
414 * Attempts to open /dev/vboxdrv (or equvivalent).
415 *
416 * @remarks This function will not return on failure.
417 */
418static void supR3HardenedMainOpenDevice(void)
419{
420 int rc = suplibOsInit(&g_SupPreInitData.Data, false);
421 if (RT_SUCCESS(rc))
422 return;
423
424 switch (rc)
425 {
426 case VERR_VM_DRIVER_NOT_INSTALLED:
427 supR3HardenedFatal("supR3HardenedMainOpenDevice: VERR_VM_DRIVER_NOT_INSTALLED\n");
428 case VERR_VM_DRIVER_NOT_ACCESSIBLE:
429 supR3HardenedFatal("supR3HardenedMainOpenDevice: VERR_VM_DRIVER_NOT_ACCESSIBLE\n");
430 case VERR_VM_DRIVER_LOAD_ERROR:
431 supR3HardenedFatal("supR3HardenedMainOpenDevice: VERR_VM_DRIVER_LOAD_ERROR\n");
432 case VERR_VM_DRIVER_OPEN_ERROR:
433 supR3HardenedFatal("supR3HardenedMainOpenDevice: VERR_VM_DRIVER_OPEN_ERROR\n");
434 case VERR_VM_DRIVER_VERSION_MISMATCH:
435 supR3HardenedFatal("supR3HardenedMainOpenDevice: VERR_VM_DRIVER_VERSION_MISMATCH\n");
436 case VERR_ACCESS_DENIED:
437 supR3HardenedFatal("supR3HardenedMainOpenDevice: VERR_ACCESS_DENIED\n");
438 default:
439 supR3HardenedFatal("supR3HardenedMainOpenDevice: rc=%d\n", rc);
440 }
441}
442
443
444/**
445 * Loads the VBoxRT DLL/SO/DYLIB, hands it the open driver,
446 * and calls RTR3Init.
447 *
448 * @param fFlags The SUPR3HardenedMain fFlags argument, passed to supR3PreInit.
449 *
450 * @remarks VBoxRT contains both IPRT and SUPR3.
451 * @remarks This function will not return on failure.
452 */
453static void supR3HardenedMainInitRuntime(uint32_t fFlags)
454{
455 /*
456 * Construct the name.
457 */
458 char szPath[RTPATH_MAX];
459 supR3HardenedPathSharedLibs(szPath, sizeof(szPath) - sizeof("/VBoxRT" SUPLIB_DLL_SUFF));
460 strcat(szPath, "/VBoxRT" SUPLIB_DLL_SUFF);
461
462 /*
463 * Open it and resolve the symbols.
464 */
465#if defined(RT_OS_WINDOWS)
466 /** @todo consider using LOAD_WITH_ALTERED_SEARCH_PATH here! */
467 HMODULE hMod = LoadLibraryEx(szPath, NULL /*hFile*/, 0 /* dwFlags */);
468 if (!hMod)
469 supR3HardenedFatal("supR3HardenedMainGetTrustedMain: LoadLibraryEx(\"%s\",,) failed, rc=%d\n",
470 szPath, GetLastError());
471 PFNRTR3INIT pfnRTInit = (PFNRTR3INIT)GetProcAddress(hMod, SUP_HARDENED_SYM("RTR3Init"));
472 if (!pfnRTInit)
473 supR3HardenedFatal("supR3HardenedMainGetTrustedMain: Entrypoint \"RTR3Init\" not found in \"%s\" (rc=%d)\n",
474 szPath, GetLastError());
475
476 PFNSUPR3PREINIT pfnSUPPreInit = (PFNSUPR3PREINIT)GetProcAddress(hMod, SUP_HARDENED_SYM("supR3PreInit"));
477 if (!pfnSUPPreInit)
478 supR3HardenedFatal("supR3HardenedMainGetTrustedMain: Entrypoint \"supR3PreInit\" not found in \"%s\" (rc=%d)\n",
479 szPath, GetLastError());
480
481#else
482 /* the dlopen crowd */
483 void *pvMod = dlopen(szPath, RTLD_NOW | RTLD_GLOBAL);
484 if (!pvMod)
485 supR3HardenedFatal("supR3HardenedMainGetTrustedMain: dlopen(\"%s\",) failed: %s\n",
486 szPath, dlerror());
487 PFNRTR3INIT pfnRTInit = (PFNRTR3INIT)(uintptr_t)dlsym(pvMod, SUP_HARDENED_SYM("RTR3Init"));
488 if (!pfnRTInit)
489 supR3HardenedFatal("supR3HardenedMainGetTrustedMain: Entrypoint \"RTR3Init\" not found in \"%s\"!\ndlerror: %s\n",
490 szPath, dlerror());
491 PFNSUPR3PREINIT pfnSUPPreInit = (PFNSUPR3PREINIT)(uintptr_t)dlsym(pvMod, SUP_HARDENED_SYM("supR3PreInit"));
492 if (!pfnSUPPreInit)
493 supR3HardenedFatal("supR3HardenedMainGetTrustedMain: Entrypoint \"supR3PreInit\" not found in \"%s\"!\ndlerror: %s\n",
494 szPath, dlerror());
495#endif
496
497 /*
498 * Make the calls.
499 */
500 supR3HardenedGetPreInitData(&g_SupPreInitData);
501 int rc = pfnSUPPreInit(&g_SupPreInitData, fFlags);
502 if (RT_FAILURE(rc))
503 supR3HardenedFatal("supR3PreInit: Failed with rc=%d\n", rc);
504 rc = pfnRTInit(!(fFlags & SUPSECMAIN_FLAGS_DONT_OPEN_DEV), 0);
505 if (RT_FAILURE(rc))
506 supR3HardenedFatal("RTR3Init: Failed with rc=%d\n", rc);
507}
508
509
510/**
511 * Loads the DLL/SO/DYLIB containing the actual program and
512 * resolves the TrustedMain symbol.
513 *
514 * @returns Pointer to the trusted main of the actual program.
515 * @param pszProgName The program name.
516 * @remarks This function will not return on failure.
517 */
518static PFNTRUSTEDMAIN supR3HardenedMainGetTrustedMain(const char *pszProgName)
519{
520 /*
521 * Construct the name.
522 */
523 char szPath[RTPATH_MAX];
524 supR3HardenedPathAppPrivateArch(szPath, sizeof(szPath) - 10);
525 size_t cch = strlen(szPath);
526 supR3HardenedStrPrintf(&szPath[cch], sizeof(szPath) - cch, "/%s%s", pszProgName, SUPLIB_DLL_SUFF);
527
528 /*
529 * Open it and resolve the symbol.
530 */
531#if defined(RT_OS_WINDOWS)
532 /** @todo consider using LOAD_WITH_ALTERED_SEARCH_PATH here! */
533 HMODULE hMod = LoadLibraryEx(szPath, NULL /*hFile*/, 0 /* dwFlags */);
534 if (!hMod)
535 supR3HardenedFatal("supR3HardenedMainGetTrustedMain: LoadLibraryEx(\"%s\",,) failed, rc=%d\n",
536 szPath, GetLastError());
537 FARPROC pfn = GetProcAddress(hMod, SUP_HARDENED_SYM("TrustedMain"));
538 if (!pfn)
539 supR3HardenedFatal("supR3HardenedMainGetTrustedMain: Entrypoint \"TrustedMain\" not found in \"%s\" (rc=%d)\n",
540 szPath, GetLastError());
541 return (PFNTRUSTEDMAIN)pfn;
542
543#else
544 /* the dlopen crowd */
545 void *pvMod = dlopen(szPath, RTLD_NOW | RTLD_GLOBAL);
546 if (!pvMod)
547 supR3HardenedFatal("supR3HardenedMainGetTrustedMain: dlopen(\"%s\",) failed: %s\n",
548 szPath, dlerror());
549 void *pvSym = dlsym(pvMod, SUP_HARDENED_SYM("TrustedMain"));
550 if (!pvSym)
551 supR3HardenedFatal("supR3HardenedMainGetTrustedMain: Entrypoint \"TrustedMain\" not found in \"%s\"!\ndlerror: %s\n",
552 szPath, dlerror());
553 return (PFNTRUSTEDMAIN)(uintptr_t)pvSym;
554#endif
555}
556
557
558/**
559 * Secure main.
560 *
561 * This is used for the set-user-ID-on-execute binaries on unixy systems
562 * and when using the open-vboxdrv-via-root-service setup on Windows.
563 *
564 * This function will perform the integrity checks of the VirtualBox
565 * installation, open the support driver, open the root service (later),
566 * and load the DLL corresponding to \a pszProgName and execute its main
567 * function.
568 *
569 * @returns Return code appropriate for main().
570 *
571 * @param pszProgName The program name. This will be used to figure out which
572 * DLL/SO/DYLIB to load and execute.
573 * @param fFlags Flags.
574 * @param argc The argument count.
575 * @param argv The argument vector.
576 * @param envp The environment vector.
577 */
578DECLHIDDEN(int) SUPR3HardenedMain(const char *pszProgName, uint32_t fFlags, int argc, char **argv, char **envp)
579{
580 /*
581 * Note! At this point there is no IPRT, so we will have to stick
582 * to basic CRT functions that everyone agree upon.
583 */
584 g_szSupLibHardenedProgName = pszProgName;
585 g_SupPreInitData.u32Magic = SUPPREINITDATA_MAGIC;
586 g_SupPreInitData.Data.hDevice = NIL_RTFILE;
587 g_SupPreInitData.u32EndMagic = SUPPREINITDATA_MAGIC;
588
589#ifdef SUP_HARDENED_SUID
590 /*
591 * Check that we're root, if we aren't then the installation is butchered.
592 */
593 uid_t const uid = getuid();
594 gid_t const gid = getgid();
595 if (geteuid() != 0 /* root */)
596 supR3HardenedFatal("SUPR3HardenedMain: effective uid is not root (euid=%d egid=%d uid=%d gid=%d)\n",
597 geteuid(), getegid(), uid, gid);
598#endif
599
600 /*
601 * Validate the installation.
602 */
603 supR3HardenedVerifyAll(true /* fFatal */, false /* fLeaveFilesOpen */, pszProgName);
604
605 /*
606 * Open the vboxdrv device.
607 */
608 if (!(fFlags & SUPSECMAIN_FLAGS_DONT_OPEN_DEV))
609 supR3HardenedMainOpenDevice();
610
611 /*
612 * Open the root service connection.
613 */
614 //if (!(fFlags & SUPSECMAIN_FLAGS_DONT_OPEN_SVC))
615 //supR3HardenedMainOpenService(&g_SupPreInitData, true /* fFatal */);
616
617#ifdef SUP_HARDENED_SUID
618 /*
619 * Drop any root privileges we might be holding.
620 */
621 setegid(gid);
622 seteuid(uid);
623 if ( geteuid() != uid
624 || getegid() != gid)
625 supR3HardenedFatal("SUPR3HardenedMain: failed to drop root privileges! (euid=%d egid=%d; wanted %d and %d)\n",
626 geteuid(), getegid(), uid, gid);
627#endif
628
629 /*
630 * Load the IPRT, hand the SUPLib part the open driver and
631 * call RTR3Init.
632 */
633 supR3HardenedMainInitRuntime(fFlags);
634
635 /*
636 * Load the DLL/SO/DYLIB containing the actual program
637 * and pass control to it.
638 */
639 PFNTRUSTEDMAIN pfnTrustedMain = supR3HardenedMainGetTrustedMain(pszProgName);
640 return pfnTrustedMain(argc, argv, envp);
641}
642
643
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette