1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
--- gnupg-1.4.0/g10/g10.c 2004-12-16 09:47:36.000000000 +0000
+++ /tmp/dpep.O5S02c/gnupg-1.4.0/g10/g10.c 2005-02-03 23:31:40.645873299 +0000
@@ -69,6 +69,11 @@
#endif
+#ifdef USE_CAPABILITIES
+#include <sys/capability.h>
+#include <sys/prctl.h>
+#endif
+
enum cmd_and_opt_values
{
aNull = 0,
@@ -1618,6 +1623,10 @@
#ifdef USE_SHM_COPROCESSING
ulong requested_shm_size=0;
#endif
+#ifdef USE_CAPABILITIES
+ uid_t curr_uid;
+ cap_t caps;
+#endif
#ifdef __riscos__
opt.lock_once = 1;
@@ -1629,6 +1638,33 @@
* when adding any stuff between here and the call to
* secmem_init() somewhere after the option parsing
*/
+
+ /* if we use capabilities and run as root, we can immediately setuid back
+ * to the normal user and only keep CAP_IPC_LOCK until the shared memory is
+ * set up.
+ */
+#ifdef USE_CAPABILITIES
+ curr_uid = getuid();
+ if( curr_uid && !geteuid() ) { /* we are setuid root */
+ if( prctl( PR_SET_KEEPCAPS, 1, 0, 0, 0 ) ) {
+ perror( "main(): could not keep capabilities" );
+ return -100;
+ }
+
+ if( setuid( curr_uid ) ) {
+ perror( "main(): could not set user id" );
+ return -100;
+ }
+
+ caps = cap_from_text( "cap_ipc_lock=p" );
+ if( cap_set_proc( caps ) ) {
+ perror( "main(): could not install capabilities" );
+ return -100;
+ }
+ cap_free( caps );
+ }
+#endif
+
log_set_name("gpg");
secure_random_alloc(); /* put random number into secure memory */
may_coredump = disable_core_dumps();
@@ -1747,7 +1783,7 @@
}
#endif
/* initialize the secure memory. */
- got_secmem=secmem_init( 32768 );
+ got_secmem=secmem_init( 32768 ); /* this will drop all remaining privileges */
maybe_setuid = 0;
/* Okay, we are now working under our real uid */
|