*** Please type your report below this line *** The 1.3 tree version is due to my own packaging of the upstream develpment relese. Although I haven't verified that I believe the following problem is present with the current deb for the stable nut version. In any case I hope you will want to hear about it in advance. The problem is that when users set mesg to n they will not get ONBATT, ONLINE and other messages on their terminal because the child upsmon process is not run with root privileges. I find it unacceptable. Following a discussion that begins at http://lists.exploits.org/upsdev/Jun2003/00002.html it seems that the best soloution is to have a special rws--x--- root:nut /usr/bin/wall. Therefore, I suggest the following modifications to resolve the problem: 1. clients/upsmon.c: s/popen("wall"/popen("nutWall"/ 2. debian/control: add bsdutils to Build-Depends. 3. printf "usr/bin\n" >> debian/nut.dirs 3. debian/rules: - add install -m 4710 /usr/bin/wall \ $(PWD)/debian/nut/usr/bin/nutWall to the install target. - add -XnutWall to dh_fixperms in the binary-arch target. 4. nut.postinst: add /usr/bin/nutWall to the chown line that is already there. Regardless of that problem I suggest to have chmod 0770 $(PWD)/debian/nut/var/*/nut in the isntall target of debian/rules rather then in nut.postinst. This would make the maintainer scripts do a bit less, which I consider desirable. I believe that with this modification one must add -X/var to dh_fixperms in the binary-arch target of debian/rules. As an aside: why does the debconf information from below shows nothing? Trying to dpkg-reconfigure nut also does not give any debconf settings.
[ I am not nut's maintainer, its upstream, etc. I'm merely and interested user. ] I don't agree with you on this; however, I can certainly see why you'd want that behavior. So, I think it should be possible to easily configure that. Methinks a suid helper that calls wall would be much better. Avoids the problems below: That's very weird, and it could create some interesting dependencies (for example, depending on two different versions of glibc). I have no idea if that is allowed, or if it would even work. Oh, and installing it in /usr/bin violates policy --- it needs to go in /usr/lib/nut. But that's a minor point. It might be there to fix how old packages did it.
[ I am not nut's maintainer, its upstream, etc. I'm merely and interested user. ] I don't agree with you on this; however, I can certainly see why you'd want that behavior. So, I think it should be possible to easily configure that. Methinks a suid helper that calls wall would be much better. Avoids the problems below: That's very weird, and it could create some interesting dependencies (for example, depending on two different versions of glibc). I have no idea if that is allowed, or if it would even work. Oh, and installing it in /usr/bin violates policy --- it needs to go in /usr/lib/nut. But that's a minor point. It might be there to fix how old packages did it.
A problem with the UPS should made any user be prepared to exit his
online work in a hurry. I can hardly see how any user that isn't using
the system for fun can ignore those messages. Putting it otherwise,
/etc/upsmon.conf allows the system administrator to configure which
messages should be walled. Letting the user deny such messages is
actually overriding the manager of the system.
Do you mean a binary which will essentially be
int main(void)
{
FILE *wfp;
char buf[1024];
int n;
if (!(wf = popen("/usr/bin/wall", "w"))) return 1;
while (n = read(STDIN_FILNO, buf, 1024) > 0)
if write(fileno(wfp), buf, n) != n) return 2;
if (n < 0) return 3;
if write(wf, '\n', 1) != 1) return 2;
if (pclose(wfp) == -1) return 4;
return 0;
}
with permissions
rws--x--- root:nut nutWallWrapper
?
/usr/bin/nutWall works. As to the dependencies problem I don't follow
you. In the same vain you could have said that nut can not use wall as
well because of those problems, couldn't you? After all /usr/bin/nutWall
is an exact copy of /usr/bin/wall. It is even in the same directory.
I am not sure that the wrapper from above, as opposed to nutWall, is a
better solution. Although with it there is one less Build-Depends and it
does use a 2 pipe scheme: one pipe calls the wrapper and the other one
actually calls /usr/bin/wall. Under which directory in the source tree
would you put that wrapper?
Why /usr/bin/nutWall violates policy? Can't an arbitrary package
install executables in /usr/bin? Can you point the exact section of the
policy that is being violated? And why /usr/lib/nut? Is that another
requirement of the policy?
Still, why not
chmod 0770 $(PWD)/debian/nut/var/*/nut
in debian/rules rather then in debian/nut.postinst? This would only
leave the chmod to debian/nut.postinst. Even if old packages did it
otherwise I can't see the harm. And I do think that as much work as
possible should be taken out from the maintainer scripts and put in
debian rules.
Well, considering a 5-second power outage results in two wall's, I'm
pretty sure a lot of users might decide to turn it off.
And editors should respond sanely to the shutdown if the battery
becomes low.
Yeah, it is. So is chsh in that sense.
I can see there being situations where it is important that everyone be
notified. I can see situations where many users may not want
notification. That's why I think it should be configurable.
No --- that's far too complicated. A simple exec would suffice,
methinks.
int main(int argc, char *argv[]) {
exec("/usr/bin/wall", NULL);
}
/* untested */
/* could use execv and pass argv, but I don't think nut would want to
pass any arguments, and this way we prevent accidents with the file
argument. */
well, almost --- add a+r (policy section 11.9, if you care)
I'm saying that dpkg-shlibdeps may get confused if two binaries in the
same package require different versions of the same library. As an
example, here is how it could happen:
1) buildd builds wall w/ glibc 2.2.x
2) buildd maintainer installs glibc 2.3.x
3) buildd builds your proposed nut, now w/ glibc 2.3.x
Now the nut package contains binaries which use glibc 2.2.x (wall) and
2.3.x (everything else). I'm not sure what shlibdeps will do. I suspect
either bail out or produce some weird dependencies.
Also, should there be a bug in wall, the nut package surprisingly will
need rebuilding.
Ummm, it could go in debian/ for now. Or wherever upstream would like
it. It's one line of source (unless I've really missed something).
shell scripts.
"object files, libraries, and internal binaries that are not intended
to be executed directly by users or shell scripts." go in /usr/lib (see
the Filesystem Hierarchy Standard, section 4.4; incorporated by
reference into Debian Policy 10.1).
On my system, /usr/lib/nut already exists. "Applications may use a
single subdirectory under /usr/lib. If an application uses a
subdirectory, all architecture-dependent data exclusively used by the
application should be placed within that subdirectory." (FHS 4.4 again)
So, being an "internal binary" and being "exclusively used by the
application" it belongs in /usr/lib/nut.
Think how annoying it'd be if bash tab-completed random binaries used
only internally by applications. On one of my systems:
anthony@Maxwell:anthony$ find /usr/lib -type f -perm +a+x | wc -l
717
That means there would be an additional 700 or so useless binaries in
the search path.
BTW: When looking in /usr/lib, I see that amanda has a suid "runtar"
which I'm guessing is pretty similar to my proposed suid wrapper:
anthony@Maxwell:tmp$ ls -l /usr/lib/amanda/runtar
-rwsr-xr-- 1 root backup 4576 Apr 2 2002
/usr/lib/amanda/runtar
Because dpkg has a history of not managing to change the permissions on
existing directories when upgrading packages. I don't know if that
applies to nut or not. If it doesn't, I'd like to see the above change,
too.
No idea why it's not in debian/rules, though --- I'm not the maintainer.
Doesn't exec a shell builtin and, as such, it is not available here?
What file argument? My problem with passing arguments is that they may
restrict the length of the text to wall. Isn't there a restriction on
the length of the arguments to main? Yet I might be not realistic since
if the arguments to main are limited to 127 chars then it is not likely
that someone will want to wall a longer message then 127 chars.
Indeed, amanda Debian source package has client-src/run{dump,tar}.c
with an introduction comment saying that
* runs {DUMP,GNUTAR} program as root
execve is a kernel call. exec uses execve. Perhaps you're confused with system(), or perl's single-argument version of exec. read the wall manpage. Wall can take its message either from stdin or a file. If nut is compromised, I wouldn't want to see the suid helper used to read arbitrary files on the system (/etc/shadow, for example). Yes, though its something on the order of several kb. I think its defined somewhere in the kernel source.
I am confused. Doing
man exec
shows that actually you have
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg
, ..., char * const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
but no pure exec. In addition, you proposed
int main(int argc, char *argv[]) {
exec("/usr/bin/wall", NULL);
}
With this proposal, what message will get displayed? If I understand it
correctly, and according to wall man page, the stdin will get displayed.
However I fail to see where the stdin is connected to. And how will the
current wall function in clients/upsmon.c run the wrapper?
The way I see it, you don't use the file argument and you don't give
something in stdin. It will just hang, waiting for the desired message.
And suppose you solved that, why making the wrapper allocate dynamic
buffer to be later passed as argv when you can get read and write and
use a static buffer?
Here is what I currently have working here:
1. clients/upsmon.c:wall is as follows:
static void wall(const char *text)
{
FILE *wf;
wf = popen("/usr/lib/nut/wallWrapper", "w");
if (!wf) {
upslog(LOG_NOTICE, "Can't invoke wallWrapper");
return;
}
fprintf(wf, "%s\n", text);
if (pclose(wf) == -1)
upslog(LOG_NOTICE, "Invocation of wallWrapper was not smooth");
}
2. debian/wallWrapper.c is the following:
/* A wrapper for the wall (1) utility.
*
* The NUT uses wall, among other measures, to make announcements.
* However it usually doesn't run as root when those announcements are
* made. As a result, users who deny messages may miss those
* announcements even though the system administrator has specifically
* ask for them in upsmon.conf. To overcome this, the following is
* meant to be installed suid root while trimming all the other
* permission bits to a minimum.
*/
#include <stdio.h>
#include <unistd.h>
int main(void)
{
FILE *wf;
char buf[1024];
int n;
if (!(wf = popen("/usr/bin/wall", "w"))) return 1;
while ((n = read(STDIN_FILENO, buf, 1024)) > 0)
if (write(fileno(wf), buf, n) != n) return 2;
if (n < 0) return 3;
if (pclose(wf) == -1) return 4;
return 0;
}
3. debian/rules has the appropriate lines to compile and install the
wrapper.
Sounds like a bug in the manpage. Correct. Whatever it was connected to when the wrapper was run. Same way it runs wall, I'd guess. That's right. It will wait for the desired message, which nut will provide it. Just like nut provides wall.
According to the thread that begins with http://lists.debian.org/debian-user/2003/debian-user-200306/msg02622.html there is no bug here. Now I get it. Quoting libc info pages: File descriptors open in the existing process image remain open in the new process image, unless they have the `FD_CLOEXEC' (close-on-exec) flag set. The files that remain open inherit all attributes of the open file description from the existing process image, including file locks. File descriptors are discussed in *Note Low-Level I/O::. I have modified the suggested debian/wallWrapper.c to be: /* A wrapper for the wall (1) utility. * * The NUT might use wall, among other measures, to make announcements. * However it usually doesn't run as root when those announcements are * made. As a result, users who deny messages may miss those * announcements even though the system administrator has explicitly * ask for them in upsmon.conf. To overcome this, the following is * meant to be installed suid root while trimming all the other * permission bits to a minimum. */ #include <unistd.h> int main(void) { return execl("/usr/bin/wall", "/usr/bin/wall", NULL); } and it is working. Yet I still don't have a clue about the following comment in popen man page: BUGS Since the standard input of a command opened for reading shares its seek offset with the process that called popen(), if the original process has done a buffered read, the command's input position may not be as expected. Similarly, the output from a command opened for writing may become intermingled with that of the original process. The latter can be avoided by calling fflush(3) before popen.
Hmmm, guess that's what I get for looking on a BSD system first time :-( http://www.opengroup.org/onlinepubs/007908799/xsh/exec.html agrees. That's fine. If you do a C-library read from stdin, then popen a process which also reads from stdin, unexpected things may occur. That's because the C library may read additional data (buffering) from stdin. IOW, you have to use read(2), not fread(3). Yep. Data written to a buffered file (e.g., fwrite) may not be immediately written. If you do a fwrite to stdout, then do a popen, all or part of your fwrite may happen _after_ the output of the popen'd command. By using fflish, you can force the buffered data to be written before running the command.
Hi Karl,
Shaul Karl wrote:
As Russell point me out, I may have be too quick to answer
about no solution. In fact, Russell is thinking about such
a things for few months. He has released some basic
concepts in nut-1.5.3 (not sure before?!) docs/ideas.txt:
---
Chrooted upsmon
===============
upsmon could run the network monitoring part in a chroot jail if it had
a pipe to another process running outside for NOTIFY dispatches. Such a
pipe would have to be constructed extremely carefully so an attacker
could not compromise it from the jailed process.
A state machine with a tightly defined sequence could do this safely.
All it has to do is dispatch the UPS name and event type.
[start] [type] [length] <name> [stop]
---
Here is an excerpt of Russell's mail which details this idea:
---
Arnaud Quette wrote:
that's linked with an anonymous pipe back to the unprivileged network
process. That third process would do nothing more than send
notifications.
I came up with this idea in the past 6 months while pondering how
something like upsmon could be chrooted sanely. It was written up in the
ideas.txt that went out with the last couple of 1.5 releases.
Assuming that was written, it would look like this:
- #1: root, unchrooted, waiting for the shutdown command on pipe from #1
- #2: nutmon, chrooted, talks on the network to upsd, has pipes to #1/#3
- #3: root or nutmon, unchrooted, listens for notify events on pipe from #2
The trick would be making sure that #2 could not exploit #3 across that
pipe. As mentioned in ideas.txt, it could be done with a tightly defined
state machine.
The state machine would not be too difficult. It would expect a start
marker, a valid notify type, a valid length byte, then <length>
characters, followed by an end marker. If it gets anything else at any
other stage, then it jumps to a state where it waits for the end marker,
ignoring anything that was sent. It only uses the data from the pipe if
it makes it all the way to the end marker without anything bad happening.
Once it has safe data, then it can build a call to the NOTIFYCMD or wall
and fork/exec it. That's where the system-level policy comes in. If you
need it to run as root to be able to talk to ttys and ptys, then you just
have that third process run as root. Nothing is totally secure, but I
think it would be very difficult to break something like this.
This is all very complicated to solve what should be a simple matter.
---
As it's in ideas.txt, and not in todo.txt, you can imagine that it's not
for now...
But the idea (and some code) is there, and it would close this bug when
available!
So we have 2 solutions:
1) Document the problem in both NUT and Debian Readme, pointing
ideas.txt. We can then safely close the bug.
2) let the bug opened until this feature is released!
I'm obviously for the first. But I can't take this decision.
@Luca: please, advice.
One more thanks to Russell Kroll.
Arnaud
Hello Dear My wife Violet and I Allen Large won 11.2M USD in a lottery 6-49 in July, 2010 and we have decided to donate the sum of 2M USD to you as part of our charity project. Contact us via our personal email for more details. You can verify this by visiting the web pages below. http://www.bbc.co.uk/news/world-us-canada-11699678 Good Luck, Allen & Violet Large.
Sou o advogado Kouevi A. Remy, estou entrando em contato com você a respeito da morte do meu falecido cliente, que você tem o mesmo sobrenome. Ele era meu cliente antes de sua morte, deixando uma certa quantia de dinheiro, US $ 7,5 milhões no banco. Depois de uma tentativa malsucedida de encontrar seu parente, decidi entrar em contato com você para ser seu único parente próximo para reivindicar os fundos, então nós compartilhamos. Se você estiver interessado, entre em contato comigo para que possamos fornecer mais esclarecimentos e procedimentos de pagamento. Obrigado.
שלום ערב טוב, אנא התקשר אליי עכשיו או השב למייל ששלחתי לך מאתמול