This commit is contained in:
parent
bf15efb9a1
commit
f8bc3d2cba
227
psmisc-22.6-memleaks.patch
Normal file
227
psmisc-22.6-memleaks.patch
Normal file
@ -0,0 +1,227 @@
|
|||||||
|
--- src/fuser.c
|
||||||
|
+++ src/fuser.c 2009-03-27 16:02:11.032550210 +0100
|
||||||
|
@@ -218,6 +218,9 @@ static void scan_procs(const opt_type op
|
||||||
|
if (islocatedon(&cwd_real[0], ino_tmp->name->filename))
|
||||||
|
add_matched_proc(ino_tmp->name, pid, uid, ACCESS_CWD);
|
||||||
|
}
|
||||||
|
+ if (root_stat) free(root_stat);
|
||||||
|
+ if (cwd_stat) free(cwd_stat);
|
||||||
|
+ if (exe_stat) free(exe_stat);
|
||||||
|
#ifndef __linux__
|
||||||
|
check_dir(pid, "lib", dev_head, ino_head, uid, ACCESS_MMAP);
|
||||||
|
check_dir(pid, "mmap", dev_head, ino_head, uid, ACCESS_MMAP);
|
||||||
|
@@ -232,10 +235,9 @@ static void add_inode(struct inode_list
|
||||||
|
{
|
||||||
|
struct inode_list *ino_tmp, *ino_head;
|
||||||
|
|
||||||
|
- ino_head = *ino_list;
|
||||||
|
-
|
||||||
|
- if ( (ino_tmp = malloc(sizeof(struct inode_list))) == NULL)
|
||||||
|
+ if ( (ino_tmp = (struct inode_list*)malloc(sizeof(struct inode_list))) == NULL)
|
||||||
|
return;
|
||||||
|
+ ino_head = *ino_list;
|
||||||
|
ino_tmp->name = this_name;
|
||||||
|
ino_tmp->device = device;
|
||||||
|
ino_tmp->inode = inode;
|
||||||
|
@@ -243,15 +245,15 @@ static void add_inode(struct inode_list
|
||||||
|
*ino_list = ino_tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void add_device(struct device_list **dev_list, struct names *this_name, dev_t device)
|
||||||
|
+static void add_device(struct device_list **restrict dev_list, struct names *this_name, dev_t device)
|
||||||
|
{
|
||||||
|
struct device_list *dev_tmp, *dev_head;
|
||||||
|
|
||||||
|
/*printf("Adding device %s %d\n", this_name->filename, device);*/
|
||||||
|
- dev_head = *dev_list;
|
||||||
|
|
||||||
|
- if ( (dev_tmp = malloc(sizeof(struct device_list))) == NULL)
|
||||||
|
+ if ( (dev_tmp = (struct device_list*)malloc(sizeof(struct device_list))) == NULL)
|
||||||
|
return;
|
||||||
|
+ dev_head = *dev_list;
|
||||||
|
dev_tmp->name = this_name;
|
||||||
|
dev_tmp->device = device;
|
||||||
|
dev_tmp->next = dev_head;
|
||||||
|
@@ -262,16 +264,14 @@ static void add_ip_conn(struct ip_connec
|
||||||
|
{
|
||||||
|
struct ip_connections *ip_tmp, *ip_head;
|
||||||
|
|
||||||
|
- ip_head = *ip_list;
|
||||||
|
-
|
||||||
|
if ( (ip_tmp = malloc(sizeof(struct ip_connections))) == NULL)
|
||||||
|
return;
|
||||||
|
+ ip_head = *ip_list;
|
||||||
|
ip_tmp->name = this_name;
|
||||||
|
ip_tmp->lcl_port = lcl_port;
|
||||||
|
ip_tmp->rmt_port = rmt_port;
|
||||||
|
ip_tmp->rmt_address.s_addr = rmt_address;
|
||||||
|
ip_tmp->next = ip_head;
|
||||||
|
-
|
||||||
|
*ip_list = ip_tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -280,10 +280,9 @@ static void add_ip6_conn(struct ip6_conn
|
||||||
|
{
|
||||||
|
struct ip6_connections *ip_tmp, *ip_head;
|
||||||
|
|
||||||
|
- ip_head = *ip_list;
|
||||||
|
-
|
||||||
|
if ( (ip_tmp = malloc(sizeof(struct ip6_connections))) == NULL)
|
||||||
|
return;
|
||||||
|
+ ip_head = *ip_list;
|
||||||
|
ip_tmp->name = this_name;
|
||||||
|
ip_tmp->lcl_port = lcl_port;
|
||||||
|
ip_tmp->rmt_port = rmt_port;
|
||||||
|
@@ -312,7 +311,7 @@ static void add_matched_proc(struct name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Not found */
|
||||||
|
- if ( (pptr = malloc(sizeof (struct procs))) == NULL) {
|
||||||
|
+ if ( (pptr = (struct procs*)malloc(sizeof (struct procs))) == NULL) {
|
||||||
|
fprintf(stderr,_("Cannot allocate memory for matched proc: %s\n"), strerror(errno));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
@@ -322,10 +321,13 @@ static void add_matched_proc(struct name
|
||||||
|
pptr->next = NULL;
|
||||||
|
/* set command name */
|
||||||
|
pptr->command = NULL;
|
||||||
|
+
|
||||||
|
+ fp = NULL;
|
||||||
|
+ pathname = NULL;
|
||||||
|
if ( (asprintf(&pathname, "/proc/%d/stat", pid) > 0) &&
|
||||||
|
( (fp = fopen(pathname, "r")) != NULL) &&
|
||||||
|
( fscanf(fp, "%*d (%100[^)]", cmdname) == 1))
|
||||||
|
- if ( (pptr->command = malloc(MAX_CMDNAME+1)) != NULL) {
|
||||||
|
+ if ( (pptr->command = (char*)malloc(MAX_CMDNAME+1)) != NULL) {
|
||||||
|
cmdlen = 0;
|
||||||
|
for (cptr = cmdname; cmdlen < MAX_CMDNAME && *cptr ; cptr++) {
|
||||||
|
if (isprint(*cptr))
|
||||||
|
@@ -339,6 +341,10 @@ static void add_matched_proc(struct name
|
||||||
|
name_list->matched_procs = pptr;
|
||||||
|
else
|
||||||
|
last_proc->next = pptr;
|
||||||
|
+ if (pathname)
|
||||||
|
+ free(pathname);
|
||||||
|
+ if (fp)
|
||||||
|
+ fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
int parse_mount(struct names *this_name, struct device_list **dev_list)
|
||||||
|
@@ -365,16 +371,16 @@ int parse_file(struct names *this_name,
|
||||||
|
|
||||||
|
real[0] = '\0';
|
||||||
|
if (check4nfs(this_name->filename, real)) {
|
||||||
|
- if ((opts & (OPT_MOUNTPOINT|OPT_MOUNTS)) == 0) {
|
||||||
|
+ if (this_name->filename)
|
||||||
|
free(this_name->filename);
|
||||||
|
- this_name->filename = strdup(real);
|
||||||
|
- this_name->name_space |= NAMESPACE_NFS;
|
||||||
|
- add_inode(ino_list, this_name, (dev_t)-1, (ino_t)-1);
|
||||||
|
- return 0;
|
||||||
|
- }
|
||||||
|
+ this_name->filename = strdup(real);
|
||||||
|
+ this_name->name_space |= NAMESPACE_NFS;
|
||||||
|
+ add_inode(ino_list, this_name, (dev_t)-1, (ino_t)-1);
|
||||||
|
+ return 0;
|
||||||
|
}
|
||||||
|
if (real[0] != '\0') {
|
||||||
|
- free(this_name->filename);
|
||||||
|
+ if (this_name->filename)
|
||||||
|
+ free(this_name->filename);
|
||||||
|
this_name->filename = strdup(real);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1211,22 +1217,26 @@ static struct stat *get_pidstat(const op
|
||||||
|
char pathname[256];
|
||||||
|
struct stat *st;
|
||||||
|
|
||||||
|
- if ( (st = malloc(sizeof(struct stat))) == NULL)
|
||||||
|
+ if ( (st = (struct stat*)malloc(sizeof(struct stat))) == NULL)
|
||||||
|
return NULL;
|
||||||
|
snprintf(pathname, 256, "/proc/%d/%s", pid, filename);
|
||||||
|
if (check4nfs(pathname, real)) {
|
||||||
|
- if ((opts & (OPT_MOUNTPOINT|OPT_MOUNTS)) == 0)
|
||||||
|
- return NULL;
|
||||||
|
+ if ((opts & (OPT_MOUNTPOINT|OPT_MOUNTS)) == 0) {
|
||||||
|
+ goto out;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
- if (stat(pathname, st) != 0)
|
||||||
|
- return NULL;
|
||||||
|
- else
|
||||||
|
- return st;
|
||||||
|
+ if (stat(pathname, st) != 0) {
|
||||||
|
+ goto out;
|
||||||
|
+ }
|
||||||
|
+ return st;
|
||||||
|
+out:
|
||||||
|
+ free(st);
|
||||||
|
+ return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
- char *dirpath, *filepath;
|
||||||
|
+ char *dirpath = NULL, *filepath = NULL;
|
||||||
|
DIR *dirp;
|
||||||
|
struct dirent *direntry;
|
||||||
|
struct inode_list *ino_tmp;
|
||||||
|
@@ -1234,13 +1244,13 @@ static void check_dir(const pid_t pid, c
|
||||||
|
struct stat st, lst;
|
||||||
|
|
||||||
|
if ( (dirpath = malloc(MAX_PATHNAME)) == NULL)
|
||||||
|
- return;
|
||||||
|
+ goto out;
|
||||||
|
if ( (filepath = malloc(MAX_PATHNAME)) == NULL)
|
||||||
|
- return;
|
||||||
|
+ goto out;
|
||||||
|
|
||||||
|
snprintf(dirpath, MAX_PATHNAME, "/proc/%d/%s", pid, dirname);
|
||||||
|
if ( (dirp = opendir(dirpath)) == NULL)
|
||||||
|
- return;
|
||||||
|
+ goto out;
|
||||||
|
while ( (direntry = readdir(dirp)) != NULL) {
|
||||||
|
if (direntry->d_name[0] < '0' || direntry->d_name[0] > '9')
|
||||||
|
continue;
|
||||||
|
@@ -1274,8 +1284,11 @@ static void check_dir(const pid_t pid, c
|
||||||
|
}
|
||||||
|
} /* while fd_dent */
|
||||||
|
closedir(dirp);
|
||||||
|
- free(dirpath);
|
||||||
|
- free(filepath);
|
||||||
|
+out:
|
||||||
|
+ if (dirpath)
|
||||||
|
+ free(dirpath);
|
||||||
|
+ if (filepath)
|
||||||
|
+ free(filepath);
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
@@ -1330,7 +1343,7 @@ void add_mount_device(struct mountdev_li
|
||||||
|
struct mountdev_list *newmount;
|
||||||
|
/*printf("Adding mount Path: %s Dir:%s dev:%0x\n",dir, fsname, device);*/
|
||||||
|
|
||||||
|
- if ( (newmount = malloc(sizeof(struct mountdev_list))) == NULL)
|
||||||
|
+ if ( (newmount = (struct mountdev_list*)malloc(sizeof(struct mountdev_list))) == NULL)
|
||||||
|
return;
|
||||||
|
newmount->fsname = strdup(fsname);
|
||||||
|
newmount->dir = strdup(dir);
|
||||||
|
@@ -1375,14 +1388,17 @@ void fill_unix_cache(struct unixsocket_l
|
||||||
|
free(path);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
- if ( (newsocket = malloc(sizeof(struct unixsocket_list))) == NULL)
|
||||||
|
+ if ( (newsocket = (struct unixsocket_list*)malloc(sizeof(struct unixsocket_list))) == NULL) {
|
||||||
|
+ free(path);
|
||||||
|
continue;
|
||||||
|
+ }
|
||||||
|
newsocket->sun_name = strdup(scanned_path);
|
||||||
|
newsocket->inode = st.st_ino;
|
||||||
|
newsocket->dev = st.st_dev;
|
||||||
|
newsocket->net_inode = scanned_inode;
|
||||||
|
newsocket->next = *unixsocket_head;
|
||||||
|
*unixsocket_head = newsocket;
|
||||||
|
+ free(path);
|
||||||
|
} /* while */
|
||||||
|
|
||||||
|
fclose(fp);
|
@ -33,7 +33,7 @@
|
|||||||
cannot report on any processes that it doesn't have permission to look at
|
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
|
the file descriptor table for. The most common time this problem occurs
|
||||||
--- src/fuser.c
|
--- src/fuser.c
|
||||||
+++ src/fuser.c 2009-03-12 10:21:40.980003767 +0100
|
+++ src/fuser.c 2009-03-27 14:06:48.860001275 +0100
|
||||||
@@ -32,9 +32,11 @@
|
@@ -32,9 +32,11 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -63,7 +63,7 @@
|
|||||||
static uid_t getpiduid(const pid_t pid);
|
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 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);
|
static void kill_matched_proc(struct procs *pptr, const opt_type opts, const int sig_number);
|
||||||
@@ -72,13 +75,18 @@ static void add_device(struct device_lis
|
@@ -72,13 +75,19 @@ static void add_device(struct device_lis
|
||||||
void scan_mount_devices(const opt_type opts, struct mountdev_list **mount_devices);
|
void scan_mount_devices(const opt_type opts, struct mountdev_list **mount_devices);
|
||||||
void fill_unix_cache(struct unixsocket_list **unixsocket_head);
|
void fill_unix_cache(struct unixsocket_list **unixsocket_head);
|
||||||
static dev_t find_net_dev(void);
|
static dev_t find_net_dev(void);
|
||||||
@ -76,6 +76,7 @@
|
|||||||
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);
|
||||||
#endif
|
#endif
|
||||||
+static struct nfs_points *mnts;
|
+static struct nfs_points *mnts;
|
||||||
|
+static void clear_mnt(void);
|
||||||
+static int check4nfs(const char * path, char * real);
|
+static int check4nfs(const char * path, char * real);
|
||||||
+
|
+
|
||||||
+typedef int (*stat_t)(const char*, struct stat*);
|
+typedef int (*stat_t)(const char*, struct stat*);
|
||||||
@ -83,7 +84,7 @@
|
|||||||
|
|
||||||
static void usage (const char *errormsg)
|
static void usage (const char *errormsg)
|
||||||
{
|
{
|
||||||
@@ -127,7 +135,14 @@ void print_version()
|
@@ -127,7 +136,14 @@ void print_version()
|
||||||
"For more information about these matters, see the files named COPYING.\n"));
|
"For more information about these matters, see the files named COPYING.\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,7 +100,7 @@
|
|||||||
{
|
{
|
||||||
DIR *topproc_dir;
|
DIR *topproc_dir;
|
||||||
struct dirent *topproc_dent;
|
struct dirent *topproc_dent;
|
||||||
@@ -137,6 +152,9 @@ static void scan_procs(struct names *nam
|
@@ -137,6 +153,9 @@ static void scan_procs(struct names *nam
|
||||||
pid_t pid, my_pid;
|
pid_t pid, my_pid;
|
||||||
uid_t uid;
|
uid_t uid;
|
||||||
struct stat *cwd_stat, *exe_stat, *root_stat;
|
struct stat *cwd_stat, *exe_stat, *root_stat;
|
||||||
@ -109,7 +110,7 @@
|
|||||||
|
|
||||||
if ( (fd_dirpath = malloc(MAX_PATHNAME)) == NULL)
|
if ( (fd_dirpath = malloc(MAX_PATHNAME)) == NULL)
|
||||||
return;
|
return;
|
||||||
@@ -157,9 +175,10 @@ static void scan_procs(struct names *nam
|
@@ -157,9 +176,10 @@ static void scan_procs(struct names *nam
|
||||||
continue;
|
continue;
|
||||||
uid = getpiduid(pid);
|
uid = getpiduid(pid);
|
||||||
|
|
||||||
@ -123,7 +124,7 @@
|
|||||||
/* Scan the devices */
|
/* Scan the devices */
|
||||||
for (dev_tmp = dev_head ; dev_tmp != NULL ; dev_tmp = dev_tmp->next) {
|
for (dev_tmp = dev_head ; dev_tmp != NULL ; dev_tmp = dev_tmp->next) {
|
||||||
if (exe_stat != NULL && exe_stat->st_dev == dev_tmp->device)
|
if (exe_stat != NULL && exe_stat->st_dev == dev_tmp->device)
|
||||||
@@ -168,6 +187,14 @@ static void scan_procs(struct names *nam
|
@@ -168,6 +188,14 @@ static void scan_procs(struct names *nam
|
||||||
add_matched_proc(dev_tmp->name, pid, uid, ACCESS_ROOT);
|
add_matched_proc(dev_tmp->name, pid, uid, ACCESS_ROOT);
|
||||||
if (cwd_stat != NULL && cwd_stat->st_dev == dev_tmp->device)
|
if (cwd_stat != NULL && cwd_stat->st_dev == dev_tmp->device)
|
||||||
add_matched_proc(dev_tmp->name, pid, uid, ACCESS_CWD);
|
add_matched_proc(dev_tmp->name, pid, uid, ACCESS_CWD);
|
||||||
@ -138,7 +139,7 @@
|
|||||||
}
|
}
|
||||||
for (ino_tmp = ino_head ; ino_tmp != NULL ; ino_tmp = ino_tmp->next) {
|
for (ino_tmp = ino_head ; ino_tmp != NULL ; ino_tmp = ino_tmp->next) {
|
||||||
if (exe_stat != NULL) {
|
if (exe_stat != NULL) {
|
||||||
@@ -186,9 +213,19 @@ static void scan_procs(struct names *nam
|
@@ -186,9 +214,19 @@ static void scan_procs(struct names *nam
|
||||||
add_matched_proc(ino_tmp->name, pid, uid, ACCESS_CWD);
|
add_matched_proc(ino_tmp->name, pid, uid, ACCESS_CWD);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -158,7 +159,7 @@
|
|||||||
check_dir(pid, "fd", dev_head, ino_head, uid, ACCESS_FILE);
|
check_dir(pid, "fd", dev_head, ino_head, uid, ACCESS_FILE);
|
||||||
check_map(pid, "maps", dev_head, ino_head, uid, ACCESS_MMAP);
|
check_map(pid, "maps", dev_head, ino_head, uid, ACCESS_MMAP);
|
||||||
|
|
||||||
@@ -325,10 +362,26 @@ int parse_mount(struct names *this_name,
|
@@ -325,10 +363,26 @@ int parse_mount(struct names *this_name,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,7 +187,7 @@
|
|||||||
if (stat(this_name->filename, &st) != 0) {
|
if (stat(this_name->filename, &st) != 0) {
|
||||||
fprintf(stderr,_("Cannot stat %s: %s\n"), this_name->filename,
|
fprintf(stderr,_("Cannot stat %s: %s\n"), this_name->filename,
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
@@ -342,34 +395,44 @@ int parse_file(struct names *this_name,
|
@@ -342,34 +396,44 @@ int parse_file(struct names *this_name,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,7 +239,7 @@
|
|||||||
|
|
||||||
if (stat(this_name->filename, &st) != 0) {
|
if (stat(this_name->filename, &st) != 0) {
|
||||||
fprintf(stderr,_("Cannot stat %s: %s\n"), this_name->filename,
|
fprintf(stderr,_("Cannot stat %s: %s\n"), this_name->filename,
|
||||||
@@ -388,6 +451,16 @@ int parse_mounts(struct names *this_name
|
@@ -388,6 +452,16 @@ int parse_mounts(struct names *this_name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -255,10 +256,76 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WITH_IPV6
|
#ifdef WITH_IPV6
|
||||||
@@ -652,6 +725,85 @@ void find_net6_sockets(struct inode_list
|
@@ -652,6 +726,150 @@ void find_net6_sockets(struct inode_list
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * Remove struct nfs_points and its sahdows from memory
|
||||||
|
+ */
|
||||||
|
+static void clear_shadow(struct shadow_list *restrict shadow)
|
||||||
|
+{
|
||||||
|
+ struct shadow_list *s, *n, *l;
|
||||||
|
+
|
||||||
|
+ n = shadow;
|
||||||
|
+ l = (struct shadow_list*)0;
|
||||||
|
+ for (s = shadow; n; s = n) {
|
||||||
|
+ l = s->prev;
|
||||||
|
+ n = s->next;
|
||||||
|
+ if (s == shadow) {
|
||||||
|
+ if (n) n->prev = (struct shadow_list*)0;
|
||||||
|
+ shadow = n;
|
||||||
|
+ } else if (l) {
|
||||||
|
+ if (n) n->prev = l;
|
||||||
|
+ l->next = n;
|
||||||
|
+ }
|
||||||
|
+ free(s);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void clear_mnt(void)
|
||||||
|
+{
|
||||||
|
+ struct nfs_points *p, *n, *l;
|
||||||
|
+
|
||||||
|
+ n = mnts;
|
||||||
|
+ l = (struct nfs_points*)0;
|
||||||
|
+ for (p = mnts; n; p = n) {
|
||||||
|
+ l = p->prev;
|
||||||
|
+ n = p->next;
|
||||||
|
+ if (p == mnts) {
|
||||||
|
+ if (n) n->prev = (struct nfs_points*)0;
|
||||||
|
+ mnts = n;
|
||||||
|
+ } else if (l) {
|
||||||
|
+ if (n) n->prev = l;
|
||||||
|
+ l->next = n;
|
||||||
|
+ }
|
||||||
|
+ if (p->shadow)
|
||||||
|
+ clear_shadow(p->shadow);
|
||||||
|
+ free(p);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Check if path is ia shadow off a NFS partition.
|
||||||
|
+ */
|
||||||
|
+static int shadow(struct shadow_list *restrict this, const char *restrict name, const size_t nlen)
|
||||||
|
+{
|
||||||
|
+ struct shadow_list *s;
|
||||||
|
+
|
||||||
|
+ if (!this)
|
||||||
|
+ goto out;
|
||||||
|
+ for (s = this; s; s = s->next) {
|
||||||
|
+ if (nlen < s->nlen)
|
||||||
|
+ continue;
|
||||||
|
+ if (name[s->nlen] != '\0' && name[s->nlen] != '/')
|
||||||
|
+ continue;
|
||||||
|
+ if (strncmp(name, s->name, s->nlen) == 0)
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+out:
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
+/*
|
+/*
|
||||||
+ * Check path is located on a NFS partition.
|
+ * Check path is located on a NFS partition.
|
||||||
+ */
|
+ */
|
||||||
@ -320,18 +387,17 @@
|
|||||||
+
|
+
|
||||||
+ if (errno == EINVAL) {
|
+ if (errno == EINVAL) {
|
||||||
+ const size_t nlen = strlen(curr);
|
+ const size_t nlen = strlen(curr);
|
||||||
+ struct nfs_points *p, *n, *l;
|
+ struct nfs_points *p;
|
||||||
+ n = mnts;
|
+ for (p = mnts; p; p = p->next) {
|
||||||
+ l = (struct nfs_points*)0;
|
|
||||||
+ for (p = mnts; n; p = n) {
|
|
||||||
+ l = p->prev;
|
|
||||||
+ n = p->next;
|
|
||||||
+ if (nlen < p->nlen)
|
+ if (nlen < p->nlen)
|
||||||
+ continue;
|
+ continue;
|
||||||
+ if (curr[p->nlen] != '\0' && curr[p->nlen] != '/')
|
+ if (curr[p->nlen] != '\0' && curr[p->nlen] != '/')
|
||||||
+ continue;
|
+ continue;
|
||||||
+ if (!strncmp(curr, p->name, p->nlen))
|
+ if (!strncmp(curr, p->name, p->nlen)) {
|
||||||
|
+ if (shadow(p->shadow, curr, nlen))
|
||||||
|
+ continue;
|
||||||
+ return 1;
|
+ return 1;
|
||||||
|
+ }
|
||||||
+ }
|
+ }
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
@ -341,7 +407,7 @@
|
|||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
opt_type opts;
|
opt_type opts;
|
||||||
@@ -676,6 +828,7 @@ int main(int argc, char *argv[])
|
@@ -676,6 +894,7 @@ int main(int argc, char *argv[])
|
||||||
int optc;
|
int optc;
|
||||||
char *option;
|
char *option;
|
||||||
char *nsptr;
|
char *nsptr;
|
||||||
@ -349,7 +415,7 @@
|
|||||||
|
|
||||||
#ifdef WITH_IPV6
|
#ifdef WITH_IPV6
|
||||||
ipv4_only = ipv6_only = 0;
|
ipv4_only = ipv6_only = 0;
|
||||||
@@ -692,7 +845,6 @@ int main(int argc, char *argv[])
|
@@ -692,7 +911,6 @@ int main(int argc, char *argv[])
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
netdev = find_net_dev();
|
netdev = find_net_dev();
|
||||||
@ -357,7 +423,7 @@
|
|||||||
fill_unix_cache(&unixsockets);
|
fill_unix_cache(&unixsockets);
|
||||||
|
|
||||||
/* getopt doesnt like things like -SIGBLAH */
|
/* getopt doesnt like things like -SIGBLAH */
|
||||||
@@ -782,6 +934,10 @@ int main(int argc, char *argv[])
|
@@ -782,6 +1000,10 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -368,7 +434,7 @@
|
|||||||
/* File specifications */
|
/* File specifications */
|
||||||
if ( (this_name = malloc(sizeof(struct names))) == NULL)
|
if ( (this_name = malloc(sizeof(struct names))) == NULL)
|
||||||
continue;
|
continue;
|
||||||
@@ -828,10 +984,14 @@ int main(int argc, char *argv[])
|
@@ -828,10 +1050,14 @@ int main(int argc, char *argv[])
|
||||||
break;
|
break;
|
||||||
default: /* FILE */
|
default: /* FILE */
|
||||||
this_name->filename = strdup(argv[optc]);
|
this_name->filename = strdup(argv[optc]);
|
||||||
@ -386,7 +452,7 @@
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -857,22 +1017,22 @@ int main(int argc, char *argv[])
|
@@ -857,25 +1083,26 @@ int main(int argc, char *argv[])
|
||||||
if (!ipv4_only) {
|
if (!ipv4_only) {
|
||||||
#endif
|
#endif
|
||||||
if (tcp_connection_list != NULL)
|
if (tcp_connection_list != NULL)
|
||||||
@ -414,7 +480,11 @@
|
|||||||
#ifdef NFS_CHECKS
|
#ifdef NFS_CHECKS
|
||||||
scan_knfsd(names_head, match_devices);
|
scan_knfsd(names_head, match_devices);
|
||||||
#endif /* NFS_CHECKS */
|
#endif /* NFS_CHECKS */
|
||||||
@@ -978,7 +1138,7 @@ static int print_matches(struct names *n
|
+ clear_mnt();
|
||||||
|
return print_matches(names_head,opts, sig_number);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -978,7 +1205,7 @@ static int print_matches(struct names *n
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -423,7 +493,7 @@
|
|||||||
{
|
{
|
||||||
char pathname[256];
|
char pathname[256];
|
||||||
struct stat *st;
|
struct stat *st;
|
||||||
@@ -986,6 +1146,10 @@ static struct stat *get_pidstat(const pi
|
@@ -986,6 +1213,10 @@ static struct stat *get_pidstat(const pi
|
||||||
if ( (st = malloc(sizeof(struct stat))) == NULL)
|
if ( (st = malloc(sizeof(struct stat))) == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
snprintf(pathname, 256, "/proc/%d/%s", pid, filename);
|
snprintf(pathname, 256, "/proc/%d/%s", pid, filename);
|
||||||
@ -434,7 +504,7 @@
|
|||||||
if (stat(pathname, st) != 0)
|
if (stat(pathname, st) != 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
else
|
else
|
||||||
@@ -1012,13 +1176,14 @@ static void check_dir(const pid_t pid, c
|
@@ -1012,13 +1243,14 @@ static void check_dir(const pid_t pid, c
|
||||||
while ( (direntry = readdir(dirp)) != NULL) {
|
while ( (direntry = readdir(dirp)) != NULL) {
|
||||||
if (direntry->d_name[0] < '0' || direntry->d_name[0] > '9')
|
if (direntry->d_name[0] < '0' || direntry->d_name[0] > '9')
|
||||||
continue;
|
continue;
|
||||||
@ -450,7 +520,7 @@
|
|||||||
if (st.st_dev == dev_tmp->device) {
|
if (st.st_dev == dev_tmp->device) {
|
||||||
if (access == ACCESS_FILE && (lstat(filepath, &lst)==0) && (lst.st_mode & S_IWUSR)) {
|
if (access == ACCESS_FILE && (lstat(filepath, &lst)==0) && (lst.st_mode & S_IWUSR)) {
|
||||||
add_matched_proc(dev_tmp->name, pid,uid, ACCESS_FILEWR|access);
|
add_matched_proc(dev_tmp->name, pid,uid, ACCESS_FILEWR|access);
|
||||||
@@ -1028,6 +1193,8 @@ static void check_dir(const pid_t pid, c
|
@@ -1028,6 +1260,8 @@ static void check_dir(const pid_t pid, c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (ino_tmp = ino_head ; ino_tmp != NULL ; ino_tmp = ino_tmp->next) {
|
for (ino_tmp = ino_head ; ino_tmp != NULL ; ino_tmp = ino_tmp->next) {
|
||||||
@ -459,7 +529,7 @@
|
|||||||
if (st.st_dev == ino_tmp->device && st.st_ino == ino_tmp->inode) {
|
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)) {
|
if (access == ACCESS_FILE && (lstat(filepath, &lst)==0) && (lst.st_mode & S_IWUSR)) {
|
||||||
add_matched_proc(ino_tmp->name, pid,uid, ACCESS_FILEWR|access);
|
add_matched_proc(ino_tmp->name, pid,uid, ACCESS_FILEWR|access);
|
||||||
@@ -1039,6 +1206,8 @@ static void check_dir(const pid_t pid, c
|
@@ -1039,6 +1273,8 @@ static void check_dir(const pid_t pid, c
|
||||||
}
|
}
|
||||||
} /* while fd_dent */
|
} /* while fd_dent */
|
||||||
closedir(dirp);
|
closedir(dirp);
|
||||||
@ -468,7 +538,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)
|
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 +1228,18 @@ static void check_map(const pid_t pid, c
|
@@ -1059,12 +1295,18 @@ static void check_map(const pid_t pid, c
|
||||||
if (sscanf(line, "%*s %*s %*s %x:%x %lld",
|
if (sscanf(line, "%*s %*s %*s %x:%x %lld",
|
||||||
&tmp_maj, &tmp_min, &tmp_inode) == 3) {
|
&tmp_maj, &tmp_min, &tmp_inode) == 3) {
|
||||||
tmp_device = tmp_maj * 256 + tmp_min;
|
tmp_device = tmp_maj * 256 + tmp_min;
|
||||||
@ -489,7 +559,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
@@ -1135,6 +1310,16 @@ void fill_unix_cache(struct unixsocket_l
|
@@ -1135,6 +1377,16 @@ void fill_unix_cache(struct unixsocket_l
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -506,21 +576,22 @@
|
|||||||
/*
|
/*
|
||||||
* scan_mount_devices : Create a list of mount points and devices
|
* scan_mount_devices : Create a list of mount points and devices
|
||||||
* This list is used later for matching purposes
|
* This list is used later for matching purposes
|
||||||
@@ -1144,17 +1329,53 @@ void scan_mount_devices(const opt_type o
|
@@ -1144,17 +1396,94 @@ void scan_mount_devices(const opt_type o
|
||||||
FILE *mntfp;
|
FILE *mntfp;
|
||||||
struct mntent *mnt_ptr;
|
struct mntent *mnt_ptr;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
-
|
-
|
||||||
- if ( (mntfp = setmntent("/etc/mtab","r")) == NULL) {
|
- if ( (mntfp = setmntent("/etc/mtab","r")) == NULL) {
|
||||||
- fprintf(stderr, _("Cannot open /etc/mtab: %s\n"),
|
+ const char * mtab;
|
||||||
- strerror(errno));
|
|
||||||
+
|
+
|
||||||
+ if (stat("/proc/version", &st) < 0)
|
+ if (stat("/proc/version", &st) < 0)
|
||||||
+ mntfp = setmntent("/etc/mtab","r");
|
+ mtab = "/etc/mtab";
|
||||||
+ else
|
+ else
|
||||||
+ mntfp = setmntent("/proc/mounts", "r");
|
+ mtab = "/proc/mounts";
|
||||||
+ if (mntfp == NULL) {
|
+
|
||||||
+ fprintf(stderr, _("Cannot open /etc/mtab: %s\n"), strerror(errno));
|
+ if ( (mntfp = setmntent(mtab,"r")) == NULL) {
|
||||||
|
fprintf(stderr, _("Cannot open /etc/mtab: %s\n"),
|
||||||
|
strerror(errno));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while ( (mnt_ptr = getmntent(mntfp)) != NULL) {
|
while ( (mnt_ptr = getmntent(mntfp)) != NULL) {
|
||||||
@ -528,13 +599,15 @@
|
|||||||
+ /*
|
+ /*
|
||||||
+ * Remember all NFS typed partitions, required to make check4nfs() work.
|
+ * Remember all NFS typed partitions, required to make check4nfs() work.
|
||||||
+ */
|
+ */
|
||||||
+ struct nfs_points * p = (struct nfs_points*)malloc(sizeof(struct nfs_points));
|
+ size_t nlen = strlen(mnt_ptr->mnt_dir);
|
||||||
+ if (!p)
|
+ struct nfs_points *restrict p;
|
||||||
|
+ if (posix_memalign((void*)&p, sizeof(void*), alignof(struct nfs_points)+(nlen+1)) != 0)
|
||||||
+ goto out;
|
+ goto out;
|
||||||
+ p->name = strdup(mnt_ptr->mnt_dir);
|
+ p->name = ((char*)p)+alignof(struct nfs_points);
|
||||||
+ if (!p->name)
|
+ p->nlen = nlen;
|
||||||
+ goto out;
|
+ p->shadow = (struct shadow_list*)0;
|
||||||
+ p->nlen = strlen(p->name);
|
+
|
||||||
|
+ strcpy(p->name, mnt_ptr->mnt_dir);
|
||||||
+ if (mnts)
|
+ if (mnts)
|
||||||
+ mnts->prev = p;
|
+ mnts->prev = p;
|
||||||
+ p->next = mnts;
|
+ p->next = mnts;
|
||||||
@ -557,6 +630,42 @@
|
|||||||
add_mount_device(mount_devices, mnt_ptr->mnt_fsname, mnt_ptr->mnt_dir, st.st_dev);
|
add_mount_device(mount_devices, mnt_ptr->mnt_fsname, mnt_ptr->mnt_dir, st.st_dev);
|
||||||
+ } else {
|
+ } else {
|
||||||
+ fprintf(stderr, _("Cannot stat file %s: %s\n"), mnt_ptr->mnt_dir, strerror(errno));
|
+ fprintf(stderr, _("Cannot stat file %s: %s\n"), mnt_ptr->mnt_dir, strerror(errno));
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ endmntent(mntfp);
|
||||||
|
+
|
||||||
|
+ if (!mnts)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ if ((mntfp = setmntent("/proc/mounts", "r")) == NULL) {
|
||||||
|
+ fprintf(stderr, _("Cannot open /etc/mtab: %s\n"), strerror(errno));
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ while ((mnt_ptr = getmntent(mntfp)) != NULL) {
|
||||||
|
+ struct nfs_points *p;
|
||||||
|
+
|
||||||
|
+ for (p = mnts; p; p = p->next) {
|
||||||
|
+ struct shadow_list *s;
|
||||||
|
+ size_t nlen;
|
||||||
|
+
|
||||||
|
+ if (strcmp(mnt_ptr->mnt_dir, p->name) == 0)
|
||||||
|
+ continue;
|
||||||
|
+ if (strncmp(mnt_ptr->mnt_dir, p->name, p->nlen) != 0)
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ nlen = strlen(mnt_ptr->mnt_dir);
|
||||||
|
+ if (posix_memalign((void*)&s, sizeof(void*), alignof(struct shadow_list)+(nlen+1)) != 0)
|
||||||
|
+ goto out;
|
||||||
|
+ s->name = ((char*)s)+alignof(struct shadow_list);
|
||||||
|
+ s->nlen = nlen;
|
||||||
|
+
|
||||||
|
+ strcpy(s->name, mnt_ptr->mnt_dir);
|
||||||
|
+ if (p->shadow)
|
||||||
|
+ p->shadow->prev = s;
|
||||||
|
+ s->next = p->shadow;
|
||||||
|
+ s->prev = (struct shadow_list*)0;
|
||||||
|
+ p->shadow = s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+out:
|
+out:
|
||||||
@ -564,7 +673,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
@@ -1280,3 +1501,56 @@ static void scan_knfsd(struct names *nam
|
@@ -1280,3 +1609,56 @@ static void scan_knfsd(struct names *nam
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* NFSCHECKS */
|
#endif /* NFSCHECKS */
|
||||||
@ -622,16 +731,33 @@
|
|||||||
+ return -1;
|
+ return -1;
|
||||||
+}
|
+}
|
||||||
--- src/fuser.h
|
--- src/fuser.h
|
||||||
+++ src/fuser.h 2008-08-07 14:26:48.000000000 +0200
|
+++ src/fuser.h 2009-03-27 13:23:36.136000974 +0100
|
||||||
@@ -80,9 +80,16 @@ struct unixsocket_list {
|
@@ -80,9 +80,33 @@ struct unixsocket_list {
|
||||||
struct unixsocket_list *next;
|
struct unixsocket_list *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
+struct shadow_list
|
||||||
|
+{
|
||||||
|
+ struct shadow_list *next;
|
||||||
|
+ struct shadow_list *prev;
|
||||||
|
+ size_t nlen;
|
||||||
|
+ char * name;
|
||||||
|
+};
|
||||||
|
+
|
||||||
+struct nfs_points {
|
+struct nfs_points {
|
||||||
+ struct nfs_points *next, *prev;
|
+ struct nfs_points *next, *prev;
|
||||||
+ char * name;
|
+ struct shadow_list *shadow;
|
||||||
+ size_t nlen;
|
+ size_t nlen;
|
||||||
|
+ char * name;
|
||||||
+};
|
+};
|
||||||
|
+
|
||||||
|
+#if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L)
|
||||||
|
+# ifndef restrict
|
||||||
|
+# define restrict __restrict__
|
||||||
|
+# endif
|
||||||
|
+#endif
|
||||||
|
+#define alignof(type) ((sizeof(type)+(sizeof(void*)-1)) & ~(sizeof(void*)-1))
|
||||||
|
+
|
||||||
+
|
+
|
||||||
#define NAMESPACE_FILE 0
|
#define NAMESPACE_FILE 0
|
||||||
#define NAMESPACE_TCP 1
|
#define NAMESPACE_TCP 1
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
-------------------------------------------------------------------
|
||||||
|
Fri Mar 27 16:56:24 CET 2009 - werner@suse.de
|
||||||
|
|
||||||
|
- nfs4fuser: do not match on shadow mounts
|
||||||
|
- resolve some memory leaks in fuser
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Thu Mar 12 10:23:12 CET 2009 - werner@suse.de
|
Thu Mar 12 10:23:12 CET 2009 - werner@suse.de
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ Group: System/Monitoring
|
|||||||
PreReq: %fillup_prereq %insserv_prereq
|
PreReq: %fillup_prereq %insserv_prereq
|
||||||
AutoReqProv: on
|
AutoReqProv: on
|
||||||
Version: 22.6
|
Version: 22.6
|
||||||
Release: 63
|
Release: 64
|
||||||
Provides: ps:/usr/bin/killall
|
Provides: ps:/usr/bin/killall
|
||||||
Summary: Utilities for managing processes on your system
|
Summary: Utilities for managing processes on your system
|
||||||
Source: http://switch.dl.sourceforge.net/sourceforge/psmisc/psmisc-%{version}.tar.bz2
|
Source: http://switch.dl.sourceforge.net/sourceforge/psmisc/psmisc-%{version}.tar.bz2
|
||||||
@ -38,6 +38,7 @@ Patch3: %name-22.6-netunix.patch
|
|||||||
Patch4: %name-22.6-writeonly.patch
|
Patch4: %name-22.6-writeonly.patch
|
||||||
Patch5: %name-22.6-fdleak.patch
|
Patch5: %name-22.6-fdleak.patch
|
||||||
Patch6: %name-22.6-tigetstr.patch
|
Patch6: %name-22.6-tigetstr.patch
|
||||||
|
Patch7: %name-22.6-memleaks.patch
|
||||||
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||||
%define nopeek s390 s390x ia64
|
%define nopeek s390 s390x ia64
|
||||||
|
|
||||||
@ -63,6 +64,7 @@ Authors:
|
|||||||
%patch4 -p0 -b .wrtonly
|
%patch4 -p0 -b .wrtonly
|
||||||
%patch5 -p0 -b .fdleak
|
%patch5 -p0 -b .fdleak
|
||||||
%patch6 -p0 -b .tigetstr
|
%patch6 -p0 -b .tigetstr
|
||||||
|
%patch7 -p0 -b .memleaks
|
||||||
%patch0 -p0
|
%patch0 -p0
|
||||||
|
|
||||||
%build
|
%build
|
||||||
@ -105,6 +107,9 @@ rm -rf $RPM_BUILD_ROOT
|
|||||||
%{_mandir}/man1/pstree.1*
|
%{_mandir}/man1/pstree.1*
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Fri Mar 27 2009 werner@suse.de
|
||||||
|
- nfs4fuser: do not match on shadow mounts
|
||||||
|
- resolve some memory leaks in fuser
|
||||||
* Thu Mar 12 2009 werner@suse.de
|
* Thu Mar 12 2009 werner@suse.de
|
||||||
- nfs4fuser: be able to detect the root file system (bnc#464295)
|
- nfs4fuser: be able to detect the root file system (bnc#464295)
|
||||||
* Wed Mar 11 2009 werner@suse.de
|
* Wed Mar 11 2009 werner@suse.de
|
||||||
|
Loading…
Reference in New Issue
Block a user