Skip to content

Commit 86a11f9

Browse files
authored
Merge pull request #28 from johnthesecond/fix_issue_1
Fix issue 1
2 parents 9d8ae9f + 69ac90f commit 86a11f9

File tree

4 files changed

+123
-58
lines changed

4 files changed

+123
-58
lines changed

include/file_system.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <sys/stat.h>
2121
#include <stdbool.h>
2222
#include <unistd.h>
23+
#include <dirent.h>
2324

2425
#include "results.h"
2526
#include "vector.h"
@@ -74,6 +75,12 @@ typedef struct Parsed_Passwd_Line
7475
*/
7576
void walk_file_system(char *entry_location, All_Results *all_results, Args *cmdline, vec_void_t *users);
7677

78+
/** Returns the d_type field if present i.e. not DT_UNKNOWN, otherwise, the equivilant is read from lstat.
79+
* @param entry the direct entry to read from.
80+
* @param location the directory that the entry is contained in. _NOT_ the path of the file itself.
81+
*/
82+
unsigned char get_d_type(struct dirent* entry, const char* location);
83+
7784
/* ============================ File_Info Functions ============================== */
7885

7986
/**
@@ -195,4 +202,4 @@ void get_file_extension(char *buf, char *f_name);
195202
* can write to that directory
196203
* @param path location to test if writable
197204
*/
198-
bool is_folder_writable(char *path);
205+
bool is_folder_writable(char *path);

src/all_scans.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,4 +191,4 @@ static void *create_walk_thread(void *args)
191191
/* Cleanup */
192192
thpool_destroy(cmdline->fs_threadpool);
193193
return NULL;
194-
}
194+
}

src/file_system.c

Lines changed: 93 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
/*
2-
This file is used to populate an array of files in the system
1+
/*
2+
This file is used to populate an array of files in the system
33
each file stored in the array will have permissions etc. We can
44
use this to find SUID binaries and writeable config files etc
55
*/
@@ -26,6 +26,7 @@
2626
/* ============================ PROTOTYPES ============================== */
2727

2828
void walk_file_system(char *entry_location, All_Results *all_results, Args *cmdline, vec_void_t *users);
29+
unsigned char get_d_type(struct dirent* entry, const char* location);
2930

3031
bool has_extension(File_Info *f, char *extension);
3132
bool has_global_write(File_Info *f);
@@ -46,15 +47,67 @@ bool is_folder_writable(char *path);
4647
static void add_file_to_thread_pool(char *file_location, char *file_name, All_Results *all_results, Args *cmdline, vec_void_t *users);
4748

4849
/* ============================ FUNCTIONS ============================== */
50+
/** Extracts the d_type form file direct structures, even if not provided directly.
51+
* This is the case when calling readdir, as :
52+
* "The only fields in the dirent structure that are mandated by POSIX.1 are d_name and d_ino. The other fields are unstandardized, and not present on all systems"
53+
* However:
54+
* " Currently, only some filesystems have full support for returning the file type in d_type.
55+
* All applications must properly handle areturn of DT_UNKNOWN. "
56+
* In this case lstat is used.
57+
*
58+
* Note this version uses lstat as is consisten with the d_type entry. A seperate version would be needed for following links.
59+
*/
60+
61+
unsigned char get_d_type(struct dirent* entry, const char* location) {
62+
struct stat statbuf;
63+
unsigned char rv = DT_UNKNOWN;
64+
65+
if (DT_UNKNOWN == entry->d_type){
66+
char filepath[MAXSIZE];
67+
strncpy(filepath, location, MAXSIZE - 1);
68+
strncat(filepath, entry->d_name, MAXSIZE - 1);
69+
// The call to lstat here might not be thread safe, if the call is being made on the same file at the same time.
70+
// I think there ius no way that this happens at the moment, but am not sure at all.
71+
// Could globally lock this or do some sort of filesystem hash to make this more fine-grained etc.
72+
73+
if(-1 != lstat(entry->d_name, &statbuf))
74+
{
75+
// Her would be a good place to sanity check that the inode numbers match.
76+
if(S_ISLNK(statbuf.st_mode)) {
77+
rv = DT_LNK;
78+
}
79+
else if (S_ISDIR(statbuf.st_mode)) {
80+
rv = DT_DIR;
81+
}
82+
else if (S_ISREG(statbuf.st_mode)) {
83+
rv = DT_REG;
84+
}
85+
// Repeat if wanted for: DT_BLK, DT_CHR, DT_FIFO, DT_SOCK
86+
// i.e.:
87+
//else if (S_ISCHR(statbuf.st_mode)) {
88+
// rv = DT_CHR;
89+
//}
90+
} else {
91+
rv = DT_UNKNOWN;
92+
}
93+
} else {
94+
// The likely case is that the d_type is set.
95+
// Here it can just be read.
96+
rv = entry->d_type;
97+
}
98+
99+
return rv;
100+
}
101+
49102

