|
Home > Archive > Unix Programming > January 2005 > deamonizing a program in Unix
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
deamonizing a program in Unix
|
|
| Pappan 2005-01-04, 5:59 pm |
| Hi all
I have query regarding deamonizing programs in unix.
Usually we do a close of all file descriptors in a loop for
deamonizing. Is this correct?
What if some backend(such as NIS) has cached an file descriptor for
performance issue because of function call before we do deamonizing and
after that during deamonizing since we close all the file descriptors
we are closing the file descriptor opened by the backend also. Is this
correct behaviour of a deamoonizing programs?
Also where can i get the source of daemon() function call?
Any pointers would be helpful
Thanks
Pappan
| |
| Rich Teer 2005-01-04, 5:59 pm |
| On Tue, 4 Jan 2005, Pappan wrote:
> Usually we do a close of all file descriptors in a loop for
> deamonizing. Is this correct?
Yep. Well, you close all the file descriptors you're not using,
which isn't necessarily ALL of them...
> What if some backend(such as NIS) has cached an file descriptor for
> performance issue because of function call before we do deamonizing and
> after that during deamonizing since we close all the file descriptors
> we are closing the file descriptor opened by the backend also. Is this
??? How does one program using a file descriptor affect how you use
it in another?
> Also where can i get the source of daemon() function call?
> Any pointers would be helpful
The example source code for my book, Solaris Systems Programming,
contains a suitable function. You can find the source code (and
much more) from www.rite-group.com/rich/ssp.
HTH,
--
Rich Teer, SCNA, SCSA, author of "Solaris Systems Programming"
. * * . * .* .
. * . .*
President, * . . /\ ( . . *
Rite Online Inc. . . / .\ . * .
.*. / * \ . .
. /* o \ .
Voice: +1 (250) 979-1638 * '''||''' .
URL: http://www.rite-online.net ******************
| |
| joe@invalid.address 2005-01-04, 5:59 pm |
| "Pappan" <padmanabhanp@fastmail.fm> writes:
> I have query regarding deamonizing programs in unix.
>
> Usually we do a close of all file descriptors in a loop for
> deamonizing. Is this correct?
It might be. Depends on your requirements. For example, a daemon that
spawns other programs would probably want to leave descriptors 0, 1
and 2 open, but pointing to /dev/null.
> What if some backend(such as NIS) has cached an file descriptor for
> performance issue because of function call before we do deamonizing
> and after that during deamonizing since we close all the file
> descriptors we are closing the file descriptor opened by the backend
> also. Is this correct behaviour of a deamoonizing programs?
I didn't understand this. Can you rephrase?
> Also where can i get the source of daemon() function call?
> Any pointers would be helpful
You can get the source code in Stevens' "Advanced programming the UNIX
Environment" at http://www.kohala.com/start/apue.html. It has a daemon
function in it. Also see
http://www.faqs.org/faqs/unix-faq/programmer/faq/
Look for question 1.7 and the example section at the end.
Joe
| |
| Lew Pitcher 2005-01-04, 5:59 pm |
| -----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Pappan wrote:
> Hi all
> I have query regarding deamonizing programs in unix.
>
> Usually we do a close of all file descriptors in a loop for
> deamonizing. Is this correct?
Usually, but not always. Certainly, you normally want to close and
discard the controlling terminal, and you usually want to close any
'unused' file descriptors (i.e. descriptors that might have been left
open by the process that exec'ed your daemon), but closing any other
descriptors is something that you do if you want or need to, not because
you have to.
> What if some backend(such as NIS) has cached an file descriptor for
> performance issue because of function call before we do deamonizing and
> after that during deamonizing since we close all the file descriptors
> we are closing the file descriptor opened by the backend also. Is this
> correct behaviour of a deamoonizing programs?
I'm not sure I understand your scenario here. Could you explain it in
simpler terms? FWIW, if you suspect that a descriptor has been cached,
and that closing the descriptor will cause problems, you don't /have/ to
close the descriptor.
> Also where can i get the source of daemon() function call?
> Any pointers would be helpful
You can take a look at this helpfull page...
http://www.enderunix.org/docs/eng/daemon.php
- --
Lew Pitcher, IT Consultant, Enterprise Data Systems
Enterprise Technology Solutions, TD Bank Financial Group
(Opinions expressed here are my own, not my employer's)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (MingW32)
iD8DBQFB2uPKagVFX4UWr64RApDJAJ9HWamZrSCt
uNznrK9ErE1ukbb34gCg8XBj
ljlZFAylWWidFUwSvFGN+O4=
=xnZs
-----END PGP SIGNATURE-----
| |
| Alex Fraser 2005-01-04, 5:59 pm |
| <joe@invalid.address> wrote in message
news:m3sm5hvxco.fsf@invalid.address...
> "Pappan" <padmanabhanp@fastmail.fm> writes:
>
> It might be. Depends on your requirements. For example, a daemon that
> spawns other programs would probably want to leave descriptors 0, 1
> and 2 open, but pointing to /dev/null.
I'd say it's not a bad idea to do this even in a daemon the doesn't spawn
other programs: at least any spurious output goes to the bit bucket instead
of possibly ending up somewhere you didn't want it to.
>
> I didn't understand this. Can you rephrase?
I think Pappan was thinking this: suppose you link your application with a
library, and that library obtains a descriptor (perhaps for a socket) when
you first call into it, but - intentionally - doesn't close it. This may be
done so that subsequent calls are faster.
Clearly, closing that (unknown) descriptor could have "interesting" effects,
particularly if the descriptor is reused.
The way I see it, you can't usually be sure whether or not some library has
deliberately left a descriptor open as part of its internal operation, but
if it has, bad things may happen, so it's usually unwise to close "random"
descriptors.
Alex
| |
| Alex Fraser 2005-01-04, 5:59 pm |
| "Alex Fraser" <me@privacy.net> wrote in message
news:340999F40h55nU1@individual.net...
[snip]
> The way I see it, you can't usually be sure whether or not some library
> has deliberately left a descriptor open as part of its internal
> operation, but if it has,
In case it isn't obvious, I meant "but if it has, and you close it"
> bad things may happen, so it's usually unwise to close "random"
> descriptors.
Alex
| |
| Rich Teer 2005-01-04, 5:59 pm |
| On Tue, 4 Jan 2005, Alex Fraser wrote:
> I think Pappan was thinking this: suppose you link your application with a
> library, and that library obtains a descriptor (perhaps for a socket) when
> you first call into it, but - intentionally - doesn't close it. This may be
> done so that subsequent calls are faster.
>
> Clearly, closing that (unknown) descriptor could have "interesting" effects,
> particularly if the descriptor is reused.
>
> The way I see it, you can't usually be sure whether or not some library has
> deliberately left a descriptor open as part of its internal operation, but
> if it has, bad things may happen, so it's usually unwise to close "random"
> descriptors.
A fair point, but given that daemonisation (usually) happens very early in
the lifetime of a (long-lived) process, a moot one. The process should become
a daemon first, before calling other stuff that might have the side effects
you mention.
--
Rich Teer, SCNA, SCSA, author of "Solaris Systems Programming"
. * * . * .* .
. * . .*
President, * . . /\ ( . . *
Rite Online Inc. . . / .\ . * .
.*. / * \ . .
. /* o \ .
Voice: +1 (250) 979-1638 * '''||''' .
URL: http://www.rite-online.net ******************
| |
| Brian Utterback 2005-01-04, 5:59 pm |
| Rich Teer wrote:
> On Tue, 4 Jan 2005, Alex Fraser wrote:
>
>
>
>
> A fair point, but given that daemonisation (usually) happens very early in
> the lifetime of a (long-lived) process, a moot one. The process should become
> a daemon first, before calling other stuff that might have the side effects
> you mention.
>
I am currently working on patches for Solaris 8 and 9 to fix a bug
due to the (undocumented) use of a file descriptor by the Netscape
security code (NSS) which is used by LDAP. Daemons sometimes try to
initialize things before daemonizing so that errors can be reported
when they start up. In the case of the LDAP backend to the name
service switch, any name service call at all before daemonizing
resulted in this file descriptor being opened, and then being closed
when the process daemonized, resulting in subsequent errors in the
LDAP calls. There are two ways to deal with this kind of thing in
a library. One is to document the usage of the the file descriptor,
and the other is to test if the descriptor is still used and pointing
where you expect it, and to reinit if it is not. The NSS code did
neither.
--
blu
I voted electronically...I think.
----------------------------------------------------------------------
Brian Utterback - OP/N1 RPE, Sun Microsystems, Inc.
Ph:877-259-7345, Em:brian.utterback-at-ess-you-enn-dot-kom
| |
| Måns Rullgård 2005-01-04, 5:59 pm |
| Rich Teer <rich.teer@rite-group.com> writes:
> On Tue, 4 Jan 2005, Alex Fraser wrote:
>
>
> A fair point, but given that daemonisation (usually) happens very
> early in the lifetime of a (long-lived) process, a moot one. The
> process should become a daemon first, before calling other stuff
> that might have the side effects you mention.
It might be desirable to do some initial setup before daemonizing, so
if something goes wrong, it can be easily reported. Many servers
attempt to bind() a socket before becoming a deamon, and exit with an
error code on failure.
--
Måns Rullgård
mru@inprovide.com
| |
| Richard Kettlewell 2005-01-04, 5:59 pm |
| Lew Pitcher <Lew.Pitcher@td.com> writes:
> Pappan wrote:
>
> Usually, but not always. Certainly, you normally want to close and
> discard the controlling terminal, and you usually want to close any
> 'unused' file descriptors (i.e. descriptors that might have been left
> open by the process that exec'ed your daemon),
Why? It's not that they can do any harm, and it's sometimes useful to
be able to pass file descriptors down to programs executed by the
daemon. (Similarly the environment, although it's less rare that
daemons try to scrub that.)
> but closing any other descriptors is something that you do if you
> want or need to, not because you have to.
>
>
> I'm not sure I understand your scenario here. Could you explain it in
> simpler terms? FWIW, if you suspect that a descriptor has been cached,
> and that closing the descriptor will cause problems, you don't /have/ to
> close the descriptor.
Some bit of the C library called before you daemonize might have
opened a file descriptor for its own purposes. If you close it,
library functions might mysteriously fail later.
--
http://www.greenend.org.uk/rjk/
| |
| Rich Teer 2005-01-04, 5:59 pm |
| On Tue, 4 Jan 2005, Måns Rullgård wrote:
> It might be desirable to do some initial setup before daemonizing, so
> if something goes wrong, it can be easily reported. Many servers
> attempt to bind() a socket before becoming a deamon, and exit with an
> error code on failure.
I agree (with you and Brian). I was using "moot" in the UK sense
of the word, as in "open to debate".
--
Rich Teer, SCNA, SCSA, author of "Solaris Systems Programming"
. * * . * .* .
. * . .*
President, * . . /\ ( . . *
Rite Online Inc. . . / .\ . * .
.*. / * \ . .
. /* o \ .
Voice: +1 (250) 979-1638 * '''||''' .
URL: http://www.rite-online.net ******************
| |
| Rich Teer 2005-01-04, 5:59 pm |
| On Tue, 4 Jan 2005, Richard Kettlewell wrote:
> Why? It's not that they can do any harm, and it's sometimes useful to
File descriptors are a finite resource, so they should be manage
accordingly.
> be able to pass file descriptors down to programs executed by the
Yes, but how often would one want a daemon to pass on a file descriptor
IT gets from its parent? Not also the word "usually", which implies
there might be circumstances under which closing the descriptors is
not a good idea. But generally, it is the correct thing to do.
> Some bit of the C library called before you daemonize might have
> opened a file descriptor for its own purposes. If you close it,
> library functions might mysteriously fail later.
Agreed; this is one of those circumstances... :-)
--
Rich Teer, SCNA, SCSA, author of "Solaris Systems Programming"
. * * . * .* .
. * . .*
President, * . . /\ ( . . *
Rite Online Inc. . . / .\ . * .
.*. / * \ . .
. /* o \ .
Voice: +1 (250) 979-1638 * '''||''' .
URL: http://www.rite-online.net ******************
| |
| Villy Kruse 2005-01-05, 7:51 am |
| On Tue, 04 Jan 2005 22:37:15 +0100,
Måns Rullgård <mru@inprovide.com> wrote:
>
> It might be desirable to do some initial setup before daemonizing, so
> if something goes wrong, it can be easily reported. Many servers
> attempt to bind() a socket before becoming a deamon, and exit with an
> error code on failure.
>
You might still want to close all unwanted descriptors, but do that very
early in main() before opening sockets and other initial processing.
Perhaps you could leave stdout and stderr as is for error reporting during
start-up, and then later close and reopen stdout and stderr to /dev/null.
Villy
| |
| Richard Kettlewell 2005-01-05, 7:51 am |
| Rich Teer <rich.teer@rite-group.com> writes:
> Richard Kettlewell wrote:
>
> File descriptors are a finite resource, so they should be manage
> accordingly.
We solve this for non-daemon programs by not passing them hundreds of
pointless FDs. The same approach works fine for daemons too.
>
> Yes, but how often would one want a daemon to pass on a file
> descriptor IT gets from its parent?
The typical situation is where you want to give a subprocess of the
daemon access to some resource that it can't (or can't conveniently)
get hold of any other way; for example:
* because file permissions would otherwise prohibit it
* because none of the names for the resource are visible
(unlink/chroot)
* because the resource never had a filesystem name in the first place
(pipe/socketpair/accept)
LD_PRELOAD means it's not limited to subprocesses either, in fact.
> Not also the word "usually", which implies there might be
> circumstances under which closing the descriptors is not a good
> idea. But generally, it is the correct thing to do.
No, it makes an occasionally-useful trick impossible for no good
reason.
--
http://www.greenend.org.uk/rjk/
| |
| Rich Teer 2005-01-05, 5:56 pm |
| On Wed, 5 Jan 2005, Richard Kettlewell wrote:
> We solve this for non-daemon programs by not passing them hundreds of
> pointless FDs. The same approach works fine for daemons too.
Yes, but that assumes you have complete control over the process that
calls the daemon. Also, the way one doesn't pass on "hundreds of
pointless FDs" is to close the ones that aren't necessary. Something
you seem to be arguing against (in general). Taking this to the extreme,
suppose your daemon was execed by a poorly written program that DID leave
open hundreds of FDs, none of which were intended to be used by the daemon.
By taking the approach you seem to be advocating, every process the daemon
creates will also inherit those useless FDs.
From a security point of view, no program should trust the environment
(including file descriptors) it inherits from its parent. Ut follows
that in the general case, programs (and especially long-lived ones like
daemons) should close all unnecessary files early in their lifetime.
Obviously there are exceptions to this, but it's a good rule of thumb.
> The typical situation is where you want to give a subprocess of the
> daemon access to some resource that it can't (or can't conveniently)
> get hold of any other way; for example:
> * because file permissions would otherwise prohibit it
> * because none of the names for the resource are visible
> (unlink/chroot)
> * because the resource never had a filesystem name in the first place
> (pipe/socketpair/accept)
Agreed--those are all valid exceptions to the rule.
> No, it makes an occasionally-useful trick impossible for no good
> reason.
We seem to be coming from opposite schools of thought. I'm from
the deny by default school, and you seem to be from the allow by
default school. Each has its place, but for those of us concerned
about security, the former is the prefered model.
--
Rich Teer, SCNA, SCSA, author of "Solaris Systems Programming"
. * * . * .* .
. * . .*
President, * . . /\ ( . . *
Rite Online Inc. . . / .\ . * .
.*. / * \ . .
. /* o \ .
Voice: +1 (250) 979-1638 * '''||''' .
URL: http://www.rite-online.net ******************
| |
| Bjorn Reese 2005-01-05, 5:56 pm |
| Rich Teer wrote:
> Yes, but that assumes you have complete control over the process that
> calls the daemon. Also, the way one doesn't pass on "hundreds of
Tell me about it. I recently was faced with this problem. Solving the
problem in the "right way" would have involved three different vendors.
Imagine the difficulties getting three vendors to agree that there is
a problem, that it should be solved, where the problem is located, how
to solve it, and then commit to release schedules... I tried (to imagine
it, that is), and then I closed all the file descriptors at my end, all
except the ones that I knew the daemon was using.
--
mail1dotstofanetdotdk
| |
| Richard Kettlewell 2005-01-06, 5:56 pm |
| Rich Teer <rich.teer@rite-group.com> writes:
> Richard Kettlewell wrote:
>
> Yes, but that assumes you have complete control over the process
> that calls the daemon. Also, the way one doesn't pass on "hundreds
> of pointless FDs" is to close the ones that aren't necessary.
> Something you seem to be arguing against (in general). Taking this
> to the extreme, suppose your daemon was execed by a poorly written
> program that DID leave open hundreds of FDs, none of which were
> intended to be used by the daemon. By taking the approach you seem
> to be advocating, every process the daemon creates will also inherit
> those useless FDs.
If you really have a situation where some daemon is unavoidably
executed by some program which opens many FDs, doesn't set
close-on-exec and is too lazy to close them inside the fork (...do
you?), then it shouldn't be hard[1] to write a wrapper which closes
them and then execs the daemon. That way the daemon remains maximally
useful to people who need to perform the tricks below yet also copes
with your weirdo invoker.
[1] i.e. no harder than doing it in the daemon itself; not that this
is entirely trivial as you don't know what the highest open FD is.
When you close "all" FDs, do you go all the way up to INT_MAX?
> From a security point of view, no program should trust the environment
> (including file descriptors) it inherits from its parent.
You think ls(1) should ignore its command line arguments and stdout,
then? If were talking about set[ug]id programs then you might have a
point but since we're not I think that remark's just wrong.
daemons usually run at lower or equal privilege to their caller, so:
(i) if the caller leaks an important FD to the daemon
then it may already be "too late" and is obviously the fault of
the caller anyway;
(ii) if the caller gives the daemon an environment (of whatever
kind) that makes the daemon misbehave, this is not a security
problem as it could have just done whatever nefarious thing the
misbehaving daemon did anyway.
>
> Agreed--those are all valid exceptions to the rule.
They might apply to any daemon which has cause to execute an
operator-supplied program; or, with LD_PRELOAD, to any daemon at all.
i.e. they are not exceptions that are anything to do with a specific
daemon; you don't generally know when you're writing the daemon that
your users will need them.
>
> We seem to be coming from opposite schools of thought. I'm from
> the deny by default school, and you seem to be from the allow by
> default school. Each has its place, but for those of us concerned
> about security, the former is the prefered model.
You should be careful about classifying people!
--
http://www.greenend.org.uk/rjk/
| |
| Rich Teer 2005-01-06, 5:56 pm |
| On Thu, 6 Jan 2005, Richard Kettlewell wrote:
> If you really have a situation where some daemon is unavoidably
> executed by some program which opens many FDs, doesn't set
> close-on-exec and is too lazy to close them inside the fork (...do
> you?), then it shouldn't be hard[1] to write a wrapper which closes
> them and then execs the daemon. That way the daemon remains maximally
> useful to people who need to perform the tricks below yet also copes
> with your weirdo invoker.
True, but then you have TWO programs to maintain.
> When you close "all" FDs, do you go all the way up to INT_MAX?
Depends on the platform. On Solaris, one can simply call closefrom().
In the more general situation, one can probably rely on the number of
open files resource limit.
>
> You think ls(1) should ignore its command line arguments and stdout,
That's an extreme way to interpret what I wrote!
> then? If were talking about set[ug]id programs then you might have a
> point but since we're not I think that remark's just wrong.
You're using a specific example to "disprove" an generalisation
that I made. There will always be exceptions to any rule, but
that doesn't make that rule any worse or invalid.
> daemons usually run at lower or equal privilege to their caller, so:
>
> (i) if the caller leaks an important FD to the daemon
> then it may already be "too late" and is obviously the fault of
> the caller anyway;
Have you not heard of security in depth? Taking this to an absurd
extreme, no program should take any security precautions because
their callers should be setting up a secure environment for them.
Also, what about deliberate abuse?
I just think that it is better for program writers to err on the
side of caution.
> (ii) if the caller gives the daemon an environment (of whatever
> kind) that makes the daemon misbehave, this is not a security
> problem as it could have just done whatever nefarious thing the
> misbehaving daemon did anyway.
That depends on what the daemon does. It's conceivable that a daemon
running as root performs certain tasks for unprivileged processes.
In this case, you (as in, the designer of the daemon) want to be as
sure as possible that the number of vulnerabilites your daemon has is
kept to a minimum.
> You should be careful about classifying people!
No offense intended!
I think we're going to have to agree to disagree on this one...
--
Rich Teer, SCNA, SCSA, author of "Solaris Systems Programming"
. * * . * .* .
. * . .*
President, * . . /\ ( . . *
Rite Online Inc. . . / .\ . * .
.*. / * \ . .
. /* o \ .
Voice: +1 (250) 979-1638 * '''||''' .
URL: http://www.rite-online.net ******************
| |
| Richard Kettlewell 2005-01-07, 5:59 pm |
| Rich Teer <rich.teer@rite-group.com> writes:
> Richard Kettlewell wrote:
>
> True, but then you have TWO programs to maintain.
Actually I think what you've really got is the same bits of code to
maintain that you always had, but now there is only one copy of the
FD-closing stuff, rather than as many copies of it as there are
daemons.
(Also I'm a fan of little programs that modify their environment in
some useful way and then exec their arguments; 'nohup' being the
best-known example of what I mean.)
>
> Depends on the platform. On Solaris, one can simply call closefrom().
Nifty. But for better or for worse we can't rely on Sun's API being
available everywhere...
> In the more general situation, one can probably rely on the number of
> open files resource limit.
You can open lots of files and then lower the resource limit and the
FDs above the new limit aren't closed.
>
> That's an extreme way to interpret what I wrote!
I imagine I must be misunderstanding what you really meant, then. My
/usr/bin is full of programs that are just supposed to do whatever
their arguments tell them, and nobody seems to think this is a problem
or a violation of any general rule or whatever.
>
> Have you not heard of security in depth?
Indeed, I have; but, it seems, I have a different view of where the
best compromise between functionality and security lies in this
particular case.
> Taking this to an absurd extreme, no program should take any
> security precautions because their callers should be setting up a
> secure environment for them.
A thing is not necessarily silly just because it's possible to take it
to a ridiculous extreme.
> Also, what about deliberate abuse?
Tell me something that you can do by somehow abusing a daemon that
runs at your own or lower privilege. I bet I can tell you how to
achieve the same thing without using the daemon.
>
> That depends on what the daemon does. It's conceivable that a daemon
> running as root performs certain tasks for unprivileged processes.
> In this case, you (as in, the designer of the daemon) want to be as
> sure as possible that the number of vulnerabilites your daemon has is
> kept to a minimum.
Yes, daemons routinely perform tasks on behalf of less-privileged
clients. But they won't execute arbitrary programs, or poke at random
FDs specified by those clients (at least, not by design; if they do,
then they have a security hole whether or not they close
apparently-superfluous FDs).
> No offense intended!
Oh, none taken.
> I think we're going to have to agree to disagree on this one...
I have no problem with that l-)
--
http://www.greenend.org.uk/rjk/
| |
| Pappan 2005-01-18, 5:56 pm |
| Exactly Alex.
------
suppose you link your application with a
library, and that library obtains a descriptor (perhaps for a socket)
when
you first call into it, but - intentionally - doesn't close it. This
may be
done so that subsequent calls are faster
-------
I am facing a situation where a call goes to NIS backend library before
inetd deamonizes. The file handle(in the case i am looking at is a
transport end point opened with t_open) that is opened by NIS is cached
by it for performance reasons.
Then comes our deamonizing code of inetd. where in a loop we close all
the file descriptors including the one cached by NIS.
Looking at this case i got into doubt whether closing without regard to
whether someone has cached it or not is a good idea by inetd
Also can anyone let me know of any inetd which supports XTI?
Thanks a lot to all for all the answers that have been provided till
now
-Pappan
|
|
|
|
|