fix HOME env of container unset error
Signed-off-by: haozi007 <liuhao27@huawei.com>
This commit is contained in:
parent
dac758fcca
commit
06e431b233
316
0009-fix-HOME-env-of-container-unset-error.patch
Normal file
316
0009-fix-HOME-env-of-container-unset-error.patch
Normal file
@ -0,0 +1,316 @@
|
||||
From 043b2483585a2d8168e0fde8b37054733a31f263 Mon Sep 17 00:00:00 2001
|
||||
From: haozi007 <liuhao27@huawei.com>
|
||||
Date: Mon, 25 Jul 2022 15:36:23 +0800
|
||||
Subject: [PATCH] fix HOME env of container unset error
|
||||
|
||||
Signed-off-by: haozi007 <liuhao27@huawei.com>
|
||||
---
|
||||
src/lxc/isulad_utils.c | 210 ++++++++++++++++++++++++++++++++++++++++-
|
||||
src/lxc/isulad_utils.h | 3 +
|
||||
src/lxc/start.c | 14 +--
|
||||
3 files changed, 216 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/src/lxc/isulad_utils.c b/src/lxc/isulad_utils.c
|
||||
index 15d9323..cd7fca8 100644
|
||||
--- a/src/lxc/isulad_utils.c
|
||||
+++ b/src/lxc/isulad_utils.c
|
||||
@@ -6,6 +6,10 @@
|
||||
* Create: 2020-04-11
|
||||
******************************************************************************/
|
||||
|
||||
+#ifndef _GNU_SOURCE
|
||||
+#define _GNU_SOURCE 1
|
||||
+#endif
|
||||
+
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
@@ -13,6 +17,10 @@
|
||||
#include <fcntl.h>
|
||||
#include <pwd.h>
|
||||
#include <ctype.h>
|
||||
+#include <stdio.h>
|
||||
+#include <unistd.h>
|
||||
+#include <errno.h>
|
||||
+#include <stdio_ext.h>
|
||||
|
||||
#include "isulad_utils.h"
|
||||
#include "log.h"
|
||||
@@ -244,20 +252,34 @@ out:
|
||||
// isulad: set env home in container
|
||||
int lxc_setup_env_home(uid_t uid)
|
||||
{
|
||||
+#define __PASSWD_FILE__ "/etc/passwd"
|
||||
char *homedir = "/"; // default home dir is /
|
||||
+ FILE *stream = NULL;
|
||||
struct passwd pw, *pwbufp = NULL;
|
||||
char buf[BUFSIZ];
|
||||
- int ret;
|
||||
|
||||
- ret = getpwuid_r(uid, &pw, buf, sizeof(buf), &pwbufp);
|
||||
- if ((ret == 0) && (pwbufp != NULL) && (pwbufp->pw_uid == uid)) {
|
||||
- homedir = pwbufp->pw_dir;
|
||||
+ stream = fopen_cloexec(__PASSWD_FILE__, "r");
|
||||
+ if (stream == NULL) {
|
||||
+ SYSWARN("Failed to open %s", __PASSWD_FILE__);
|
||||
goto set_env;
|
||||
}
|
||||
|
||||
+#if IS_BIONIC
|
||||
+ while (util_getpwent_r(stream, &pw, buf, sizeof(buf), &pwbufp) == 0 && pwbufp != NULL) {
|
||||
+#else
|
||||
+ while (fgetpwent_r(stream, &pw, buf, sizeof(buf), &pwbufp) == 0 && pwbufp != NULL) {
|
||||
+#endif
|
||||
+ if (pwbufp->pw_uid == uid) {
|
||||
+ homedir = pwbufp->pw_dir;
|
||||
+ goto set_env;
|
||||
+ }
|
||||
+ }
|
||||
WARN("User invalid, can not find user '%u'", uid);
|
||||
|
||||
set_env:
|
||||
+ if (stream)
|
||||
+ fclose(stream);
|
||||
+
|
||||
// if we didn't configure HOME, set it based on uid
|
||||
if (setenv("HOME", homedir, 0) < 0) {
|
||||
SYSERROR("Unable to set env 'HOME'");
|
||||
@@ -317,3 +339,183 @@ bool is_non_negative_num(const char *s)
|
||||
}
|
||||
return true;
|
||||
}
|
||||
+
|
||||
+static int hold_int(const char delim, bool required, char **src, unsigned int *dst)
|
||||
+{
|
||||
+ unsigned long long int res = 0;
|
||||
+ char *err_str = NULL;
|
||||
+
|
||||
+ // ensure *src not a empty string
|
||||
+ if (**src == '\0') {
|
||||
+ ERROR("Empty subject on given entrie is not allowed.");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ errno = 0;
|
||||
+ // covert string to long long
|
||||
+ res = strtoull(*src, &err_str, 0);
|
||||
+ if (errno != 0 && errno != ERANGE) {
|
||||
+ ERROR("Parse int from string failed.");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ // **src is not a digit
|
||||
+ if (err_str == *src) {
|
||||
+ if (!required) {
|
||||
+ ERROR("Integer part is missing.");
|
||||
+ return -1;
|
||||
+ }
|
||||
+ // if required, just set 0
|
||||
+ *dst = 0;
|
||||
+ } else {
|
||||
+ if (sizeof(void *) > 4 && res > UINT_MAX) { // make sure 64-bit platform behave same as 32-bit
|
||||
+ res = UINT_MAX;
|
||||
+ }
|
||||
+ res = res & UINT_MAX;
|
||||
+ *dst = (uint32_t)res;
|
||||
+ }
|
||||
+
|
||||
+ // normal case
|
||||
+ if (*err_str == delim) {
|
||||
+ err_str++;
|
||||
+ } else if (*err_str != '\0') {
|
||||
+ ERROR("Invalid digit string.");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ *src = err_str; // update src to next valid context in line.
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void hold_string(const char delim, char **src, char **dst)
|
||||
+{
|
||||
+ for (*dst = *src; **src != delim; ++(*src)) {
|
||||
+ if (**src == '\0') {
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (**src == delim) {
|
||||
+ **src = '\0';
|
||||
+ ++(*src);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int parse_line_pw(const char delim, char *line, struct passwd *result)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+ bool required = false;
|
||||
+ char *walker = NULL;
|
||||
+
|
||||
+ walker = strpbrk(line, "\n");
|
||||
+ if (walker != NULL) {
|
||||
+ // clear newline char
|
||||
+ *walker = '\0';
|
||||
+ }
|
||||
+
|
||||
+ hold_string(delim, &line, &result->pw_name);
|
||||
+
|
||||
+ required = (result->pw_name[0] == '+' || result->pw_name[0] == '-') ? true : false;
|
||||
+
|
||||
+ hold_string(delim, &line, &result->pw_passwd);
|
||||
+
|
||||
+ ret = hold_int(delim, required, &line, &result->pw_uid);
|
||||
+ if (ret != 0) {
|
||||
+ // a legitimate line must have uid
|
||||
+ ERROR("Parse uid error.");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = hold_int(delim, required, &line, &result->pw_gid);
|
||||
+ if (ret != 0) {
|
||||
+ // it's ok to not provide gid
|
||||
+ ERROR("Parse gid error.");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ hold_string(delim, &line, &result->pw_gecos);
|
||||
+
|
||||
+ hold_string(delim, &line, &result->pw_dir);
|
||||
+
|
||||
+ result->pw_shell = line;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+char *util_left_trim_space(char *str)
|
||||
+{
|
||||
+ char *begin = str;
|
||||
+ char *tmp = str;
|
||||
+ while (isspace(*begin)) {
|
||||
+ begin++;
|
||||
+ }
|
||||
+ while ((*tmp++ = *begin++)) {
|
||||
+ }
|
||||
+ return str;
|
||||
+}
|
||||
+
|
||||
+int util_getpwent_r(FILE *stream, struct passwd *resbuf, char *buffer, size_t buflen, struct passwd **result)
|
||||
+{
|
||||
+ const char delim = ':';
|
||||
+ char *buff_end = NULL;
|
||||
+ char *walker = NULL;
|
||||
+ bool got = false;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ if (stream == NULL || resbuf == NULL || buffer == NULL || result == NULL) {
|
||||
+ ERROR("Password obj, params is NULL.");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if (buflen <= 1) {
|
||||
+ ERROR("Inadequate buffer length was given.");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ buff_end = buffer + buflen - 1;
|
||||
+ flockfile(stream);
|
||||
+
|
||||
+ while (1) {
|
||||
+ *buff_end = '\xff';
|
||||
+ walker = fgets_unlocked(buffer, buflen, stream);
|
||||
+ // if get NULL string
|
||||
+ if (walker == NULL) {
|
||||
+ *result = NULL;
|
||||
+ // reach end of file, return error
|
||||
+ if (feof(stream)) {
|
||||
+ ret = ENOENT;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ // overflow buffer
|
||||
+ ret = ERANGE;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ // just overflow last char in buffer
|
||||
+ if (*buff_end != '\xff') {
|
||||
+ *result = NULL;
|
||||
+ ret = ERANGE;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ (void)util_left_trim_space(buffer);
|
||||
+ // skip comment line and empty line
|
||||
+ if (walker[0] == '#' || walker[0] == '\0') {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (parse_line_pw(delim, walker, resbuf) == 0) {
|
||||
+ got = true;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ if (!got) {
|
||||
+ *result = NULL;
|
||||
+ ret = ERANGE;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ *result = resbuf;
|
||||
+ ret = 0;
|
||||
+out:
|
||||
+ funlockfile(stream);
|
||||
+ return ret;
|
||||
+}
|
||||
\ No newline at end of file
|
||||
diff --git a/src/lxc/isulad_utils.h b/src/lxc/isulad_utils.h
|
||||
index 345f511..7a5eb89 100644
|
||||
--- a/src/lxc/isulad_utils.h
|
||||
+++ b/src/lxc/isulad_utils.h
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
+#include <pwd.h>
|
||||
|
||||
/* isulad: replace space with SPACE_MAGIC_STR */
|
||||
#define SPACE_MAGIC_STR "[#)"
|
||||
@@ -96,4 +97,6 @@ extern bool lxc_process_alive(pid_t pid, unsigned long long start_time);
|
||||
|
||||
extern bool is_non_negative_num(const char *s);
|
||||
|
||||
+int util_getpwent_r(FILE *stream, struct passwd *resbuf, char *buffer, size_t buflen, struct passwd **result);
|
||||
+
|
||||
#endif
|
||||
diff --git a/src/lxc/start.c b/src/lxc/start.c
|
||||
index f82df34..6fe1203 100644
|
||||
--- a/src/lxc/start.c
|
||||
+++ b/src/lxc/start.c
|
||||
@@ -1727,6 +1727,13 @@ static int do_start(void *data)
|
||||
new_uid = handler->conf->init_uid;
|
||||
new_gid = handler->conf->init_gid;
|
||||
|
||||
+#ifdef HAVE_ISULAD
|
||||
+ // isulad: set env home in container, must before "Avoid unnecessary syscalls."
|
||||
+ if (lxc_setup_env_home(new_uid) < 0) {
|
||||
+ goto out_warn_father;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
/* Avoid unnecessary syscalls. */
|
||||
if (new_uid == nsuid)
|
||||
new_uid = LXC_INVALID_UID;
|
||||
@@ -1734,13 +1741,6 @@ static int do_start(void *data)
|
||||
if (new_gid == nsgid)
|
||||
new_gid = LXC_INVALID_GID;
|
||||
|
||||
-#ifdef HAVE_ISULAD
|
||||
- // isulad: set env home in container
|
||||
- if (lxc_setup_env_home(new_uid) < 0) {
|
||||
- goto out_warn_father;
|
||||
- }
|
||||
-#endif
|
||||
-
|
||||
/* Make sure that the processes STDIO is correctly owned by the user that we are switching to */
|
||||
ret = fix_stdio_permissions(new_uid);
|
||||
if (ret)
|
||||
--
|
||||
2.25.1
|
||||
|
||||
9
lxc.spec
9
lxc.spec
@ -1,4 +1,4 @@
|
||||
%global _release 2022072104
|
||||
%global _release 2022072501
|
||||
|
||||
Name: lxc
|
||||
Version: 4.0.3
|
||||
@ -16,6 +16,7 @@ Patch0005: 0005-refactor-patch-code-of-attach-and-seccomp.patch
|
||||
Patch0006: 0006-refactor-patch-about-namespace-log-terminal.patch
|
||||
Patch0007: 0007-refactor-patches-on-terminal.c-start.c-and-so-on.patch
|
||||
Patch0008: 0008-refactor-patch-code-of-json.patch
|
||||
Patch0009: 0009-fix-HOME-env-of-container-unset-error.patch
|
||||
|
||||
BuildRequires: systemd-units git libtool graphviz docbook2X doxygen chrpath
|
||||
BuildRequires: pkgconfig(libseccomp)
|
||||
@ -187,6 +188,12 @@ make check
|
||||
%{_mandir}/*/man7/%{name}*
|
||||
|
||||
%changelog
|
||||
* Mon Jul 25 2022 haozi007<liuhao27@huawei.com> - 4.0.3-2022072501
|
||||
- Type:bugfix
|
||||
- ID:NA
|
||||
- SUG:NA
|
||||
- DESC: fix HOME env unset error
|
||||
|
||||
* Thu Jul 21 2022 zhangxiaoyu<zhangxiaoyu58@huawei.com> - 4.0.3-2022072104
|
||||
- Type:bugfix
|
||||
- ID:NA
|
||||
|
||||
@ -6,4 +6,4 @@
|
||||
0006-refactor-patch-about-namespace-log-terminal.patch
|
||||
0007-refactor-patches-on-terminal.c-start.c-and-so-on.patch
|
||||
0008-refactor-patch-code-of-json.patch
|
||||
|
||||
0009-fix-HOME-env-of-container-unset-error.patch
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user