Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

opkg: return 255 when using Luci and Lighttpd to install software packages #1922

Closed
alzhao opened this issue Nov 6, 2015 · 24 comments
Closed
Assignees

Comments

@alzhao
Copy link

alzhao commented Nov 6, 2015

When using Luci and uhttpd, it works fine. But when using Lighttpd, there will be "status 255" errors when you install anything from the web UI.

Collected errors: * pkg_run_script: package "socat" postinst script returned status 255. * opkg_configure: socat.postinst returned 255.

There is no problem to install via shell.
Similar problems are found by others: https://forum.openwrt.org/viewtopic.php?id=56953

This was no such issues in BB1407.

@gstrauss
Copy link
Contributor

gstrauss commented Jan 5, 2017

@alzhao is this still an issue for you?

@alzhao
Copy link
Author

alzhao commented Jan 5, 2017 via email

@gstrauss
Copy link
Contributor

gstrauss commented Jan 5, 2017

I'm willing to look into it if more info can be provided, such as any info in lighttpd error.log or breakage.log, or any other info as to why socat.postinst (or other scripts) are getting errors from 'something' and therefore exiting 255. I do not currently have an openwrt environment set up.

@alzhao
Copy link
Author

alzhao commented Feb 24, 2017

I can send you one router and you play with it. OK?

@gstrauss
Copy link
Contributor

