tuyau

Client/server for transfering files (like cp)
git clone https://noulin.net/git/tuyau.git
Log | Files | Refs | README

commit 2942d44a51881b74a16907f083c4e0c08228fd07
parent a2c0fa314c98321ca42d17a0bf306d292f5f7c0c
Author: Remy Noulin <loader2x@gmail.com>
Date:   Mon, 22 Aug 2022 04:12:56 -0400

check packet and string sizes and free disk space

to avoid buffer overflows.

NOTES.md          |  1 +
serverPackage.yml |  2 +-
sserver.c         | 40 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 42 insertions(+), 1 deletion(-)

Diffstat:
MNOTES.md | 1+
MserverPackage.yml | 2+-
Msserver.c | 40++++++++++++++++++++++++++++++++++++++++
3 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/NOTES.md b/NOTES.md @@ -2,6 +2,7 @@ - create tests - send errors from server to client - make daemon +- add timeouts in server to close the connection when a client is too slow ..- tls ..- check inputs, add limits ..- add rate limiter, ban wrong token for 15minutes diff --git a/serverPackage.yml b/serverPackage.yml @@ -1,6 +1,6 @@ --- name: tuyauServer - version: 0.0.4 + version: 0.0.5 description: "Server for copying files with tuyau" bin: ./tuyauServer.c #cflags: -DA -g3 -std=gnu11 -fPIC -pipe diff --git a/sserver.c b/sserver.c @@ -27,6 +27,9 @@ // basename #include <libgen.h> +// statvfs +#include <sys/statvfs.h> + #include "libsheepyObject.h" #include "netFrame.h" #include "shpPackages/short/short.h" @@ -196,6 +199,8 @@ int main(int ARGC, char** ARGV) { void saveReceivedData(void *receiveB, size_t sz) { logVarG(sz); if (packetCount == 0) { + // check packet size + if (sz < (1/*command*/ + 8/*token*/)) ret; // receive a new command // header u8 *command = (u8*) receiveB; @@ -214,18 +219,26 @@ void saveReceivedData(void *receiveB, size_t sz) { if (*command == 0) { // receive file + // check packet size + if (sz < (1/*command*/ + 8/*token*/ + 2 /*filenameLength*/ + 1 /*filename*/)) ret; u16 *filenameLength = (u16*)(receiveB + 9); if (*filenameLength > 4096) ret; + // check that filenameLength is correct + if (sz < (1/*command*/ + 8/*token*/ + 2 /*filenameLength*/ + *filenameLength /*filename*/)) ret; // receiveB + 11 = filename cleanCharP(filename) = malloc(*filenameLength + 1); filename[*filenameLength] = 0; memcpy(filename, receiveB + 11, *filenameLength); u32 bufi = 11 + *filenameLength; + // check that filemode and path are in the buffer + if (sz < (bufi + 2 /*filemode*/ + 2 /*pathLength*/)) ret; u16 *filemode = (u16*)(receiveB + bufi); bufi += 2; u16 *pathLength = (u16*)(receiveB + bufi); if (*pathLength > 4096) ret; bufi += 2; + // check path length is correct and that filesize is in the buffer + if (sz < (bufi + *pathLength + 8 /*filesize*/)) ret; cleanCharP(destPath) = null; if (*pathLength) { destPath = malloc(*pathLength + 1); @@ -264,9 +277,27 @@ void saveReceivedData(void *receiveB, size_t sz) { ret; } filenameInDestPath = yes; + // check if there is enough free space on disk + struct statvfs fs; + if (statvfs(dir, &fs) == -1) { + shperror("statvfs check free space"); + ret; + } + if (*filesize >= fs.f_bsize * fs.f_bavail) { + logE("Not enough free space available in path %s", path); + } } //lv(filenameInDestPath); if (not filenameInDestPath) { + // check if there is enough free space on disk + struct statvfs fs; + if (statvfs(path, &fs) == -1) { + shperror("statvfs check free space"); + ret; + } + if (*filesize >= fs.f_bsize * fs.f_bavail) { + logE("Not enough free space available in path %s", path); + } pErrorNULL(iAppendManyS(&path, "/", filename)); } lv(path); @@ -295,9 +326,14 @@ void saveReceivedData(void *receiveB, size_t sz) { } elif (*command == 1) { // mkdir + + // check packet size + if (sz < (1/*command*/ + 8/*token*/ + 2 /*filemode*/ + 2 /*pathLength*/ + 1 /*path*/)) ret; u16 *filemode = (u16*)(receiveB + 9); u16 *pathLength = (u16*)(receiveB + 11); if (*pathLength > 4096) ret; + // check that pathLength is correct, path has to be at least 1 byte + if (sz < (1/*command*/ + 8/*token*/ + 2 /*filemode*/ + 2 /*pathLength*/ + *pathLength /*path*/)) ret; cleanCharP(destPath) = malloc(*pathLength + 1); memcpy(destPath, receiveB + 13, *pathLength); destPath[*pathLength] = 0; @@ -310,9 +346,13 @@ void saveReceivedData(void *receiveB, size_t sz) { pError0(fileChmod(path, *filemode)); } elif (*command == 2) { + // check packet size, sendFile path has to be at least 1 byte + if (sz < (1/*command*/ + 8/*token*/ + 2 /*sendFileLength*/ + 1 /*sendFile*/)) ret; logD("send files to client"); u16 *sendFileLength = (u16*)(receiveB + 9); if (*sendFileLength > 4096) ret; + // check that sendFileLength is correct + if (sz < (1/*command*/ + 8/*token*/ + 2 /*sendFileLength*/ + *sendFileLength)) ret; cleanCharP(sendFile) = malloc(*sendFileLength + 1); memcpy(sendFile, receiveB + 11, *sendFileLength); sendFile[*sendFileLength] = 0;