New upstream version 2.0-0.9
Some checks failed
Build / build (push) Has been cancelled

This commit is contained in:
geos_one
2025-08-14 09:28:49 +02:00
parent c338ff82fb
commit 17bb5d7efa
634 changed files with 19105 additions and 52303 deletions

View File

@@ -4,7 +4,7 @@
#include <unistd.h>
#include <fcntl.h>
#include <grp.h>
#ifdef HAVE_SYS_IO_H
#ifdef __linux__
#include <sys/io.h>
#endif
#include "emu.h"
@@ -58,7 +58,7 @@ static int pop_priv(saved_priv_status *privs)
leavedos(99);
}
#ifdef PRIV_TESTING
c_printf("PRIV: popping %d privs_ptr=%p\n", *privs, privs);
c_printf("PRIV: poping %d privs_ptr=%p\n", *privs, privs);
#endif
ret = (int)*privs;
*privs = PRIV_MAGIC;
@@ -138,7 +138,7 @@ int real_leave_priv_setting(saved_priv_status *privs)
int priv_iopl(int pl)
{
#ifdef HAVE_SYS_IO_H
#ifdef __linux__
int ret;
if (PRIVS_ARE_OFF) {
_priv_on();
@@ -201,16 +201,28 @@ int priv_drop(void)
return 1;
}
#define MAXGROUPS 20
static gid_t *groups;
static int num_groups = 0;
int is_in_groups(gid_t gid)
{
int i;
for (i=0; i<num_groups; i++) {
if (gid == groups[i]) return 1;
}
return 0;
}
void priv_init(void)
{
const char *sh = getenv("SUDO_HOME"); // theoretical future var
const char *h = getenv("HOME");
uid = cur_uid = getuid();
/* suid bit only sets euid & suid but not uid, sudo sets all 3 */
if (!uid) under_root_login = 1;
if (!uid) under_root_login =1;
euid = cur_euid = geteuid();
if (!euid) can_do_root_stuff = 1;
if (!uid && !euid) skip_priv_setting = 1;
if (!uid) skip_priv_setting = 1;
gid = cur_gid = getgid();
egid = cur_egid = getegid();
@@ -219,10 +231,7 @@ void priv_init(void)
dosemu_proc_self_exe = readlink_malloc("/proc/self/exe");
/* For Fedora we must also save a file descriptor to /proc/self/maps */
dosemu_proc_self_maps_fd = open("/proc/self/maps", O_RDONLY | O_CLOEXEC);
if (!sh)
sh = getenv("DOSEMU_SUDO_HOME");
/* see if -E was used */
if (under_root_login && sh && h && strcmp(sh, h) == 0)
if (under_root_login)
{
/* check for sudo and set to original user */
char *s = getenv("SUDO_GID");
@@ -236,6 +245,12 @@ void priv_init(void)
if (s) {
uid = cur_uid = atoi(s);
if (uid) {
pid_t ppid;
char *path;
FILE *fp;
size_t n;
char *line;
skip_priv_setting = under_root_login = 0;
using_sudo = 1;
s = getenv("SUDO_USER");
@@ -244,6 +259,22 @@ void priv_init(void)
setenv("USER", s, 1);
}
setreuid(uid, euid);
/* retrieve $HOME from sudo's (the parent process') environment */
ppid = getppid();
if (asprintf(&path, "/proc/%d/environ", ppid) != -1) {
if ((fp = fopen(path, "r"))) {
line = NULL;
while(getdelim(&line, &n, '\0', fp) != -1) {
if(n>5 && memcmp(line, "HOME=", 5) == 0) {
setenv("HOME", line+5, 1);
}
}
free(line);
fclose(fp);
}
free(path);
}
}
}
}
@@ -253,5 +284,28 @@ void priv_init(void)
skip_priv_setting = 1;
}
if ((num_groups = getgroups(0, NULL)) <= 0) {
error("priv_init(): getgroups() size returned %d!\n", num_groups);
goto error_exit;
}
if ((groups = malloc(num_groups * sizeof(gid_t))) == NULL) {
error("priv_init(): malloc() failed!\n");
goto error_exit;
}
if (getgroups(num_groups, groups) == -1) {
error("priv_init(): getgroups() failed '%s'!\n", strerror(errno));
free(groups);
goto error_exit;
}
goto done;
error_exit:
num_groups = 0;
groups = NULL;
done:
if (!skip_priv_setting) _priv_off();
}