Skip to content

Commit

Permalink
linux: force HOME to be set
Browse files Browse the repository at this point in the history
if the HOME environment variable is not set, try to read it from the
/etc/passwd file.

Signed-off-by: Giuseppe Scrivano <[email protected]>
  • Loading branch information
giuseppe committed Sep 21, 2019
1 parent 66cd22c commit 1c87552
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 1 deletion.
1 change: 1 addition & 0 deletions cfg.mk
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ local-checks-to-skip = \
sc_unmarked_diagnostics \
sc_prohibit_always_true_header_tests \
sc_prohibit_intprops_without_use \
sc_error_message_uppercase


#SHELL=bash -x
Expand Down
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ AC_CHECK_HEADERS([sys/capability.h], [], [AC_MSG_ERROR([*** POSIX caps headers n

AC_CHECK_HEADERS([error.h])

AC_CHECK_FUNCS(copy_file_range bpf fgetxattr statx)
AC_CHECK_FUNCS(copy_file_range bpf fgetxattr statx fgetpwent_r)

AC_SEARCH_LIBS(cap_from_name, [cap], [AC_DEFINE([HAVE_CAP], 1, [Define if libcap is available])], [AC_MSG_ERROR([*** libcap headers not found])])
AC_SEARCH_LIBS(seccomp_rule_add, [seccomp], [AC_DEFINE([HAVE_SECCOMP], 1, [Define if seccomp is available])], [AC_MSG_ERROR([*** libseccomp headers not found])])
Expand Down
14 changes: 14 additions & 0 deletions src/libcrun/container.c
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,13 @@ container_entrypoint_init (void *args, const char *notify_socket,
return crun_make_error (err, errno, "putenv '%s'", def->process->env[i]);
}

if (getenv ("HOME") == NULL)
{
ret = set_home_env (container->container_uid);
if (UNLIKELY (ret < 0))
libcrun_warning ("cannot set HOME environment variable");
}

if (def->process && def->process->args)
{
*exec_path = find_executable (def->process->args[0]);
Expand Down Expand Up @@ -1977,6 +1984,13 @@ libcrun_container_exec (libcrun_context_t *context, const char *id, oci_containe
if (putenv (process->env[i]) < 0)
libcrun_fail_with_error ( errno, "putenv '%s'", process->env[i]);

if (getenv ("HOME") == NULL)
{
ret = set_home_env (container->container_uid);
if (UNLIKELY (ret < 0))
libcrun_warning ("cannot set HOME environment variable");
}

if (process->selinux_label)
{
if (UNLIKELY (set_selinux_exec_label (process->selinux_label, err) < 0))
Expand Down
51 changes: 51 additions & 0 deletions src/libcrun/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -757,6 +757,57 @@ run_process (char **args, libcrun_error_t *err)
_exit (EXIT_FAILURE);
}

int
set_home_env (uid_t id)
{
#ifdef HAVE_FGETPWENT_R
struct passwd pwd;
cleanup_free char *buf = NULL;
long buf_size;
cleanup_file FILE *stream = NULL;

buf_size = sysconf (_SC_GETPW_R_SIZE_MAX);
if (buf_size < 0)
buf_size = 1024;

buf = xmalloc (buf_size);

stream = fopen ("/etc/passwd", "r");
if (stream == NULL)
return -1;

for (;;)
{
int ret;
struct passwd *ret_pw = NULL;

ret = fgetpwent_r (stream, &pwd, buf, buf_size, &ret_pw);
if (UNLIKELY (ret != 0))
{
if (errno == ENOENT)
return 0;

if (errno != ERANGE)
return ret;

buf_size *= 2;
buf = xrealloc (buf, buf_size);
continue;
}

if (ret_pw && ret_pw->pw_uid == id)
{
setenv ("HOME", ret_pw->pw_dir, 1);
return 0;
}
}
return 0;
#else
errno = ENOTSUP;
return -1;
#endif
}

/*if subuid or subgid exist, take the first range for the user */
static int
getsubidrange (uid_t id, int is_uid, uint32_t *from, uint32_t *len)
Expand Down
2 changes: 2 additions & 0 deletions src/libcrun/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,4 +131,6 @@ const char *find_executable (const char *executable_path);

int copy_recursive_fd_to_fd (int srcfd, int destfd, const char *srcname, const char *destname, libcrun_error_t *err);

int set_home_env (uid_t uid);

#endif

0 comments on commit 1c87552

Please sign in to comment.