OBS User unknown 2008-09-24 15:25:01 +00:00 committed by Git OBS Bridge
parent 0cb55aafb0
commit 0999096aff
4 changed files with 140 additions and 69 deletions

View File

@ -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 */

View File

@ -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;
};

View File

@ -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

View File

@ -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