Sure. I am up for that. Please email me privately (email on my github page https://github.com/gstrauss)

The issue might be related to startup scripts restarting lighttpd. See also discussion in pi-hole/pi-hole#945

@gstrauss
Copy link
Contributor

gstrauss commented Mar 2, 2017

I got my hands on some sacrificial hardware and installed openwrt 15.05.1. I was able to reproduce the problem. lighttpd (intentionally) clears the environment when running CGI scripts, including PATH. Therefore PATH is the default in the shell when PATH is not set, usually "/bin:/usr/bin" or something like that, but apparently that not what /bin/opkg expects, and opkg fails to execute some commands.

strace found that opkg tried to execve() "(null)/sh"

execve("(null)/sh", ["sh", "-c", "//usr/lib/opkg/info/libuuid.postinst configure"], [/* 35 vars */]) = -1 ENOENT (No such file or directory)

This is something that should be fixed in opkg ("(null)/sh" is obviously wrong). However, since LuCI intends to do root-level things, LuCI itself ought to check for the presence of /usr/sbin:/sbin in PATH, and ought to set a reasonable PATH (for LuCI) if one is not present.

So, both opkg and LuCI ought to get some patches.

In the meantime, https://redmine.lighttpd.net/projects/lighttpd/wiki/Docs_ModCGI section "PATH environment variable" suggests using mod_setenv (opkg install lighttpd-mod-setenv) and configuring /etc/lighttpd/conf.d/30-setenv.conf with

server.modules += ( "mod_setenv" )
setenv.add-environment = ( "PATH" => "/sbin:/usr/sbin:/bin:/usr/bin" )

(updated example above per @alzhao comment below)

@alzhao
Copy link
Author

alzhao commented Mar 2, 2017

@gstrauss Thanks. I just tried to add setenv to lighttpd and it works. However the correct syntax is the following:
setenv.add-environment = ( "PATH" => "/sbin:/usr/sbin:/bin:/usr/bin" )
Just cannot believe lighttpd docs just contains such errors.

Will you be able to make the patches for opkg and luci?

@gstrauss
Copy link
Contributor

gstrauss commented Mar 2, 2017

@alzhao Thx for the correction. FYI: the lighttpd wiki doc contained that error only for a few hours, as I had made the changes earlier today. They have been updated, too.

@alzhao
Copy link
Author

alzhao commented Mar 2, 2017

@gstrauss sorry I am aware you are lighttpd developer and just modified that. I thought that was a well managed wiki. Thanks very much for your help!

@gstrauss
Copy link
Contributor

gstrauss commented Mar 2, 2017

See openwrt/luci#1048 for pull request I submitted to openwrt/luci repo.

I do not have further time at the moment to look into a similar fix for opkg, but openwrt/luci#1048 also applies to opkg when LuCI CGI calls opkg

@gstrauss
Copy link
Contributor

gstrauss commented Mar 2, 2017

Actual source of the problem isolated in opkg. opkg_prep_intercepts() calls getenv("PATH") and then uses the returned value in string concatenation without checking if getenv("PATH") returned NULL. Some newer libc *sprintf() implementations replace NULL with the "(null)". (Other implementations may crash dereferencing NULL ptr.)

Later, in opkg_finalize_intercepts(), setenv() is called to set PATH and, again, a NULL value is passed (instead of using unsetenv() if original PATH was NULL). This setenv() might fail (or crash) when copying the value (NULL), though that is implementation-dependent.

execvp() has special behavior if PATH is unset, but after opkg_prep_intercepts(), PATH is no longer unset in the environment, and can be considered undefined behavior.

I'll submit some patches upstream to the opkg-devel mailing list on googlegroups.com.

@hnyman
Copy link
Contributor

hnyman commented Mar 2, 2017

I'll submit some patches upstream to the opkg-devel mailing list on googlegroups.com.

Not much use, as Openwrt and LEDE use an ancient version of opkg due to size constraints...

But @jow- is writing a new opkg-lede version for LEDE in https://git.lede-project.org/?p=project/opkg-lede.git , so you might check the path handling there.

@gstrauss
Copy link
Contributor

gstrauss commented Mar 2, 2017

Thanks @hnyman. The patch submission procedure to opkg is not as fluid as it is for github projects. Also, there's not a clear CONTRIBUTING procedure in https://git.lede-project.org/?p=project/opkg-lede.git, so I'll just post some patches below, and hopefully @jow- will see them. The fork appears to be based off opkg-0.2.x branch instead of master of http://git.yoctoproject.org/git/opkg, and the fork contains the same PATH handling issue when PATH is not set in the environment.

From: Glenn Strauss <gstrauss@gluelogic.com>
Date: Thu, 2 Mar 2017 16:20:27 -0500
Subject: [opkg-0.2.x PATCH] libopkg/opkg_cmd.c: more robust PATH handling
To: opkg-devel@googlegroups.com

preserve semantics of PATH when PATH is not set in environment

error and undefined behavior reported in
  https://github.com/openwrt/packages/issues/1922
when PATH not set in environment
(lighttpd executes CGI with empty base env, plus standard CGI env vars)

Signed-off-by: Glenn Strauss <gstrauss@gluelogic.com>
---
 libopkg/opkg_cmd.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/libopkg/opkg_cmd.c b/libopkg/opkg_cmd.c
index 567dfb1..6bdb7d9 100644
--- a/libopkg/opkg_cmd.c
+++ b/libopkg/opkg_cmd.c
@@ -257,11 +257,13 @@ static opkg_intercept_t
 opkg_prep_intercepts(void)
 {
     opkg_intercept_t ctx;
+    const char *oldpath;
     char *newpath;
 
     ctx = xcalloc(1, sizeof (*ctx));
     ctx->oldpath = xstrdup(getenv("PATH"));
-    sprintf_alloc(&newpath, "%s/opkg/intercept:%s", DATADIR, ctx->oldpath);
+    oldpath = ctx->oldpath ? ctx->oldpath : "/usr/sbin:/usr/bin:/sbin:/bin";
+    sprintf_alloc(&newpath, "%s/opkg/intercept:%s", DATADIR, oldpath);
     sprintf_alloc(&ctx->statedir, "%s/opkg-intercept-XXXXXX", conf->tmp_dir);
 
     if (mkdtemp(ctx->statedir) == NULL) {
@@ -286,7 +288,10 @@ opkg_finalize_intercepts(opkg_intercept_t ctx)
     DIR *dir;
     int err = 0;
 
-    setenv ("PATH", ctx->oldpath, 1);
+    if (ctx->oldpath)
+        setenv("PATH", ctx->oldpath, 1);
+    else
+        unsetenv("PATH");
     free (ctx->oldpath);
 
     dir = opendir (ctx->statedir);
-- 
2.9.3

From: Glenn Strauss <gstrauss@gluelogic.com>
Date: Thu, 2 Mar 2017 03:18:30 -0500
Subject: [opkg-0.2.x PATCH] libopkg: specify "/bin/sh" instead of "sh"
To: opkg-devel@googlegroups.com

avoid strange behavior with execvp() when PATH is not set in environment
(in which case confstr(_CS_PATH) should return something reasonable)

reproducable running openwrt 15.05 and 15.05.1 and attempting to install
a software package (e.g. libuuid) via LuCI (prior to openwrt/luci#1048).
(https://github.com/openwrt/luci/pull/1048) libuuid.postinst fails with
status 255 on 15.05 and opkg segfaults in 15.05.1.  This probably merits
further exploration.

Originally reported in https://github.com/openwrt/packages/issues/1922

Signed-off-by: Glenn Strauss <gstrauss@gluelogic.com>
---
 libopkg/opkg_cmd.c | 2 +-
 libopkg/pkg.c      | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/libopkg/opkg_cmd.c b/libopkg/opkg_cmd.c
index 567dfb1..d9b8762 100644
--- a/libopkg/opkg_cmd.c
+++ b/libopkg/opkg_cmd.c
@@ -300,7 +300,7 @@ opkg_finalize_intercepts(opkg_intercept_t ctx)
 
 	    sprintf_alloc (&path, "%s/%s", ctx->statedir, de->d_name);
 	    if (access (path, X_OK) == 0) {
-		const char *argv[] = {"sh", "-c", path, NULL};
+		const char *argv[] = {"/bin/sh", "-c", path, NULL};
 		xsystem (argv);
 	    }
 	    free (path);
diff --git a/libopkg/pkg.c b/libopkg/pkg.c
index 7c0cf99..d471d19 100644
--- a/libopkg/pkg.c
+++ b/libopkg/pkg.c
@@ -1297,7 +1297,7 @@ pkg_run_script(pkg_t *pkg, const char *script, const char *args)
      sprintf_alloc(&cmd, "%s %s", path, args);
      free(path);
      {
-	  const char *argv[] = {"sh", "-c", cmd, NULL};
+	  const char *argv[] = {"/bin/sh", "-c", cmd, NULL};
 	  err = xsystem(argv);
      }
      free(cmd);
-- 
2.9.3

@hnyman hnyman changed the title return 255 when using Luci and Lighttpd to install software packages opkg: return 255 when using Luci and Lighttpd to install software packages Mar 3, 2017
@jow-
Copy link
Contributor

jow- commented Mar 15, 2017

@gstrauss
Copy link
Contributor

@jow- can this issue be closed after the patches you applied? Or what needs to be done to make these libopkg patches available to chaos-calmer?

@jow-
Copy link
Contributor

jow- commented Apr 10, 2017

No idea about Chaos Calmer, I am not sure who takes care of backporting them there

@gstrauss
Copy link
Contributor

@hnyman mentioned:

Not much use, as Openwrt and LEDE use an ancient version of opkg due to size constraints..."

One workaround would be backporting the patch in openwrt/luci#1048 to have cgi-bin/luci set PATH.

@gstrauss
Copy link
Contributor

gstrauss commented May 3, 2017

@jow- rejected the patch in openwrt/luci#1048

Please note that we still have a broken opkg in Chaos Calmer 15.05.1 -- the current openwrt binary release -- and subsequently a broken luci interface to opkg.

@jow- wrote above:

No idea about Chaos Calmer, I am not sure who takes care of backporting them there

@diizzyy
Copy link
Contributor

diizzyy commented Jun 7, 2017

@thess @hnyman
Please close, rejected my maintainer and 15.05.1 is obsolete/unsupported now.

@gstrauss
Copy link
Contributor

gstrauss commented Jun 7, 2017

@Diizzy, 15.05.1 is not obsolete, is it? It is still the target download at https://downloads.openwrt.org/

@diizzyy
Copy link
Contributor

diizzyy commented Jun 7, 2017

@gstrauss It's been superseded by LEDE (www.lede-project.org)

@gstrauss
Copy link
Contributor

gstrauss commented Jun 8, 2017

@diizzyy it is true that 15.05.1 is no longer latest (latest is LEDE 17.01.1), but let's not mislead those who read this ticket: https://openwrt.org/ notes in a link to http://lists.infradead.org/pipermail/lede-dev/2017-May/007336.html that OpenWRT and LEDE projects are planning to merge, and to maintain the OpenWRT name.

It would have been nice to existing users if any of my fixes (patches above to opkg, and openwrt/luci#1048 for LuCI) made it into 15.05.1, but since it appears maintainers are no longer supporting 15.05, I guess this can be closed. The opkg patches above were merged into LEDE in March, so I believe the fixes to this issue made it into LEDE 17.01.1

@diizzyy
Copy link
Contributor

diizzyy commented Jun 13, 2017

@gstrauss
It's not maintained/supported, please test the latest LEDE release instead. I'm not going into the politics about the split but the remaining OpenWrt team has decided to ignore/not mention LEDE leaving their users in a rather bad situation. There's still a bit of sour lemon for some when you "redirect" OpenWrt uses to LEDE on irc/forums and I doubt you'll see any mentioning about it on the main page.

mmatuska pushed a commit to mmatuska/opkg that referenced this issue Aug 3, 2018
avoid strange behavior with execvp() when PATH is not set in environment
(in which case confstr(_CS_PATH) should return something reasonable)

reproducable running openwrt 15.05 and 15.05.1 and attempting to install
a software package (e.g. libuuid) via LuCI (prior to openwrt/luci#1048).
(openwrt/luci#1048) libuuid.postinst fails with
status 255 on 15.05 and opkg segfaults in 15.05.1.  This probably merits
further exploration.

Originally reported in openwrt/packages#1922

Signed-off-by: Glenn Strauss <gstrauss@gluelogic.com>
mmatuska pushed a commit to mmatuska/opkg that referenced this issue Aug 3, 2018
preserve semantics of PATH when PATH is not set in environment

error and undefined behavior reported in
  openwrt/packages#1922
when PATH not set in environment
(lighttpd executes CGI with empty base env, plus standard CGI env vars)

Signed-off-by: Glenn Strauss <gstrauss@gluelogic.com>
[Jo-Philipp Wich: avoid free() on NULL, use default from cmake cache string]
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
@dibdot
Copy link
Contributor

dibdot commented Aug 17, 2018

Seems to be fixed in OpenWrt nowadays.

@dibdot dibdot closed this as completed Aug 17, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants