Skip to content

Commit a70e6fe

Browse files
committed
Move static variables in process_id to lsof_ctx_dialect for thread safety
1 parent 9dfa9a7 commit a70e6fe

4 files changed

Lines changed: 95 additions & 49 deletions

File tree

lib/dialects/linux/dlsof.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,4 +91,28 @@ void lsof_dialect_destroy(struct lsof_context *ctx) {
9191
CLEAN(Vbuf);
9292
Vsz = 0;
9393
}
94+
95+
/* Free /proc/FD/fd buffer */
96+
if (Dpath) {
97+
CLEAN(Dpath);
98+
Dpathl = 0;
99+
}
100+
101+
/* Free /proc/FD/fdinfo buffer */
102+
if (Ipath) {
103+
CLEAN(Ipath);
104+
Ipathl = 0;
105+
}
106+
107+
/* Free /proc/FD/fdinfo/%d buffer */
108+
if (Pathi) {
109+
CLEAN(Pathi);
110+
Pathil = 0;
111+
}
112+
113+
/* Free /proc/FD/ temp buffer */
114+
if (Path) {
115+
CLEAN(Path);
116+
Pathl = 0;
117+
}
94118
}

lib/dialects/linux/dlsof.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,18 @@ struct lsof_context_dialect {
226226
/* dnode.c - lock stream buffer */
227227
char *lock_stream_buf;
228228
size_t lock_stream_buf_sz;
229+
/* dproc.c - /proc/FD/fd buffer */
230+
char *fd_path_buf;
231+
int fd_path_buf_sz;
232+
/* dproc.c - /proc/FD/fdinfo buffer */
233+
char *fdinfo_path_buf;
234+
int fdinfo_path_buf_sz;
235+
/* dproc.c - /proc/FD/fdinfo/%d buffer */
236+
char *fdinfo_entry_path_buf;
237+
int fdinfo_entry_path_buf_sz;
238+
/* dproc.c - /proc/FD temp buffer */
239+
char *temp_path_buf;
240+
int temp_path_buf_sz;
229241
};
230242

231243
/* Dialect-specific cleanup function */
@@ -250,4 +262,20 @@ void lsof_dialect_destroy(struct lsof_context *ctx);
250262
# define Vbuf (ctx->dialect.lock_stream_buf)
251263
# define Vsz (ctx->dialect.lock_stream_buf_sz)
252264

265+
/* /proc/FD/fd path buffer macros */
266+
# define Dpath (ctx->dialect.fd_path_buf)
267+
# define Dpathl (ctx->dialect.fd_path_buf_sz)
268+
269+
/* /proc/FD/fdinfo path buffer macros */
270+
# define Ipath (ctx->dialect.fdinfo_path_buf)
271+
# define Ipathl (ctx->dialect.fdinfo_path_buf_sz)
272+
273+
/* /proc/FD/fdinfo/%d path buffer macros */
274+
# define Pathi (ctx->dialect.fdinfo_entry_path_buf)
275+
# define Pathil (ctx->dialect.fdinfo_entry_path_buf_sz)
276+
277+
/* /proc/FD temp path buffer macros */
278+
# define Path (ctx->dialect.temp_path_buf)
279+
# define Pathl (ctx->dialect.temp_path_buf_sz)
280+
253281
#endif /* LINUX_LSOF_H */

lib/dialects/linux/dproc.c

Lines changed: 41 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -898,23 +898,15 @@ static int process_id(struct lsof_context *ctx, /* context */
898898
char *tcmd) /* task command, if non-NULL) */
899899
{
900900
int av = 0;
901-
static char *dpath = (char *)NULL;
902-
static int dpathl = 0;
903901
short efs, enls, enss, lnk, oty, pn, pss, sf;
904902
int fd, i, ls = 0, n, ss, sv;
905903
struct l_fdinfo fi;
906904
DIR *fdp;
907905
struct dirent *fp;
908-
static char *ipath = (char *)NULL;
909-
static int ipathl = 0;
910906
int j = 0;
911907
struct lfile *lfr;
912908
struct stat lsb, sb;
913909
char nmabuf[MAXPATHLEN + 1], pbuf[MAXPATHLEN + 1];
914-
static char *path = (char *)NULL;
915-
static int pathl = 0;
916-
static char *pathi = (char *)NULL;
917-
static int pathil = 0;
918910
char *rest;
919911
int txts = 0;
920912
int enss_fd = 0;
@@ -970,9 +962,9 @@ static int process_id(struct lsof_context *ctx, /* context */
970962
*/
971963
efs = 0;
972964
if (!Ckscko) {
973-
(void)make_proc_path(ctx, idp, idpl, &path, &pathl, "cwd");
965+
(void)make_proc_path(ctx, idp, idpl, &Path, &Pathl, "cwd");
974966
alloc_lfile(ctx, LSOF_FD_CWD, -1);
975-
if (getlinksrc(path, pbuf, sizeof(pbuf), (char **)NULL) < 1) {
967+
if (getlinksrc(Path, pbuf, sizeof(pbuf), (char **)NULL) < 1) {
976968
if (!Fwarn) {
977969
zeromem((char *)&sb, sizeof(sb));
978970
lnk = ss = 0;
@@ -992,10 +984,10 @@ static int process_id(struct lsof_context *ctx, /* context */
992984
} else {
993985
ss = SB_ALL;
994986
if (HasNFS) {
995-
if ((sv = statsafely(ctx, path, &sb)))
987+
if ((sv = statsafely(ctx, Path, &sb)))
996988
sv = statEx(ctx, pbuf, &sb, &ss);
997989
} else
998-
sv = stat(path, &sb);
990+
sv = stat(Path, &sb);
999991
if (sv) {
1000992
ss = 0;
1001993
if (!Fwarn) {
@@ -1008,7 +1000,7 @@ static int process_id(struct lsof_context *ctx, /* context */
10081000
}
10091001
}
10101002
if (pn) {
1011-
(void)process_proc_node(ctx, lnk ? pbuf : path, path, &sb, ss,
1003+
(void)process_proc_node(ctx, lnk ? pbuf : Path, Path, &sb, ss,
10121004
(struct stat *)NULL, 0);
10131005
if (Lf->sf)
10141006
link_lfile(ctx);
@@ -1019,9 +1011,9 @@ static int process_id(struct lsof_context *ctx, /* context */
10191011
*/
10201012
lnk = ss = 0;
10211013
if (!Ckscko) {
1022-
(void)make_proc_path(ctx, idp, idpl, &path, &pathl, "root");
1014+
(void)make_proc_path(ctx, idp, idpl, &Path, &Pathl, "root");
10231015
alloc_lfile(ctx, LSOF_FD_ROOT_DIR, -1);
1024-
if (getlinksrc(path, pbuf, sizeof(pbuf), (char **)NULL) < 1) {
1016+
if (getlinksrc(Path, pbuf, sizeof(pbuf), (char **)NULL) < 1) {
10251017
if (!Fwarn) {
10261018
zeromem((char *)&sb, sizeof(sb));
10271019
(void)snpf(nmabuf, sizeof(nmabuf), "(readlink: %s)",
@@ -1039,10 +1031,10 @@ static int process_id(struct lsof_context *ctx, /* context */
10391031
else {
10401032
ss = SB_ALL;
10411033
if (HasNFS) {
1042-
if ((sv = statsafely(ctx, path, &sb)))
1034+
if ((sv = statsafely(ctx, Path, &sb)))
10431035
sv = statEx(ctx, pbuf, &sb, &ss);
10441036
} else
1045-
sv = stat(path, &sb);
1037+
sv = stat(Path, &sb);
10461038
if (sv) {
10471039
ss = 0;
10481040
if (!Fwarn) {
@@ -1055,7 +1047,7 @@ static int process_id(struct lsof_context *ctx, /* context */
10551047
}
10561048
}
10571049
if (pn) {
1058-
(void)process_proc_node(ctx, lnk ? pbuf : path, path, &sb, ss,
1050+
(void)process_proc_node(ctx, lnk ? pbuf : Path, Path, &sb, ss,
10591051
(struct stat *)NULL, 0);
10601052
if (Lf->sf)
10611053
link_lfile(ctx);
@@ -1066,9 +1058,9 @@ static int process_id(struct lsof_context *ctx, /* context */
10661058
*/
10671059
lnk = ss = txts = 0;
10681060
if (!Ckscko) {
1069-
(void)make_proc_path(ctx, idp, idpl, &path, &pathl, "exe");
1061+
(void)make_proc_path(ctx, idp, idpl, &Path, &Pathl, "exe");
10701062
alloc_lfile(ctx, LSOF_FD_PROGRAM_TEXT, -1);
1071-
if (getlinksrc(path, pbuf, sizeof(pbuf), (char **)NULL) < 1) {
1063+
if (getlinksrc(Path, pbuf, sizeof(pbuf), (char **)NULL) < 1) {
10721064
zeromem((void *)&sb, sizeof(sb));
10731065
if (!Fwarn) {
10741066
if ((errno != ENOENT) || uid) {
@@ -1088,13 +1080,13 @@ static int process_id(struct lsof_context *ctx, /* context */
10881080
else {
10891081
ss = SB_ALL;
10901082
if (HasNFS) {
1091-
if ((sv = statsafely(ctx, path, &sb))) {
1083+
if ((sv = statsafely(ctx, Path, &sb))) {
10921084
sv = statEx(ctx, pbuf, &sb, &ss);
10931085
if (!sv && (ss & SB_DEV) && (ss & SB_INO))
10941086
txts = 1;
10951087
}
10961088
} else
1097-
sv = stat(path, &sb);
1089+
sv = stat(Path, &sb);
10981090
if (sv) {
10991091
ss = 0;
11001092
if (!Fwarn) {
@@ -1108,7 +1100,7 @@ static int process_id(struct lsof_context *ctx, /* context */
11081100
}
11091101
}
11101102
if (pn) {
1111-
(void)process_proc_node(ctx, lnk ? pbuf : path, path, &sb, ss,
1103+
(void)process_proc_node(ctx, lnk ? pbuf : Path, Path, &sb, ss,
11121104
(struct stat *)NULL, 0);
11131105
if (Lf->sf)
11141106
link_lfile(ctx);
@@ -1118,8 +1110,8 @@ static int process_id(struct lsof_context *ctx, /* context */
11181110
* Process the ID's memory map info.
11191111
*/
11201112
if (!Ckscko) {
1121-
(void)make_proc_path(ctx, idp, idpl, &path, &pathl, "maps");
1122-
(void)process_proc_map(ctx, path, txts ? &sb : (struct stat *)NULL,
1113+
(void)make_proc_path(ctx, idp, idpl, &Path, &Pathl, "maps");
1114+
(void)process_proc_map(ctx, Path, txts ? &sb : (struct stat *)NULL,
11231115
txts ? ss : 0);
11241116
}
11251117

@@ -1161,17 +1153,17 @@ static int process_id(struct lsof_context *ctx, /* context */
11611153
/*
11621154
* Process the ID's file descriptor directory.
11631155
*/
1164-
if ((i = make_proc_path(ctx, idp, idpl, &dpath, &dpathl, "fd/")) < 3)
1156+
if ((i = make_proc_path(ctx, idp, idpl, &Dpath, &Dpathl, "fd/")) < 3)
11651157
return (0);
1166-
dpath[i - 1] = '\0';
1158+
Dpath[i - 1] = '\0';
11671159
if ((OffType == OFFSET_FDINFO) &&
1168-
((j = make_proc_path(ctx, idp, idpl, &ipath, &ipathl, "fdinfo/")) >= 7))
1160+
((j = make_proc_path(ctx, idp, idpl, &Ipath, &Ipathl, "fdinfo/")) >= 7))
11691161
oty = 1;
11701162
else
11711163
oty = 0;
1172-
if (!(fdp = opendir(dpath))) {
1164+
if (!(fdp = opendir(Dpath))) {
11731165
if (!Fwarn) {
1174-
(void)snpf(nmabuf, sizeof(nmabuf), "%s (opendir: %s)", dpath,
1166+
(void)snpf(nmabuf, sizeof(nmabuf), "%s (opendir: %s)", Dpath,
11751167
strerror(errno));
11761168
alloc_lfile(ctx, LSOF_FD_NOFD, -1);
11771169
nmabuf[sizeof(nmabuf) - 1] = '\0';
@@ -1180,14 +1172,14 @@ static int process_id(struct lsof_context *ctx, /* context */
11801172
}
11811173
return (0);
11821174
}
1183-
dpath[i - 1] = '/';
1175+
Dpath[i - 1] = '/';
11841176
while ((fp = readdir(fdp))) {
11851177
if (nm2id(fp->d_name, &fd, &n))
11861178
continue;
1187-
(void)make_proc_path(ctx, dpath, i, &path, &pathl, fp->d_name);
1179+
(void)make_proc_path(ctx, Dpath, i, &Path, &Pathl, fp->d_name);
11881180
(void)alloc_lfile(ctx, LSOF_FD_NUMERIC, fd);
11891181
efs = 0;
1190-
if (getlinksrc(path, pbuf, sizeof(pbuf), &rest) < 1) {
1182+
if (getlinksrc(Path, pbuf, sizeof(pbuf), &rest) < 1) {
11911183
zeromem((char *)&sb, sizeof(sb));
11921184
lnk = ss = 0;
11931185
if (!Fwarn) {
@@ -1207,15 +1199,15 @@ static int process_id(struct lsof_context *ctx, /* context */
12071199
pn = 0;
12081200
} else {
12091201
if (HasNFS) {
1210-
if (lstatsafely(ctx, path, &lsb)) {
1202+
if (lstatsafely(ctx, Path, &lsb)) {
12111203
enls_fd = errno;
12121204
(void)statEx(ctx, pbuf, &lsb, &ls);
12131205
enls = errno;
12141206
} else {
12151207
enls = 0;
12161208
ls = SB_ALL;
12171209
}
1218-
if (statsafely(ctx, path, &sb)) {
1210+
if (statsafely(ctx, Path, &sb)) {
12191211
enss_fd = errno;
12201212
(void)statEx(ctx, pbuf, &sb, &ss);
12211213
enss = errno;
@@ -1224,9 +1216,9 @@ static int process_id(struct lsof_context *ctx, /* context */
12241216
ss = SB_ALL;
12251217
}
12261218
} else {
1227-
ls = lstat(path, &lsb) ? 0 : SB_ALL;
1219+
ls = lstat(Path, &lsb) ? 0 : SB_ALL;
12281220
enls = errno;
1229-
ss = stat(path, &sb) ? 0 : SB_ALL;
1221+
ss = stat(Path, &sb) ? 0 : SB_ALL;
12301222
enss = errno;
12311223
}
12321224
if (!ls && !Fwarn) {
@@ -1258,7 +1250,7 @@ static int process_id(struct lsof_context *ctx, /* context */
12581250

12591251
if (oty) {
12601252
int fdinfo_mask = FDINFO_BASE;
1261-
(void)make_proc_path(ctx, ipath, j, &pathi, &pathil,
1253+
(void)make_proc_path(ctx, Ipath, j, &Pathi, &Pathil,
12621254
fp->d_name);
12631255

12641256
if (rest && rest[0] == '[' && rest[1] == 'e' &&
@@ -1278,12 +1270,13 @@ static int process_id(struct lsof_context *ctx, /* context */
12781270
#endif /* defined(HASEPTOPTS) */
12791271
if (rest && rest[0] == '[' && rest[1] == 'p')
12801272
fdinfo_mask |= FDINFO_PID;
1281-
else if (Lf && Lf->ntype == N_REGLR && rest && *rest && strcmp(pbuf, "pidfd") == 0) {
1273+
else if (Lf && Lf->ntype == N_REGLR && rest && *rest &&
1274+
strcmp(pbuf, "pidfd") == 0) {
12821275
// https://github.com/lsof-org/lsof/issues/317
12831276
fdinfo_mask |= FDINFO_PID;
12841277
}
12851278

1286-
if ((av = get_fdinfo(ctx, pathi, fdinfo_mask, &fi)) &
1279+
if ((av = get_fdinfo(ctx, Pathi, fdinfo_mask, &fi)) &
12871280
FDINFO_POS) {
12881281
if (efs) {
12891282
lfr->off = (SZOFFTYPE)fi.pos;
@@ -1308,7 +1301,7 @@ static int process_id(struct lsof_context *ctx, /* context */
13081301
#endif /* !defined(HASNOFSFLAGS) */
13091302
}
13101303
if (pn) {
1311-
process_proc_node(ctx, lnk ? pbuf : path, path, &sb, ss, &lsb,
1304+
process_proc_node(ctx, lnk ? pbuf : Path, Path, &sb, ss, &lsb,
13121305
ls);
13131306
if (Lf->ntype == N_ANON_INODE) {
13141307
if (rest && *rest) {
@@ -1352,15 +1345,15 @@ static int process_id(struct lsof_context *ctx, /* context */
13521345
// https://github.com/lsof-org/lsof/issues/317
13531346
// pidfd since Linux 6.9 becomes a regular file:
13541347
// /proc/PID/fd/FD -> pidfd:[INODE]
1355-
(void)snpf(rest, sizeof(pbuf) - (rest - pbuf),
1356-
"[pidfd:%d]", fi.pid);
1348+
(void)snpf(rest, sizeof(pbuf) - (rest - pbuf), "[pidfd:%d]",
1349+
fi.pid);
13571350
enter_nm(ctx, rest);
13581351
}
13591352

1360-
if ((Selflags & SELNLINK) &&
1361-
(enss_fd == ESTALE || enls_fd == ESTALE)) {
1362-
Lf->sf |= SELNLINK;
1363-
(void)add_nma(ctx, " (STALE)", 8);
1353+
if ((Selflags & SELNLINK) &&
1354+
(enss_fd == ESTALE || enls_fd == ESTALE)) {
1355+
Lf->sf |= SELNLINK;
1356+
(void)add_nma(ctx, " (STALE)", 8);
13641357
}
13651358

13661359
if (Lf->sf)
@@ -1375,7 +1368,7 @@ static int process_id(struct lsof_context *ctx, /* context */
13751368
/*
13761369
* compare_mntns() - compare mount namespace of this lsof process and the
13771370
* target process
1378-
*
1371+
*
13791372
* Note: mount namespace path might not be found with legacy linux kernel (e.g.
13801373
* linux-2.6) which does not have path "/proc/self/ns" or "/proc/${pid}/ns",
13811374
* see Commit 6b4e306aa3dc ("ns: proc files for namespace naming policy.")

lib/dialects/linux/dsock.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4077,7 +4077,8 @@ void process_proc_sock(struct lsof_context *ctx, /* context */
40774077
Lf->type = LSOF_FILE_SOCKET;
40784078
(void)snpf(Lf->iproto, sizeof(Lf->iproto), "%.*s", IPROTOL - 1, "SCTP");
40794079
Lf->inp_ty = 2;
4080-
(void)snpf(tbuf, sizeof(tbuf), "%" INODEPSPEC "u", (INODETYPE)s->st_ino);
4080+
(void)snpf(tbuf, sizeof(tbuf), "%" INODEPSPEC "u",
4081+
(INODETYPE)s->st_ino);
40814082
tbuf[sizeof(tbuf) - 1] = '\0';
40824083
enter_dev_ch(ctx, tbuf);
40834084
Namech[0] = '\0';

0 commit comments

Comments
 (0)