Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions src/libcrun/container.c
Original file line number Diff line number Diff line change
Expand Up @@ -1176,8 +1176,9 @@ setup_environment (runtime_spec_schema_config_schema *def, uid_t container_uid,
ret = set_home_env (container_uid);
if (UNLIKELY (ret < 0))
{
setenv ("HOME", "/", 1);
libcrun_warning ("cannot detect HOME environment variable, setting default");
if (UNLIKELY (setenv ("HOME", "/", 1) < 0))
return crun_make_error (err, errno, "setenv HOME");
}
}

Expand Down Expand Up @@ -1402,8 +1403,9 @@ container_init_setup (void *args, pid_t own_pid, char *notify_socket,
/* Set primary process to 1 explicitly if nothing is configured and LISTEN_FD is not set. */
if (entrypoint_args->context->listen_fds > 0 && getenv ("LISTEN_PID") == NULL)
{
setenv ("LISTEN_PID", "1", 1);
libcrun_warning ("setting LISTEN_PID=1 since no previous configuration was found");
if (UNLIKELY (setenv ("LISTEN_PID", "1", 1) < 0))
return crun_make_error (err, errno, "setenv LISTENPID");
}

/* Attempt to chdir immediately here, before doing the setresuid. If we fail here, let's
Expand Down Expand Up @@ -3690,8 +3692,9 @@ exec_process_entrypoint (libcrun_context_t *context,
ret = set_home_env (container_uid);
if (UNLIKELY (ret < 0))
{
setenv ("HOME", "/", 1);
libcrun_warning ("cannot detect HOME environment variable, setting default");
if (UNLIKELY (setenv ("HOME", "/", 1) < 0))
return crun_make_error (err, errno, "setenv HOME");
}
}

Expand Down
6 changes: 4 additions & 2 deletions src/libcrun/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -1482,8 +1482,10 @@ set_home_env (uid_t id)

if (ret_pw && ret_pw->pw_uid == id)
{
setenv ("HOME", ret_pw->pw_dir, 1);
return 0;
if (UNLIKELY (setenv ("HOME", ret_pw->pw_dir, 1) < 0))
OOM ();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we just set errno and return -1 here?

We may look at better error reporting later, but OOM seems overkill here

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

setenv can fail for two reasons: EINVAL (when name is null, or empty, or contains =, which is not the case with $HOME), and ENOMEM. From the quick glance into glibc's stdlib/setenv.c it seems to be true, so OOM seems legit here.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The above theoretically means we can OOM() in other places after setenv failed, if its first argument is known to be good. Practically, I'm not sure since non-glibc implementations can possibly return other errors (although looking into current musl sources, it's the same as for glibc).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok that is good, OOM looks correct. Thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't had time to look into this, but my original idea by using OOM() was to avoid that
the environment variable HOME is set to / because the system is low on memory, for example here

crun/src/libcrun/container.c

Lines 3690 to 3696 in c07aadc

ret = set_home_env (container_uid);
if (UNLIKELY (ret < 0))
{
setenv ("HOME", "/", 1);
libcrun_warning ("cannot detect HOME environment variable, setting default");
}
}

Thinking more about it, a similar problem could occur if fopen() fails with ENFILE here

crun/src/libcrun/utils.c

Lines 1457 to 1459 in c07aadc

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

Maybe set_home_env() should take an err argument so that it is possible for the caller to differentiate between

  • no. home path was found in /etc/passwd
  • some other problems occured (for instance ENFILE or ENOMEM)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@eriksjolund this sounds good to me. I'm going to merge this PR as is though, as it fixes the issue #1998.

Feel free to a new PR, improving set_home_env error reporting.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... and also calling OOM in case setenv failed, in other places, like suggested above.

else
return 0;
}
}
}
Expand Down
Loading