How to make an application to prevent itself from launching from the command line?
I have a binary which should be launched by a daemon; but when somebody tries to launch the binary from command line, I should error out stating "cannot be launched from command line".
Tried googling but in vain.

Dani AI

Generated

A couple of solid ideas are already on the table: checking the parent process (as suggested by ) and verifying whether stdin is attached to an interactive terminal (as noted by and followed up by ). Those are useful quick checks, but they are heuristics — easy to bypass with redirection, wrapper scripts, PID reuse, or by a privileged user. Treat the problem as an authentication problem rather than a binary “can/cannot” one.

A more reliable pattern is to require something only the daemon can provide at exec time — for example, a short random token sent over an inherited pipe or a private UNIX-domain socket. The child immediately reads that token and exits if it doesn’t match. Minimal child-side check (illustrative):

int check_token(int fd, const char *expected) {
    char tok[64];
    ssize_t n = read(fd, tok, sizeof(tok)-1);
    if (n <= 0) return 0;
    tok[n] = '\0';
    return strcmp(tok, expected) == 0;
}

Daemon side: create the pipe/socket, write the token, then exec the child with the FD inherited (do not set close-on-exec). Make the token short-lived and unpredictable. This approach is robust because it cannot be faked by simply running the binary from a shell.

If you want lighter-weight heuristics, combine a couple of checks: read /proc/<ppid>/comm or /proc/<ppid>/exe to verify the parent binary, and inspect /proc/self/fd/0 with readlink to see if stdin points at /dev/null or a pty. Example:

ssize_t r = readlink("/proc/self/fd/0", buf, sizeof(buf)-1);
if (r > 0) { buf[r] = '\0'; if (strcmp(buf, "/dev/null")==0) /* likely daemon */ }

Caveats: parent checks are racy (parent may exit and PID be reused), stdin tests can be defeated by redirection, and root can bypass everything. For anything security-sensitive, prefer authenticated IPC (token + restricted unix socket or systemd socket activation). Combine token-based authentication with a tty/parent check as practical extra defenses, and always log and exit with a clear message and nonzero status when the checks fail.

Recommended Answers

All 5 Replies

My first approach would probably be to check the parent process and kill the program if the parent is a shell, like bash or csh.

Another approach would be to see if stdin is attached to a real terminal. A process that is spawned by a daemon would have no stdin device, or it would be /dev/null.

commented: never mind.. i got it! +0

, i need to check parent name against all the possible shells.. is that what you are suggesting? sounds fine to me.. but i was looking for other approaches which would take lesser lines of code..
, that makes sense.. will you please spare time to tell me how to check if stdin device of a process is /dev/null or not?

In C, you can #include <unistd.h> and then use the ttyname(0) function. It resturns a pointer to the terminal that fd 0 (stdin) is connected with, or NULL if it isn't attached to a terminal (or there is an error) - checking errno for ENOTTY will tell you if it is not attached. From the Linux ttyname(3) man page:

TTYNAME(3)                 Linux Programmer’s Manual                TTYNAME(3)

NAME
       ttyname, ttyname_r - return name of a terminal

SYNOPSIS
       #include <unistd.h>

       char *ttyname(int fd);

       int ttyname_r(int fd, char *buf, size_t buflen);

DESCRIPTION
       The function ttyname() returns a pointer to the null-terminated pathname of the terminal device that is open on
       the file descriptor fd, or NULL on error (for example, if fd is not connected to a terminal).  The return value
       may point to static data, possibly overwritten by the next call.  The function ttyname_r() stores this pathname
       in the buffer buf of length buflen.

RETURN VALUE
       The function ttyname() returns a pointer to a pathname on success.  On error, NULL is returned,  and  errno  is
       set appropriately.  The function ttyname_r() returns 0 on success, and an error number upon error.

ERRORS
       ttyname_r():

       EBADF  Bad file descriptor.

       ENOTTY File descriptor does not refer to a terminal device.

       ERANGE buflen was too small to allow storing the pathname.

CONFORMING TO
       4.2BSD, POSIX.1-2001.

SEE ALSO
       fstat(2), isatty(3)

COLOPHON
       This  page  is part of release 3.22 of the Linux man-pages project.  A description of the project, and informa-
       tion about reporting bugs, can be found at http://www.kernel.org/doc/man-pages/.

Linux                             2008-07-14                        TTYNAME(3)

, thanks for the info!.. I think "isatty(STDIN_FILENO)" will serve my purpose..

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.