Hi Axel,

On 05/01/2014 12:13 PM, Axel Beckert wrote:
The problem is the second scanning pass which looks for the parent
processes. It seems to happen if a process is a child of a kernel
thread... sadly I could not reproduce it, yet.

Strange. I really wonder what's so different on my boxes. Did you try
it with Debian Unstable kernels? Or rather with Debian Stable kernels?
Maybe there changed something which causes this behaviour. (I haven't
tried 0.8 on Stable yet.)

another trigger to break readlink /proc/<pid>/exe seems to be a permission issue. Example:

$ stat /proc/`pidof -s kdm`/exe
File: ‘/proc/28931/exe’stat: cannot read symbolic link ‘/proc/28931/exe’: Permission denied

  Size: 0               Blocks: 0          IO Block: 1024   symbolic link
Device: 3h/3d   Inode: 3131274     Links: 1
Access: (0777/lrwxrwxrwx)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2014-05-05 20:39:01.701539207 +0200
Modify: 2014-05-05 20:15:58.193830135 +0200
Change: 2014-05-05 20:15:58.193830135 +0200
 Birth: -


Does the system has any enhanced security mechanism established?

I've attached a small debug script (modified needrestart script) which analysis the processes and looks for non-readable /proc/<pid>/exe symlinks. Could you please run it once and provide it's output?


TIA,
Thomas

--

    ::  WWW:                         http://fiasko-nw.net/~thomas/  ::
   :::  Jabber:                   xmpp:tho...@jabber.fiasko-nw.net  :::
    ::  flickr:              http://www.flickr.com/photos/laugufe/  ::
#!/usr/bin/perl

use Getopt::Std;
use NeedRestart;
use NeedRestart::UI;
use NeedRestart::Utils;

use warnings;
use strict;

our %nrconf = (
    verbose => 1,
    hook_d => '/etc/needrestart/hook.d',
    restart => 'l',
    defno => 0,
    blacklist => [],
    interpscan => 1,
    kernelhints => 1,
);

$nrconf{ui} = qq(NeedRestart::UI::stdio);

warn "WARNING: This program should be run as root!\n" if($< != 0);

# get UI
my $ui = needrestart_ui($nrconf{verbose}, $nrconf{ui});
die "Error: no UI class available!\n" unless(defined($ui));

# inspect only pids
my $ptable = nr_ptable();
$ui->progress_prep(scalar keys %$ptable, 'Scanning processes', 1);
my %stage2;
for my $pid (sort {$a <=> $b} keys %$ptable) {
    my $restart = 0;

    # get executable (Linux 2.2+)
    $ui->progress_step($ptable->{$pid}->{exec});

    # ignore kernel threads
    next unless(defined($ptable->{$pid}->{exec}));

    # orphaned binary
    $restart++;

    # find parent process
    my $ppid = $ptable->{$pid}->{ppid};
    if($ppid != $pid && $ppid > 1) {
        print STDERR "#$pid is a child of #$ppid\n" if($nrconf{verbose});

        unless(exists($stage2{$ppid})) {
            # ignore kernel threads
            unless(defined($ptable->{$ppid}->{exec})) {
                warn "#$pid is a child of a kernel process!\n";
                use Data::Dumper;
                print Dumper($ptable->{$pid}, $ptable->{$ppid});
            }

            $stage2{$ppid} = $ptable->{$pid}->{exec};
        }
    }
    else {
        print STDERR "#$pid is not a child\n" if($nrconf{verbose});
        $stage2{$pid} = $ptable->{$pid}->{exec};
    }
}
$ui->progress_fin(1);

Reply via email to