This commit is contained in:
parent
0cb55aafb0
commit
0999096aff
@ -1,18 +1,5 @@
|
||||
--- src/fuser.c
|
||||
+++ src/fuser.c 2008-09-01 15:03:05.054239318 +0200
|
||||
@@ -925,8 +925,10 @@ int main(int argc, char *argv[])
|
||||
continue;
|
||||
}
|
||||
|
||||
- scan_mount_devices(opts, &mount_devices);
|
||||
- fill_unix_cache(&unixsockets);
|
||||
+ if (!mount_devices)
|
||||
+ scan_mount_devices(opts, &mount_devices);
|
||||
+ if (!unixsockets)
|
||||
+ fill_unix_cache(&unixsockets);
|
||||
|
||||
/* File specifications */
|
||||
if ( (this_name = malloc(sizeof(struct names))) == NULL)
|
||||
@@ -1306,6 +1308,7 @@ void fill_unix_cache(struct unixsocket_l
|
||||
*unixsocket_head = newsocket;
|
||||
} /* while */
|
||||
|
@ -33,8 +33,8 @@
|
||||
cannot report on any processes that it doesn't have permission to look at
|
||||
the file descriptor table for. The most common time this problem occurs
|
||||
--- src/fuser.c
|
||||
+++ src/fuser.c 2008-08-07 14:47:58.126764924 +0200
|
||||
@@ -32,6 +32,7 @@
|
||||
+++ src/fuser.c 2008-09-23 16:00:18.038188677 +0200
|
||||
@@ -32,9 +32,11 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
@ -42,7 +42,19 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/socket.h>
|
||||
@@ -62,7 +63,7 @@
|
||||
+#include <sys/wait.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <pwd.h>
|
||||
@@ -45,6 +47,7 @@
|
||||
#include <mntent.h>
|
||||
#include <signal.h>
|
||||
#include <getopt.h>
|
||||
+#include <setjmp.h>
|
||||
|
||||
#include "fuser.h"
|
||||
#include "signals.h"
|
||||
@@ -62,7 +65,7 @@
|
||||
static void add_matched_proc(struct names *name_list, const pid_t pid, const uid_t uid, const char access);
|
||||
static void check_dir(const pid_t pid, const char *dirname, struct device_list *dev_head, struct inode_list *ino_head, const uid_t uid, const char access);
|
||||
static void check_map(const pid_t pid, const char *filename, struct device_list *dev_head, struct inode_list *ino_head, const uid_t uid, const char access);
|
||||
@ -51,25 +63,27 @@
|
||||
static uid_t getpiduid(const pid_t pid);
|
||||
static int print_matches(struct names *names_head, const opt_type opts, const int sig_number);
|
||||
static void kill_matched_proc(struct procs *pptr, const opt_type opts, const int sig_number);
|
||||
@@ -72,13 +73,15 @@ static void add_device(struct device_lis
|
||||
@@ -72,13 +75,18 @@ static void add_device(struct device_lis
|
||||
void scan_mount_devices(const opt_type opts, struct mountdev_list **mount_devices);
|
||||
void fill_unix_cache(struct unixsocket_list **unixsocket_head);
|
||||
static dev_t find_net_dev(void);
|
||||
-static void scan_procs(struct names *names_head, struct inode_list *ino_head, struct device_list *dev_head);
|
||||
+static void scan_procs(const opt_type opts, struct names *names_head, struct inode_list *ino_head, struct device_list *dev_head, struct mountdev_list *mounts);
|
||||
+static void scan_procs(const opt_type opts, struct names *names_head, struct inode_list *ino_head, struct device_list *dev_head);
|
||||
#ifdef NFS_CHECKS
|
||||
static void scan_knfsd(struct names *names_head, struct device_list *dev_head);
|
||||
#endif /* NFS_CHECKS */
|
||||
#ifdef DEBUG
|
||||
-static void debug_match_lists(struct names *names_head, struct inode_list *ino_head, struct device_list *dev_head);
|
||||
+static void debug_match_lists(struct names *names_head, struct inode_list *ino_head, struct device_list *dev_head, struct mountdev_list *mounts);
|
||||
static void debug_match_lists(struct names *names_head, struct inode_list *ino_head, struct device_list *dev_head);
|
||||
#endif
|
||||
+static struct nfs_points *mnts;
|
||||
+static int check4nfs(const char * path, char * real);
|
||||
+
|
||||
+typedef int (*stat_t)(const char*, struct stat*);
|
||||
+static int nfssafe(stat_t func, const char *path, struct stat *buf);
|
||||
|
||||
static void usage (const char *errormsg)
|
||||
{
|
||||
@@ -127,7 +130,14 @@ void print_version()
|
||||
@@ -127,7 +135,14 @@ void print_version()
|
||||
"For more information about these matters, see the files named COPYING.\n"));
|
||||
}
|
||||
|
||||
@ -81,11 +95,11 @@
|
||||
+ return (strstr(path, loc) == path);
|
||||
+}
|
||||
+
|
||||
+static void scan_procs(const opt_type opts, struct names *names_head, struct inode_list *ino_head, struct device_list *dev_head, struct mountdev_list *mounts)
|
||||
+static void scan_procs(const opt_type opts, struct names *names_head, struct inode_list *ino_head, struct device_list *dev_head)
|
||||
{
|
||||
DIR *topproc_dir;
|
||||
struct dirent *topproc_dent;
|
||||
@@ -137,6 +147,9 @@ static void scan_procs(struct names *nam
|
||||
@@ -137,6 +152,9 @@ static void scan_procs(struct names *nam
|
||||
pid_t pid, my_pid;
|
||||
uid_t uid;
|
||||
struct stat *cwd_stat, *exe_stat, *root_stat;
|
||||
@ -95,7 +109,7 @@
|
||||
|
||||
if ( (fd_dirpath = malloc(MAX_PATHNAME)) == NULL)
|
||||
return;
|
||||
@@ -157,9 +170,10 @@ static void scan_procs(struct names *nam
|
||||
@@ -157,9 +175,10 @@ static void scan_procs(struct names *nam
|
||||
continue;
|
||||
uid = getpiduid(pid);
|
||||
|
||||
@ -109,7 +123,7 @@
|
||||
/* Scan the devices */
|
||||
for (dev_tmp = dev_head ; dev_tmp != NULL ; dev_tmp = dev_tmp->next) {
|
||||
if (exe_stat != NULL && exe_stat->st_dev == dev_tmp->device)
|
||||
@@ -168,6 +182,14 @@ static void scan_procs(struct names *nam
|
||||
@@ -168,6 +187,14 @@ static void scan_procs(struct names *nam
|
||||
add_matched_proc(dev_tmp->name, pid, uid, ACCESS_ROOT);
|
||||
if (cwd_stat != NULL && cwd_stat->st_dev == dev_tmp->device)
|
||||
add_matched_proc(dev_tmp->name, pid, uid, ACCESS_CWD);
|
||||
@ -124,7 +138,7 @@
|
||||
}
|
||||
for (ino_tmp = ino_head ; ino_tmp != NULL ; ino_tmp = ino_tmp->next) {
|
||||
if (exe_stat != NULL) {
|
||||
@@ -186,9 +208,19 @@ static void scan_procs(struct names *nam
|
||||
@@ -186,9 +213,19 @@ static void scan_procs(struct names *nam
|
||||
add_matched_proc(ino_tmp->name, pid, uid, ACCESS_CWD);
|
||||
}
|
||||
}
|
||||
@ -144,7 +158,7 @@
|
||||
check_dir(pid, "fd", dev_head, ino_head, uid, ACCESS_FILE);
|
||||
check_map(pid, "maps", dev_head, ino_head, uid, ACCESS_MMAP);
|
||||
|
||||
@@ -325,10 +357,26 @@ int parse_mount(struct names *this_name,
|
||||
@@ -325,10 +362,26 @@ int parse_mount(struct names *this_name,
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -172,7 +186,7 @@
|
||||
if (stat(this_name->filename, &st) != 0) {
|
||||
fprintf(stderr,_("Cannot stat %s: %s\n"), this_name->filename,
|
||||
strerror(errno));
|
||||
@@ -342,34 +390,44 @@ int parse_file(struct names *this_name,
|
||||
@@ -342,34 +395,44 @@ int parse_file(struct names *this_name,
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -224,7 +238,7 @@
|
||||
|
||||
if (stat(this_name->filename, &st) != 0) {
|
||||
fprintf(stderr,_("Cannot stat %s: %s\n"), this_name->filename,
|
||||
@@ -388,6 +446,16 @@ int parse_mounts(struct names *this_name
|
||||
@@ -388,6 +451,16 @@ int parse_mounts(struct names *this_name
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
@ -241,7 +255,7 @@
|
||||
}
|
||||
|
||||
#ifdef WITH_IPV6
|
||||
@@ -652,6 +720,80 @@ void find_net6_sockets(struct inode_list
|
||||
@@ -652,6 +725,80 @@ void find_net6_sockets(struct inode_list
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -322,49 +336,52 @@
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
opt_type opts;
|
||||
@@ -664,7 +806,7 @@ int main(int argc, char *argv[])
|
||||
struct device_list *match_devices = NULL;
|
||||
struct unixsocket_list *unixsockets = NULL;
|
||||
@@ -676,6 +823,7 @@ int main(int argc, char *argv[])
|
||||
int optc;
|
||||
char *option;
|
||||
char *nsptr;
|
||||
+ size_t len;
|
||||
|
||||
- dev_t netdev;
|
||||
+ dev_t netdev = find_net_dev();
|
||||
struct ip_connections *tcp_connection_list = NULL;
|
||||
struct ip_connections *udp_connection_list = NULL;
|
||||
#ifdef WITH_IPV6
|
||||
@@ -691,10 +833,6 @@ int main(int argc, char *argv[])
|
||||
textdomain(PACKAGE);
|
||||
ipv4_only = ipv6_only = 0;
|
||||
@@ -692,7 +840,6 @@ int main(int argc, char *argv[])
|
||||
#endif
|
||||
|
||||
- netdev = find_net_dev();
|
||||
netdev = find_net_dev();
|
||||
- scan_mount_devices(opts, &mount_devices);
|
||||
- fill_unix_cache(&unixsockets);
|
||||
-
|
||||
fill_unix_cache(&unixsockets);
|
||||
|
||||
/* getopt doesnt like things like -SIGBLAH */
|
||||
for(optc = 1; optc < argc; optc++) {
|
||||
if (argv[optc][0] == '-') { /* its an option */
|
||||
@@ -782,6 +920,10 @@ int main(int argc, char *argv[])
|
||||
@@ -782,6 +929,10 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
continue;
|
||||
}
|
||||
+
|
||||
+ scan_mount_devices(opts, &mount_devices);
|
||||
+ fill_unix_cache(&unixsockets);
|
||||
+ if (!mount_devices)
|
||||
+ scan_mount_devices(opts, &mount_devices);
|
||||
+
|
||||
/* File specifications */
|
||||
if ( (this_name = malloc(sizeof(struct names))) == NULL)
|
||||
continue;
|
||||
@@ -828,8 +970,8 @@ int main(int argc, char *argv[])
|
||||
@@ -828,10 +979,14 @@ int main(int argc, char *argv[])
|
||||
break;
|
||||
default: /* FILE */
|
||||
this_name->filename = strdup(argv[optc]);
|
||||
- parse_file(this_name, &match_inodes);
|
||||
- parse_unixsockets(this_name, &match_inodes, unixsockets);
|
||||
- if (opts & OPT_MOUNTPOINT || opts & OPT_MOUNTS)
|
||||
+ len = strlen(this_name->filename);
|
||||
+ if (this_name->filename[len-1] == '/')
|
||||
+ this_name->filename[len-1] = '\0';
|
||||
+ parse_file(this_name, &match_inodes, opts);
|
||||
+ parse_unixsockets(this_name, &match_inodes, unixsockets, netdev, opts);
|
||||
if (opts & OPT_MOUNTPOINT || opts & OPT_MOUNTS)
|
||||
+ if (opts & (OPT_MOUNTPOINT | OPT_MOUNTS)) {
|
||||
parse_mounts(this_name, mount_devices, &match_devices, opts);
|
||||
+ }
|
||||
break;
|
||||
@@ -857,22 +999,22 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
@@ -857,22 +1012,22 @@ int main(int argc, char *argv[])
|
||||
if (!ipv4_only) {
|
||||
#endif
|
||||
if (tcp_connection_list != NULL)
|
||||
@ -385,15 +402,14 @@
|
||||
}
|
||||
#endif
|
||||
#ifdef DEBUG
|
||||
- debug_match_lists(names_head, match_inodes, match_devices);
|
||||
+ debug_match_lists(names_head, match_inodes, match_devices, mount_devices);
|
||||
debug_match_lists(names_head, match_inodes, match_devices);
|
||||
#endif
|
||||
- scan_procs(names_head, match_inodes, match_devices);
|
||||
+ scan_procs(opts, names_head, match_inodes, match_devices, mount_devices);
|
||||
+ scan_procs(opts, names_head, match_inodes, match_devices);
|
||||
#ifdef NFS_CHECKS
|
||||
scan_knfsd(names_head, match_devices);
|
||||
#endif /* NFS_CHECKS */
|
||||
@@ -978,7 +1120,7 @@ static int print_matches(struct names *n
|
||||
@@ -978,7 +1133,7 @@ static int print_matches(struct names *n
|
||||
|
||||
}
|
||||
|
||||
@ -402,7 +418,7 @@
|
||||
{
|
||||
char pathname[256];
|
||||
struct stat *st;
|
||||
@@ -986,6 +1128,10 @@ static struct stat *get_pidstat(const pi
|
||||
@@ -986,6 +1141,10 @@ static struct stat *get_pidstat(const pi
|
||||
if ( (st = malloc(sizeof(struct stat))) == NULL)
|
||||
return NULL;
|
||||
snprintf(pathname, 256, "/proc/%d/%s", pid, filename);
|
||||
@ -413,7 +429,7 @@
|
||||
if (stat(pathname, st) != 0)
|
||||
return NULL;
|
||||
else
|
||||
@@ -1012,13 +1158,14 @@ static void check_dir(const pid_t pid, c
|
||||
@@ -1012,13 +1171,14 @@ static void check_dir(const pid_t pid, c
|
||||
while ( (direntry = readdir(dirp)) != NULL) {
|
||||
if (direntry->d_name[0] < '0' || direntry->d_name[0] > '9')
|
||||
continue;
|
||||
@ -429,7 +445,7 @@
|
||||
if (st.st_dev == dev_tmp->device) {
|
||||
if (access == ACCESS_FILE && (lstat(filepath, &lst)==0) && (lst.st_mode & S_IWUSR)) {
|
||||
add_matched_proc(dev_tmp->name, pid,uid, ACCESS_FILEWR|access);
|
||||
@@ -1028,6 +1175,8 @@ static void check_dir(const pid_t pid, c
|
||||
@@ -1028,6 +1188,8 @@ static void check_dir(const pid_t pid, c
|
||||
}
|
||||
}
|
||||
for (ino_tmp = ino_head ; ino_tmp != NULL ; ino_tmp = ino_tmp->next) {
|
||||
@ -438,7 +454,7 @@
|
||||
if (st.st_dev == ino_tmp->device && st.st_ino == ino_tmp->inode) {
|
||||
if (access == ACCESS_FILE && (lstat(filepath, &lst)==0) && (lst.st_mode & S_IWUSR)) {
|
||||
add_matched_proc(ino_tmp->name, pid,uid, ACCESS_FILEWR|access);
|
||||
@@ -1039,6 +1188,8 @@ static void check_dir(const pid_t pid, c
|
||||
@@ -1039,6 +1201,8 @@ static void check_dir(const pid_t pid, c
|
||||
}
|
||||
} /* while fd_dent */
|
||||
closedir(dirp);
|
||||
@ -447,7 +463,7 @@
|
||||
}
|
||||
|
||||
static void check_map(const pid_t pid, const char *filename, struct device_list *dev_head, struct inode_list *ino_head, const uid_t uid, const char access)
|
||||
@@ -1059,12 +1210,18 @@ static void check_map(const pid_t pid, c
|
||||
@@ -1059,12 +1223,18 @@ static void check_map(const pid_t pid, c
|
||||
if (sscanf(line, "%*s %*s %*s %x:%x %lld",
|
||||
&tmp_maj, &tmp_min, &tmp_inode) == 3) {
|
||||
tmp_device = tmp_maj * 256 + tmp_min;
|
||||
@ -468,7 +484,7 @@
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
@@ -1144,22 +1301,48 @@ void scan_mount_devices(const opt_type o
|
||||
@@ -1144,17 +1314,53 @@ void scan_mount_devices(const opt_type o
|
||||
FILE *mntfp;
|
||||
struct mntent *mnt_ptr;
|
||||
struct stat st;
|
||||
@ -488,7 +504,7 @@
|
||||
while ( (mnt_ptr = getmntent(mntfp)) != NULL) {
|
||||
+ if (!strcasecmp(MNTTYPE_NFS, mnt_ptr->mnt_type)) {
|
||||
+ /*
|
||||
+ * Remember all NFS typed partitions.
|
||||
+ * Remember all NFS typed partitions, required to make check4nfs() work.
|
||||
+ */
|
||||
+ struct nfs_points * p = (struct nfs_points*)malloc(sizeof(struct nfs_points));
|
||||
+ if (!p)
|
||||
@ -506,9 +522,19 @@
|
||||
+ add_mount_device(mount_devices, mnt_ptr->mnt_fsname, mnt_ptr->mnt_dir, (dev_t)-1);
|
||||
+ continue;
|
||||
+ }
|
||||
+ if (nfssafe(stat, mnt_ptr->mnt_dir, &st) == 0) {
|
||||
+ add_mount_device(mount_devices, mnt_ptr->mnt_fsname, mnt_ptr->mnt_dir, st.st_dev);
|
||||
+ } else {
|
||||
+ fprintf(stderr, _("Cannot stat file %s: %s\n"), mnt_ptr->mnt_dir, strerror(errno));
|
||||
+ }
|
||||
+ continue;
|
||||
+ }
|
||||
+ if ((opts & (OPT_MOUNTPOINT|OPT_MOUNTS)) == 0)
|
||||
+ continue;
|
||||
if (stat(mnt_ptr->mnt_dir, &st) == 0) {
|
||||
add_mount_device(mount_devices, mnt_ptr->mnt_fsname, mnt_ptr->mnt_dir, st.st_dev);
|
||||
+ } else {
|
||||
+ fprintf(stderr, _("Cannot stat file %s: %s\n"), mnt_ptr->mnt_dir, strerror(errno));
|
||||
}
|
||||
}
|
||||
+out:
|
||||
@ -516,14 +542,65 @@
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
/* often not used, doesnt need translation */
|
||||
-static void debug_match_lists(struct names *names_head, struct inode_list *ino_head, struct device_list *dev_head)
|
||||
+static void debug_match_lists(struct names *names_head, struct inode_list *ino_head, struct device_list *dev_head, )
|
||||
{
|
||||
struct names *nptr;
|
||||
struct inode_list *iptr;
|
||||
@@ -1280,3 +1486,56 @@ static void scan_knfsd(struct names *nam
|
||||
}
|
||||
}
|
||||
#endif /* NFSCHECKS */
|
||||
+
|
||||
+static sigjmp_buf jenv;
|
||||
+static int timeout = 5;
|
||||
+static void sigalarm(int sig)
|
||||
+{
|
||||
+ if (sig == SIGALRM)
|
||||
+ siglongjmp(jenv, 1);
|
||||
+}
|
||||
+static int nfssafe(stat_t func, const char *path, struct stat *buf)
|
||||
+{
|
||||
+ pid_t pid = 0;
|
||||
+ int ret = 0, pipes[4];
|
||||
+
|
||||
+ if (pipe(&pipes[0]) < 0)
|
||||
+ goto err;
|
||||
+ switch ((pid = fork ())) {
|
||||
+ case -1:
|
||||
+ close(pipes[0]);
|
||||
+ close(pipes[1]);
|
||||
+ goto err;
|
||||
+ case 0:
|
||||
+ (void) signal(SIGALRM, SIG_DFL);
|
||||
+ close(pipes[0]);
|
||||
+ if ((ret = func(path, buf)) == 0)
|
||||
+ write(pipes[1], buf, sizeof(struct stat));
|
||||
+ close(pipes[1]);
|
||||
+ exit(ret);
|
||||
+ default:
|
||||
+ close(pipes[1]);
|
||||
+ if (sigsetjmp(jenv, 1)) {
|
||||
+ (void) alarm(0);
|
||||
+ (void) signal(SIGALRM, SIG_DFL);
|
||||
+ if (waitpid(0, (int*)0, WNOHANG) == 0)
|
||||
+ kill(pid, SIGKILL);
|
||||
+ errno = ETIMEDOUT;
|
||||
+ timeout = 1;
|
||||
+ goto err;
|
||||
+ }
|
||||
+ (void) signal(SIGALRM, sigalarm);
|
||||
+ (void) alarm(timeout);
|
||||
+ if (read(pipes[0], buf, sizeof(struct stat)) == 0) {
|
||||
+ errno = EFAULT;
|
||||
+ ret = -1;
|
||||
+ }
|
||||
+ (void) alarm(0);
|
||||
+ (void) signal(SIGALRM, SIG_DFL);
|
||||
+ close(pipes[0]);
|
||||
+ break;
|
||||
+ }
|
||||
+ return ret;
|
||||
+err:
|
||||
+ return -1;
|
||||
+}
|
||||
--- src/fuser.h
|
||||
+++ src/fuser.h 2008-08-07 14:26:47.587191317 +0200
|
||||
+++ src/fuser.h 2008-08-07 14:26:48.000000000 +0200
|
||||
@@ -80,9 +80,16 @@ struct unixsocket_list {
|
||||
struct unixsocket_list *next;
|
||||
};
|
||||
|
@ -1,3 +1,8 @@
|
||||
-------------------------------------------------------------------
|
||||
Tue Sep 23 15:30:58 CEST 2008 - werner@suse.de
|
||||
|
||||
- Enhance NFS patch for fuser (bug #409011)
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Mon Sep 1 15:10:43 CEST 2008 - werner@suse.de
|
||||
|
||||
|
@ -27,7 +27,7 @@ Group: System/Monitoring
|
||||
PreReq: %fillup_prereq %insserv_prereq
|
||||
AutoReqProv: on
|
||||
Version: 22.6
|
||||
Release: 52
|
||||
Release: 59
|
||||
Provides: ps:/usr/bin/killall
|
||||
Summary: Utilities for managing processes on your system
|
||||
Source: http://switch.dl.sourceforge.net/sourceforge/psmisc/psmisc-%{version}.tar.bz2
|
||||
@ -103,6 +103,8 @@ rm -rf $RPM_BUILD_ROOT
|
||||
%{_mandir}/man1/pstree.1*
|
||||
|
||||
%changelog
|
||||
* Tue Sep 23 2008 werner@suse.de
|
||||
- Enhance NFS patch for fuser (bug #409011)
|
||||
* Mon Sep 01 2008 werner@suse.de
|
||||
- Do not leak on /proc/net/unix (bnc#417841)
|
||||
- Read /proc/net/unix and /proc/mounts only once
|
||||
|
Loading…
Reference in New Issue
Block a user