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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
|
Add pledge() and unveil()
Index: main.c
--- main.c.orig
+++ main.c
@@ -306,7 +306,7 @@ ttyslot(void)
#include <sys/param.h> /* for NOFILE */
#endif
-#if defined(BSD) && (BSD >= 199103)
+#if defined(BSD) && (BSD >= 199103) && !defined(__OpenBSD__)
#define WTMP
#endif
@@ -397,6 +397,7 @@ extern struct utmp *getutid __((struct utmp * _Id));
#define UTMP_FILENAME UTMP_FILE
#elif defined(_PATH_UTMP)
#define UTMP_FILENAME _PATH_UTMP
+int utmp_fd = -1;
#else
#define UTMP_FILENAME "/etc/utmp"
#endif
@@ -2838,6 +2839,13 @@ main(int argc, char *argv[]ENVP_ARG)
spawnXTerm(term, line_speed);
+ /* xterm (parent) grabs a fd for the utmp file now, while it
+ * has egid = "utmp". Then discard the egid. */
+ setEffectiveGroup(save_egid);
+ utmp_fd = open(etc_utmp, O_WRONLY | O_CLOEXEC);
+ setresgid(save_rgid, save_rgid, save_rgid);
+ save_egid = -1;
+
#ifndef VMS
/* Child process is out there, let's catch its termination */
@@ -2955,6 +2963,89 @@ main(int argc, char *argv[]ENVP_ARG)
if (resource.maximized)
RequestMaximize(term, True);
#endif
+
+ {
+#if OPT_EXEC_SELECTION
+ String data = NULL;
+ getKeymapResources(SHELL_OF(term), "vt100", "VT100", XtRString, &data, sizeof(data));
+ if (data &&
+ (strstr(data, "exec-formatted") || strstr(data, "exec-selectable"))) {
+
+ if (pledge("stdio rpath wpath id proc exec tty", NULL) == -1) {
+ xtermWarning("pledge\n");
+ exit(1);
+ }
+ } else
+#endif /* OPT_EXEC_SELECTION */
+ {
+ char *env;
+
+ if ((env = getenv("HOME"))) {
+ char homefile[PATH_MAX];
+ if (snprintf(homefile, sizeof homefile, "%s/.fonts",
+ env) <= sizeof(homefile))
+ if (unveil(homefile, "r") == -1)
+ xtermPerror("unveil %s", homefile);
+ if (snprintf(homefile, sizeof homefile, "%s/.cache/fontconfig",
+ env) <= sizeof(homefile))
+ if (unveil(homefile, "r") == 1)
+ xtermPerror("unveil %s", homefile);
+ if (snprintf(homefile, sizeof homefile, "%s/.icons",
+ env) <= sizeof(homefile))
+ if (unveil(homefile, "r") == -1)
+ xtermPerror("unveil %s", homefile);
+ }
+ if ((env = getenv("XDG_CONFIG_HOME"))) {
+ char xdgfile[PATH_MAX];
+
+ if (snprintf(xdgfile, sizeof xdgfile, "%s/fontconfig",
+ env) <= sizeof(xdgfile))
+ if (unveil(xdgfile, "r") == -1)
+ xtermPerror("unveil %s", xdgfile);
+ if (snprintf(xdgfile, sizeof xdgfile, "%s/icons",
+ env) <= sizeof(xdgfile))
+ if (unveil(xdgfile, "r") == -1)
+ xtermPerror("unveil %s", xdgfile);
+ }
+ if ((env = getenv("XDG_DATA_HOME"))) {
+ char xdgfile[PATH_MAX];
+
+ if (snprintf(xdgfile, sizeof xdgfile, "%s/fontconfig",
+ env) <= sizeof(xdgfile))
+ if (unveil(xdgfile, "r") == -1)
+ xtermPerror("unveil %s", xdgfile);
+ if (snprintf(xdgfile, sizeof xdgfile, "%s/icons",
+ env) <= sizeof(xdgfile))
+ if (unveil(xdgfile, "r") == -1)
+ xtermPerror("unveil %s", xdgfile);
+ }
+ if ((env = getenv("XDG_CACHE_HOME"))) {
+ char xdgfile[PATH_MAX];
+
+ if (snprintf(xdgfile, sizeof xdgfile, "%s/fontconfig",
+ env) <= sizeof(xdgfile))
+ if (unveil(xdgfile, "r") == -1)
+ xtermPerror("unveil %s", xdgfile);
+ }
+
+ if (unveil("/usr/X11R6", "r") == -1)
+ xtermPerror("unveil /usr/X11R6");
+ if (unveil("/usr/local/share/fonts", "r") == -1)
+ xtermPerror("unveil /usr/local/share/fonts");
+ if (unveil("/var/cache/fontconfig", "r") == -1)
+ xtermPerror("unveil /var/cache/fontconfig");
+ if (unveil("/usr/local/share/icons", "r") == -1)
+ xtermPerror("unveil /usr/local/share/icons");
+ if (unveil("/usr/local/lib/X11/icons", "r") == -1)
+ xtermPerror("unveil /usr/local/lib/X11/icons");
+
+ if (pledge("stdio rpath proc tty", NULL) == -1) {
+ xtermWarning("pledge\n");
+ exit(1);
+ }
+ }
+ }
+
for (;;) {
#if OPT_TEK4014
if (TEK4014_ACTIVE(term))
@@ -5489,10 +5580,12 @@ Exit(int n)
if (!resource.utmpInhibit && added_utmp_entry &&
(am_slave < 0 && tslot > 0)) {
#if defined(USE_UTMP_SETGID)
- setEffectiveGroup(save_egid);
- TRACE_IDS;
+ if (save_egid != -1) {
+ setEffectiveGroup(save_egid);
+ TRACE_IDS;
+ }
#endif
- if ((wfd = open(etc_utmp, O_WRONLY)) >= 0) {
+ if ((wfd = utmp_fd) != -1 || (wfd = open(etc_utmp, O_WRONLY)) >= 0) {
memset(&utmp, 0, sizeof(utmp));
lseek(wfd, (long) (tslot * sizeof(utmp)), 0);
IGNORE_RC(write(wfd, (char *) &utmp, sizeof(utmp)));
@@ -5510,8 +5603,10 @@ Exit(int n)
}
#endif /* WTMP */
#ifdef USE_UTMP_SETGID
- disableSetGid();
- TRACE_IDS;
+ if (save_egid != -1) {
+ disableSetGid();
+ TRACE_IDS;
+ }
#endif
}
#endif /* USE_SYSV_UTMP */
|