From 3464871501cc042ff27b1a633e9e89eb0a396ba1 Mon Sep 17 00:00:00 2001 From: Marco Ciacco Date: Wed, 4 Oct 2023 11:05:00 +0100 Subject: [PATCH 1/4] Fixing Memoryleak Adding header adding CMakeLists --- .gitignore | 2 ++ CMakeLists.txt | 3 ++ common.h | 5 ++++ handles.c | 20 ++++++++------ server.c | 11 ++++++-- server.h | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 105 insertions(+), 11 deletions(-) create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 server.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1899660 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +build +.vscode \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..fc7ff5a --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.5) +project(ftp) +add_executable(${PROJECT_NAME} server.h server.c handles.c) \ No newline at end of file diff --git a/common.h b/common.h index eca335f..4b8dbb1 100644 --- a/common.h +++ b/common.h @@ -1,3 +1,6 @@ +#ifndef COMMON_INCLUDE_ +#define COMMON_INCLUDE_ + #define _GNU_SOURCE #include #include @@ -117,3 +120,5 @@ void ftp_abor(State *); void str_perm(int, char *); void my_wait(int); + +#endif \ No newline at end of file diff --git a/handles.c b/handles.c index 99e5158..70172bc 100644 --- a/handles.c +++ b/handles.c @@ -1,4 +1,6 @@ +#include #include "common.h" +#include "server.h" #ifndef sendfile #define BUF_SIZE 8192 ssize_t sendfile(int out_fd, int in_fd, off_t * offset, size_t count ) @@ -128,17 +130,17 @@ void ftp_pasv(Command *cmd, State *state) int ip[4]; char buff[255]; char *response = "227 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\n"; - Port *port = malloc(sizeof(Port)); - gen_port(port); + Port port; + gen_port(&port); getip(state->connection,ip); /* Close previous passive socket? */ close(state->sock_pasv); /* Start listening here, but don't accept the connection */ - state->sock_pasv = create_socket((256*port->p1)+port->p2); - printf("port: %d\n",256*port->p1+port->p2); - sprintf(buff,response,ip[0],ip[1],ip[2],ip[3],port->p1,port->p2); + state->sock_pasv = create_socket((256*port.p1)+port.p2); + printf("port: %d\n",256*port.p1+port.p2); + sprintf(buff,response,ip[0],ip[1],ip[2],ip[3],port.p1,port.p2); state->message = buff; state->mode = SERVER; puts(state->message); @@ -199,7 +201,7 @@ void ftp_list(Command *cmd, State *state) strftime(timebuff,80,"%b %d %H:%M",time); str_perm((statbuf.st_mode & ALLPERMS), perms); dprintf(connection, - "%c%s %5d %4d %4d %8d %s %s\r\n", + "%c%s %5ld %4d %4d %8ld %s %s\r\n", (entry->d_type==DT_DIR)?'d':'-', perms,statbuf.st_nlink, statbuf.st_uid, @@ -506,7 +508,7 @@ void ftp_size(Command *cmd, State *state) memset(filesize,0,128); /* Success */ if(stat(cmd->arg,&statbuf)==0){ - sprintf(filesize, "213 %d\n", statbuf.st_size); + sprintf(filesize, "213 %ld\n", statbuf.st_size); state->message = filesize; }else{ state->message = "550 Could not get file size.\n"; @@ -531,7 +533,7 @@ void str_perm(int perm, char *str_perm) int read, write, exec; /* Flags buffer */ - char fbuff[3]; + char fbuff[4]; read = write = exec = 0; @@ -540,7 +542,7 @@ void str_perm(int perm, char *str_perm) /* Explode permissions of user, group, others; starting with users */ curperm = ((perm & ALLPERMS) >> i ) & 0x7; - memset(fbuff,0,3); + memset(fbuff,0,4); /* Check rwx flags for each*/ read = (curperm >> 2) & 0x1; write = (curperm >> 1) & 0x1; diff --git a/server.c b/server.c index 93e6cc8..2984eb0 100644 --- a/server.c +++ b/server.c @@ -1,4 +1,7 @@ -#include "common.h" +#include "server.h" + +#include +#include /** * Sets up server and handles incoming connections * @param port Server port @@ -53,6 +56,10 @@ void server(int port) if(buffer[0]<=127 || buffer[0]>=0){ response(cmd,state); } + else + { + printf("Ignoring command %s\n", cmd->command); + } memset(buffer,0,BSIZE); memset(cmd,0,sizeof(cmd)); }else{ @@ -203,7 +210,7 @@ void my_wait(int signum) wait(&status); } -main() +int main() { server(8021); return 0; diff --git a/server.h b/server.h new file mode 100644 index 0000000..beb97f6 --- /dev/null +++ b/server.h @@ -0,0 +1,75 @@ +#ifndef SERVER_INCLUDE +#define SERVER_INCLUDE + +#include "common.h" +/** + * Sets up server and handles incoming connections + * @param port Server port + */ +void server(int port); + +/** + * Creates socket on specified port and starts listening to this socket + * @param port Listen on this port + * @return int File descriptor for new socket + */ +int create_socket(int port); + +/** + * Accept connection from client + * @param socket Server listens this + * @return int File descriptor to accepted connection + */ +int accept_connection(int socket); + +/** + * Get ip where client connected to + * @param sock Commander socket connection + * @param ip Result ip array (length must be 4 or greater) + * result IP array e.g. {127,0,0,1} + */ +void getip(int sock, int *ip); + +/** + * Lookup enum value of string + * @param cmd Command string + * @return Enum index if command found otherwise -1 + */ + +int lookup_cmd(char *cmd); +/** + * General lookup for string arrays + * It is suitable for smaller arrays, for bigger ones trie is better + * data structure for instance. + * @param needle String to lookup + * @param haystack Strign array + * @param count Size of haystack + */ +int lookup(char *needle, const char **haystack, int count); + + +/** + * Writes current state to client + */ +void write_state(State *state); + +/** + * Generate random port for passive mode + * @param state Client state + */ +void gen_port(Port *port); + +/** + * Parses FTP command string into struct + * @param cmdstring Command string (from ftp client) + * @param cmd Command struct + */ +void parse_command(char *cmdstring, Command *cmd); + +/** + * Handles zombies + * @param signum Signal number + */ +void my_wait(int signum); + +#endif \ No newline at end of file From 73c41e1ab5fc368ca9595c5e884bb76ca0d1e254 Mon Sep 17 00:00:00 2001 From: Marco Ciacco Date: Wed, 4 Oct 2023 15:30:01 +0100 Subject: [PATCH 2/4] Remove malloc and memoryleak --- common.h | 4 ++-- handles.c | 15 +++++++++++---- server.c | 16 ++++++++-------- 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/common.h b/common.h index 4b8dbb1..ddadf94 100644 --- a/common.h +++ b/common.h @@ -1,7 +1,6 @@ #ifndef COMMON_INCLUDE_ #define COMMON_INCLUDE_ -#define _GNU_SOURCE #include #include #include @@ -10,6 +9,7 @@ #include #include #include +#define __USE_GNU #include #include #include @@ -36,7 +36,7 @@ typedef struct State /* Is this username allowed? */ int username_ok; - char *username; + char username[32]; /* Response message to client e.g. 220 Welcome */ char *message; diff --git a/handles.c b/handles.c index 70172bc..b299218 100644 --- a/handles.c +++ b/handles.c @@ -1,6 +1,6 @@ -#include #include "common.h" #include "server.h" +#include #ifndef sendfile #define BUF_SIZE 8192 ssize_t sendfile(int out_fd, int in_fd, off_t * offset, size_t count ) @@ -100,7 +100,6 @@ void ftp_user(Command *cmd, State *state) { const int total_usernames = sizeof(usernames)/sizeof(char *); if(lookup(cmd->arg,usernames,total_usernames)>=0){ - state->username = malloc(32); memset(state->username,0,32); strcpy(state->username,cmd->arg); state->username_ok = 1; @@ -192,14 +191,22 @@ void ftp_list(Command *cmd, State *state) if(stat(entry->d_name,&statbuf)==-1){ fprintf(stderr, "FTP: Error reading file stats...\n"); }else{ - char *perms = malloc(9); - memset(perms,0,9); + char perms[10]; + memset(perms,0,10); /* Convert time_t to tm struct */ rawtime = statbuf.st_mtime; time = localtime(&rawtime); strftime(timebuff,80,"%b %d %H:%M",time); str_perm((statbuf.st_mode & ALLPERMS), perms); + printf("%c%s %5ld %4d %4d %8ld %s %s\r\n", + (entry->d_type==DT_DIR)?'d':'-', + perms,statbuf.st_nlink, + statbuf.st_uid, + statbuf.st_gid, + statbuf.st_size, + timebuff, + entry->d_name); dprintf(connection, "%c%s %5ld %4d %4d %8ld %s %s\r\n", (entry->d_type==DT_DIR)?'d':'-', diff --git a/server.c b/server.c index 2984eb0..b6f0cf7 100644 --- a/server.c +++ b/server.c @@ -16,8 +16,8 @@ void server(int port) while(1){ connection = accept(sock, (struct sockaddr*) &client_address,&len); char buffer[BSIZE]; - Command *cmd = malloc(sizeof(Command)); - State *state = malloc(sizeof(State)); + Command cmd; + State state; pid = fork(); memset(buffer,0,BSIZE); @@ -48,20 +48,20 @@ void server(int port) if(!(bytes_read>BSIZE)){ /* TODO: output this to log */ buffer[BSIZE-1] = '\0'; - printf("User %s sent command: %s\n",(state->username==0)?"unknown":state->username,buffer); - parse_command(buffer,cmd); - state->connection = connection; + printf("User %s sent command: %s\n",(state.username==0)?"unknown":state.username,buffer); + parse_command(buffer,&cmd); + state.connection = connection; /* Ignore non-ascii char. Ignores telnet command */ if(buffer[0]<=127 || buffer[0]>=0){ - response(cmd,state); + response(&cmd,&state); } else { - printf("Ignoring command %s\n", cmd->command); + printf("Ignoring command %s\n", cmd.command); } memset(buffer,0,BSIZE); - memset(cmd,0,sizeof(cmd)); + memset(&cmd,0,sizeof(cmd)); }else{ /* Read error */ perror("server:read"); From f99b05fdd35a75cebb2954eb099a4dee502f354b Mon Sep 17 00:00:00 2001 From: Marco Ciacco Date: Wed, 4 Oct 2023 16:24:37 +0100 Subject: [PATCH 3/4] Revert the define --- common.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/common.h b/common.h index ddadf94..1c3895d 100644 --- a/common.h +++ b/common.h @@ -1,6 +1,6 @@ #ifndef COMMON_INCLUDE_ #define COMMON_INCLUDE_ - +#define _GNU_SOURCE #include #include #include @@ -9,7 +9,6 @@ #include #include #include -#define __USE_GNU #include #include #include From ba6e7102f783540dcf1da0bdc61ccc4efe72a515 Mon Sep 17 00:00:00 2001 From: Marco Ciacco Date: Wed, 4 Oct 2023 16:37:31 +0000 Subject: [PATCH 4/4] Add the cross compiling settings --- CMakeLists.txt | 51 +++++++++++++++++++++++++++++++++++++++++++++++- compile.sh | 5 +++++ cross_compile.sh | 7 +++++++ 3 files changed, 62 insertions(+), 1 deletion(-) create mode 100755 compile.sh create mode 100755 cross_compile.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index fc7ff5a..7b4bf9b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,3 +1,52 @@ cmake_minimum_required(VERSION 3.5) project(ftp) -add_executable(${PROJECT_NAME} server.h server.c handles.c) \ No newline at end of file + +if(DEFINED CROSS_COMPILE_PATH) + # the name of the target operating system + message(STATUS "SETTING CROSS COMPILER") + set(CMAKE_SYSTEM_NAME Linux) + + #SET(CROSS_COMPILE_PATH "/opt/arm/arm-ca9-linux-gnueabihf-6.5") + if(NOT ${ROOTFS}) + set(ROOTFS "${CROSS_COMPILE_PATH}") + endif() + #SET(ROOTFS "/na51055_linux_sdk/BSP/linux-kernel/") + + add_compile_options(-nostdinc) + + # which compilers to use for C and C++ + set(CMAKE_C_COMPILER ${CROSS_COMPILE_PATH}/bin/arm-ca9-linux-gnueabihf-gcc) + set(CMAKE_CXX_COMPILER ${CROSS_COMPILE_PATH}/bin/arm-ca9-linux-gnueabihf-g++) + + set(CMAKE_FIND_ROOT_PATH ${ROOTFS}) + link_directories(${CROSS_COMPILE_PATH}/lib ${CROSS_COMPILE_PATH}/local/lib ${CROSS_COMPILE_PATH}/arch/powerpc/boot) + + + + + # adjust the default behavior of the FIND_XXX() commands: + # search programs in the host environment + set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + + # search headers and libraries in the target environment + set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) + set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + +endif() + +add_executable(${PROJECT_NAME} server.h server.c handles.c) + + +if(DEFINED CROSS_COMPILE_PATH) + + # target_include_directories(${PROJECT_NAME} SYSTEM PRIVATE + # /opt/arm/arm-ca9-linux-gnueabihf-6.5/arm-ca9-linux-gnueabihf/sysroot/usr/include/ + # ) + target_include_directories(${PROJECT_NAME} BEFORE PRIVATE + ${CROSS_COMPILE_PATH}/arm-ca9-linux-gnueabihf/sysroot/usr/include/ + ${ROOTFS}/arch/powerpc/boot/ + ${ROOTFS}/arch/arm/include/generated/ + ${CROSS_COMPILE_PATH}/arm-ca9-linux-gnueabihf/include/c++/6.5.0/ + ${CROSS_COMPILE_PATH}/lib/gcc/arm-ca9-linux-gnueabihf/6.5.0/include/ + ) +endif() diff --git a/compile.sh b/compile.sh new file mode 100755 index 0000000..9923a0e --- /dev/null +++ b/compile.sh @@ -0,0 +1,5 @@ +rm -r build +mkdir build +cd build +cmake .. +make diff --git a/cross_compile.sh b/cross_compile.sh new file mode 100755 index 0000000..095a9f0 --- /dev/null +++ b/cross_compile.sh @@ -0,0 +1,7 @@ +rm -r build +mkdir build +cd build +cmake -DCROSS_COMPILE_PATH="/opt/arm/arm-ca9-linux-gnueabihf-6.5" \ + -DROOTFS="/na51055_linux_sdk/BSP/linux-kernel/" \ + .. +make