50103
/**
51104
* Walks the file system, will skip files in ignore directory (cmdline arguments)
52-
* For each path encountered it will pass the file to a thread pool
53-
* The thread pool will perform scans on the file
54-
* Note this scan will not walk the proc file system
55-
* @param entry_location the root location to walk
56-
* @param all_results a pointer to structure containinng all the future enumy findings
57-
* @param cmdline a pointer to the run time arguments
105+
* For each path encountered it will pass the file to a thread pool
106+
* The thread pool will perform scans on the file
107+
* Note this scan will not walk the proc file system
108+
* @param entry_location the root location to walk
109+
* @param all_results a pointer to structure containinng all the future enumy findings
110+
* @param cmdline a pointer to the run time arguments
58111
* @param users This is the parsed /etc/passwd file
59112
*/
60113
void walk_file_system(char *entry_location, All_Results *all_results, Args *cmdline, vec_void_t *users)
@@ -75,13 +128,13 @@ void walk_file_system(char *entry_location, All_Results *all_results, Args *cmdl
75128
{
76129
if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0)
77130
{
78-
if (entry->d_type & DT_REG)
131+
if (get_d_type(entry, entry_location) & DT_REG)
79132
{
80133
strncpy(file_location, entry_location, sizeof(file_location) - 1);
81134
strncat(file_location, entry->d_name, sizeof(file_location) - 1 - strlen(file_location));
82135
add_file_to_thread_pool(file_location, entry->d_name, all_results, cmdline, users);
83136
}
84-
else if (entry->d_type & DT_DIR)
137+
else if (get_d_type(entry, entry_location) & DT_DIR)
85138
{
86139
strncpy(file_location, entry_location, sizeof(file_location) - 1);
87140
strncat(file_location, entry->d_name, sizeof(file_location) - 1 - strlen(file_location));
@@ -107,53 +160,53 @@ void walk_file_system(char *entry_location, All_Results *all_results, Args *cmdl
107160
/* ============================ has_* FUNCTIONS ============================== */
108161

109162
/**
110-
* Tests to see if other read is enabled
111-
* @param fi this is the current file that's being scanned
163+
* Tests to see if other read is enabled
164+
* @param fi this is the current file that's being scanned
112165
*/
113166
bool has_global_read(File_Info *f)
114167
{
115168
return f->stat->st_mode & S_IROTH;
116169
}
117170

118171
/**
119-
* Tests to see if other write is enabled
120-
* @param fi this is the current file that's being scanned
172+
* Tests to see if other write is enabled
173+
* @param fi this is the current file that's being scanned
121174
*/
122175
bool has_global_write(File_Info *f)
123176
{
124177
return f->stat->st_mode & S_IWOTH;
125178
}
126179

127180
/**
128-
* Tests to see if other execute is enabled
129-
* @param fi this is the current file that's being scanned
181+
* Tests to see if other execute is enabled
182+
* @param fi this is the current file that's being scanned
130183
*/
131184
bool has_global_execute(File_Info *f)
132185
{
133186
return f->stat->st_mode & S_IXOTH;
134187
}
135188

136189
/**
137-
* Tests to see if group execute is enabled
138-
* @param fi this is the current file that's being scanned
190+
* Tests to see if group execute is enabled
191+
* @param fi this is the current file that's being scanned
139192
*/
140193
bool has_group_execute(File_Info *f)
141194
{
142195
return f->stat->st_mode & S_IXGRP;
143196
}
144197

145198
/**
146-
* Tests to see if group write is enabled
147-
* @param fi this is the current file that's being scanned
199+
* Tests to see if group write is enabled
200+
* @param fi this is the current file that's being scanned
148201
*/
149202
bool has_group_write(File_Info *f)
150203
{
151204
return f->stat->st_mode & S_IWGRP;
152205
}
153206

154207
/**
155-
* Tests to see if the current file has SUID bit enabled
156-
* @param fi this is the current file that's being scanned
208+
* Tests to see if the current file has SUID bit enabled
209+
* @param fi this is the current file that's being scanned
157210
*/
158211
bool has_suid(File_Info *f)
159212
{
@@ -162,7 +215,7 @@ bool has_suid(File_Info *f)
162215

163216
/**
164217
* Tests to see if the current file has GUID bit enabled
165-
* @param fi this is the current file that's being scanned
218+
* @param fi this is the current file that's being scanned
166219
*/
167220
bool has_guid(File_Info *f)
168221
{
@@ -171,7 +224,7 @@ bool has_guid(File_Info *f)
171224

172225
/**
173226
* Tests to see if the current file has a matching extension
174-
* @param fi this is the current file that's being scanned
227+
* @param fi this is the current file that's being scanned
175228
* @param extension this is the extension to check against
176229
*/
177230
bool has_extension(File_Info *f, char *extension)
@@ -180,17 +233,17 @@ bool has_extension(File_Info *f, char *extension)
180233
}
181234

182235
/**
183-
* Tests to see if the group or other can execute the file
184-
* @param fi this is the current file that's being scanned
236+
* Tests to see if the group or other can execute the file
237+
* @param fi this is the current file that's being scanned
185238
*/
186239
bool has_executable(File_Info *f)
187240
{
188241
return (has_group_execute(f) || has_global_execute(f));
189242
}
190243

191244
/**
192-
* Tests to see if the file is readable by the current process
193-
* @param fi this is the current file that's being scanned
245+
* Tests to see if the file is readable by the current process
246+
* @param fi this is the current file that's being scanned
194247
*/
195248
bool can_read(File_Info *fi)
196249
{
@@ -204,7 +257,7 @@ bool can_read(File_Info *fi)
204257
* abc.tar.gz would return .gz not .tar.gz
205258
* The extensions is saved in lowercase
206259
* @param buffer location to save the file extension
207-
* @param f_name the files name
260+
* @param f_name the files name
208261
*/
209262
void get_file_extension(char *buf, char *f_name)
210263
{
@@ -235,7 +288,7 @@ void get_file_extension(char *buf, char *f_name)
235288
}
236289

237290
/**
238-
* Given a full path this function returns the file path
291+
* Given a full path this function returns the file path
239292
* @param full_path the files full path
240293
* @return a heap pointer containing the file's name
241294
*/
@@ -256,10 +309,10 @@ char *get_file_name(char *full_path)
256309
}
257310

258311
/**
259-
* Given a full path this function will return all the files parent directorys
260-
* DONT forget to free the returned pointer
261-
* @param full_path the files full path
262-
* @return a heap pointer containing the files's directory name
312+
* Given a full path this function will return all the files parent directorys
313+
* DONT forget to free the returned pointer
314+
* @param full_path the files full path
315+
* @return a heap pointer containing the files's directory name
263316
*/
264317
char *get_dir_name(char *full_path)
265318
{
@@ -269,8 +322,8 @@ char *get_dir_name(char *full_path)
269322
/* ============================ is_* FUNCTIONS ============================== */
270323

271324
/**
272-
* Given a directory returns true if the current process
273-
* can write to that directory
325+
* Given a directory returns true if the current process
326+
* can write to that directory
274327
* @param path location to test if writable
275328
*/
276329
bool is_folder_writable(char *path)
@@ -282,9 +335,9 @@ bool is_folder_writable(char *path)
282335

283336
/**
284337
* Adds the file at to the thread pool of scans to perform
285-
* This function blocks if the thread pool is at maxiumum capacity
286-
* @param file_location the file to be scaned
287-
* @param file_name the name of the file that is going to be ccaned
338+
* This function blocks if the thread pool is at maxiumum capacity
339+
* @param file_location the file to be scaned
340+
* @param file_name the name of the file that is going to be ccaned
288341
*/
289342
static void add_file_to_thread_pool(char *file_location, char *file_name, All_Results *all_results, Args *cmdline, vec_void_t *users)
290343
{
@@ -310,4 +363,4 @@ static void add_file_to_thread_pool(char *file_location, char *file_name, All_Re
310363
usleep(200);
311364

312365
thpool_add_work(cmdline->fs_threadpool, (void *)scan_file_for_issues, (void *)args);
313-
}
366+
}

src/shared_libs.c

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
2-
This file is used to find out where the ld will look for share objects at
3-
run time. We can use this list to find out if any executables have injectable
2+
This file is used to find out where the ld will look for share objects at
3+
run time. We can use this list to find out if any executables have injectable
44
shared objects. This is used in conjunction with the RPATH scan
55
*/
66

@@ -34,10 +34,10 @@ static bool read_file(char *location, vec_str_t *v);
3434
/* ============================ FUNCTIONS ============================== */
3535

3636
/**
37-
* This function will find where ld.so searches for shared objects and
38-
* then walk through all of those search locations. When a shared object
37+
* This function will find where ld.so searches for shared objects and
38+
* then walk through all of those search locations. When a shared object
3939
* is found we will add the full path to the vector
40-
* @param shared_lib_vec Uninitilized pointer to a vector to store results
40+
* @param shared_lib_vec Uninitilized pointer to a vector to store results
4141
* @return Returns false if something went wrong and True if everything went well
4242
*/
4343
bool find_shared_libs(vec_str_t *shared_lib_vec)
@@ -90,12 +90,12 @@ bool find_shared_libs(vec_str_t *shared_lib_vec)
9090
}
9191

9292
/**
93-
* Given a populated vector containing shared object full path locations
94-
* this function will search through the vector to see if the new_shared_lib
95-
* exists inside of the vector
93+
* Given a populated vector containing shared object full path locations
94+
* this function will search through the vector to see if the new_shared_lib
95+
* exists inside of the vector
9696
* @param shared_libs_vec This is the vector to itterate through
97-
* @param new_shared_lib This is the full path of the file that we want to search for
98-
* @return True if the new_shared_lib was found inside of the shared_libs vector
97+
* @param new_shared_lib This is the full path of the file that we want to search for
98+
* @return True if the new_shared_lib was found inside of the shared_libs vector
9999
*/
100100
bool test_if_standard_shared_object(vec_str_t *shared_libs, char *new_shared_lib)
101101
{
@@ -152,22 +152,27 @@ static void walk(char *location, vec_str_t *v)
152152
/* Buffer overflow possible? */
153153
/* ============================ TODO ============================== */
154154

155-
if (entry->d_type & DT_REG)
155+
if (get_d_type(entry, location) & DT_REG)
156156
{
157157
/* Ignore none shared objects */
158158
if (strstr(entry->d_name, ".so") == NULL)
159159
continue;
160160
char *new_location = malloc(sizeof(char) * MAXSIZE);
161-
memset(new_location, '\0', sizeof(char) * MAXSIZE);
161+
if (!new_location) {
162+
/* PANIC */
163+
printf("Failed to allocate memory when adding a new issue.\n");
164+
exit(EXIT_FAILURE);
165+
}
166+
memset(new_location, '\0', MAXSIZE);
162167
strncpy(new_location, location, MAXSIZE - 1);
163-
strcat(new_location, entry->d_name);
168+
strncat(new_location, entry->d_name, MAXSIZE - 1);
164169
vec_push(v, new_location);
165170
}
166-
if (entry->d_type & DT_DIR)
171+
if (get_d_type(entry, location) & DT_DIR)
167172
{
168173
strncpy(file_location, location, MAXSIZE - 1);
169-
strcat(file_location, entry->d_name);
170-
strcat(file_location, "/");
174+
strncat(file_location, entry->d_name, MAXSIZE - 1);
175+
strncat(file_location, "/", MAXSIZE-1);
171176
walk(file_location, v);
172177
}
173178
}

0 commit comments

Comments
 (0)