yaffs direct: Add more tests for valid paths.
[yaffs2.git] / direct / yaffsfs.c
index e3f6fb04d03ff15da2777fdeb08d58021761f506..2b1a82c991b94fa831ab79d724dfa9d6a9e00e5a 100644 (file)
@@ -635,6 +635,10 @@ static struct yaffs_obj *yaffsfs_FindObject(struct yaffs_obj *relDir,
 }
 
 
+/*************************************************************************
+ *     Start of yaffsfs visible functions. 
+ *************************************************************************/
+
 int yaffs_dup(int fd)
 {
        int newHandle = -1;
@@ -649,17 +653,17 @@ int yaffs_dup(int fd)
        if(newHandle >= 0)
                newPtr = yaffsfs_GetHandlePointer(newHandle);
 
-       if(newPtr){
+       if(newPtr)
                *newPtr = *oldPtr;
-               return newHandle;
-       }
+
+       yaffsfs_Unlock();
 
        if(!oldPtr)
                yaffsfs_SetError(-EBADF);
-       else
+       else if (!newPtr)
                yaffsfs_SetError(-ENOMEM);
 
-       return -1;
+       return newHandle;
 
 }
 
@@ -687,6 +691,11 @@ int yaffs_open_sharing(const YCHAR *path, int oflag, int mode, int sharing)
        int notDir = 0;
        int loop = 0;
 
+       if(!path) {
+               yaffsfs_SetError(-EFAULT);
+               return -1;
+       }
+
        if(yaffsfs_CheckPath(path) < 0){
                yaffsfs_SetError(-ENAMETOOLONG);
                return -1;
@@ -756,6 +765,13 @@ int yaffs_open_sharing(const YCHAR *path, int oflag, int mode, int sharing)
                        if( writeRequested && !(obj->yst_mode & S_IWRITE))
                                openDenied = 1;
 
+                       if( !errorReported && writeRequested && 
+                               obj->my_dev->read_only){
+                               openDenied = 1;
+                               yaffsfs_SetError(-EROFS);
+                               errorReported = 1;
+                       }
+
                        if(openDenied && !errorReported ) {
                                /* Error if the file exists but permissions are refused. */
                                yaffsfs_SetError(-EACCES);
@@ -820,7 +836,7 @@ int yaffs_open_sharing(const YCHAR *path, int oflag, int mode, int sharing)
                if(!obj && dir && !errorReported && (oflag & O_CREAT)) {
                        /* Let's see if we can create this file if it does not exist. */
                        if(dir->my_dev->read_only){
-                               yaffsfs_SetError(-EINVAL);
+                               yaffsfs_SetError(-EROFS);
                                errorReported = 1;
                        } else
                                obj = yaffs_create_file(dir,name,mode,0,0);
@@ -881,19 +897,23 @@ int yaffs_open(const YCHAR *path, int oflag, int mode)
 int yaffs_Dofsync(int fd,int datasync)
 {
        yaffsfs_Handle *h = NULL;
-       int retVal = 0;
+       int retVal = -1;
 
        yaffsfs_Lock();
 
        h = yaffsfs_GetHandlePointer(fd);
 
-       if(h && h->useCount > 0)
-               /* flush the file */
-               yaffs_flush_file(yaffsfs_inode[h->inodeId].iObj,1,datasync);
-       else {
-               /* bad handle */
+       if(!h || h->useCount < 1)
                yaffsfs_SetError(-EBADF);
-               retVal = -1;
+       else {
+               struct yaffs_obj * obj;
+               obj = yaffsfs_inode[h->inodeId].iObj;
+               if(obj->my_dev->read_only)
+                       yaffsfs_SetError(-EROFS);
+               else {          
+                       yaffs_flush_file(yaffsfs_inode[h->inodeId].iObj,1,datasync);
+                       retVal = 0;
+               }
        }
 
        yaffsfs_Unlock();
@@ -956,6 +976,11 @@ int yaffsfs_do_read(int fd, void *vbuf, unsigned int nbyte, int isPread, int off
        unsigned int maxRead;
        u8 *buf = (u8 *)vbuf;
 
+       if(!vbuf){
+               yaffsfs_SetError(-EFAULT);
+               return -1;
+       }
+
        yaffsfs_Lock();
        h = yaffsfs_GetHandlePointer(fd);
        obj = yaffsfs_GetHandleObject(fd);
@@ -1073,6 +1098,11 @@ int yaffsfs_do_write(int fd, const void *vbuf, unsigned int nbyte, int isPwrite,
        int nToWrite = 0;
        const u8 *buf = (const u8 *)vbuf;
 
+       if(!vbuf){
+               yaffsfs_SetError(-EFAULT);
+               return -1;
+       }
+
        yaffsfs_Lock();
        h = yaffsfs_GetHandlePointer(fd);
        obj = yaffsfs_GetHandleObject(fd);
@@ -1081,9 +1111,12 @@ int yaffsfs_do_write(int fd, const void *vbuf, unsigned int nbyte, int isPwrite,
                /* bad handle */
                yaffsfs_SetError(-EBADF);
                totalWritten = -1;
-       } else if( h && obj && (!h->writing || obj->my_dev->read_only)){
+       } else if(!h->writing){
                yaffsfs_SetError(-EINVAL);
                totalWritten=-1;
+       } else if(obj->my_dev->read_only){
+               yaffsfs_SetError(-EROFS);
+               totalWritten=-1;
        } else {
                if(h->append)
                        startPos = yaffs_get_obj_length(obj);
@@ -1175,6 +1208,11 @@ int yaffs_truncate(const YCHAR *path,off_t new_size)
        int notDir = 0;
        int loop = 0;
 
+       if(!path){
+               yaffsfs_SetError(-EFAULT);
+               return -1;
+       }
+
        if(yaffsfs_CheckPath(path) < 0){
                yaffsfs_SetError(-ENAMETOOLONG);
                return -1;
@@ -1183,6 +1221,7 @@ int yaffs_truncate(const YCHAR *path,off_t new_size)
        yaffsfs_Lock();
 
        obj = yaffsfs_FindObject(NULL,path,0,1,&dir,&notDir,&loop);
+       obj = yaffsfs_FollowLink(obj,0,&loop);
 
        if(!dir && notDir)
                yaffsfs_SetError(-ENOTDIR);
@@ -1190,10 +1229,12 @@ int yaffs_truncate(const YCHAR *path,off_t new_size)
                yaffsfs_SetError(-ELOOP);
        else if(!dir || !obj)
                yaffsfs_SetError(-ENOENT);
+       else if(obj->my_dev->read_only)
+               yaffsfs_SetError(-EROFS);
        else if(obj->variant_type != YAFFS_OBJECT_TYPE_FILE)
                yaffsfs_SetError(-EISDIR);
        else if(obj->my_dev->read_only)
-               yaffsfs_SetError(-EACCES);
+               yaffsfs_SetError(-EROFS);
        else if(new_size < 0 || new_size > YAFFS_MAX_FILE_SIZE)
                yaffsfs_SetError(-EINVAL);
        else
@@ -1217,8 +1258,10 @@ int yaffs_ftruncate(int fd, off_t new_size)
        if(!h || !obj)
                /* bad handle */
                yaffsfs_SetError(-EBADF);
+       else if(!h->writing)
+               yaffsfs_SetError(-EINVAL);
        else if(obj->my_dev->read_only)
-               yaffsfs_SetError(-EACCES);
+               yaffsfs_SetError(-EROFS);
        else if( new_size < 0 || new_size > YAFFS_MAX_FILE_SIZE)
                yaffsfs_SetError(-EINVAL);
        else
@@ -1281,6 +1324,11 @@ int yaffsfs_DoUnlink(const YCHAR *path,int isDirectory)
        int notDir = 0;
        int loop = 0;
 
+       if(!path){
+               yaffsfs_SetError(-EFAULT);
+               return -1;
+       }
+
        if(yaffsfs_CheckPath(path) < 0){
                yaffsfs_SetError(-ENAMETOOLONG);
                return -1;
@@ -1302,7 +1350,7 @@ int yaffsfs_DoUnlink(const YCHAR *path,int isDirectory)
        else if(!obj)
                yaffsfs_SetError(-ENOENT);
        else if(obj->my_dev->read_only)
-               yaffsfs_SetError(-EINVAL);
+               yaffsfs_SetError(-EROFS);
        else if(!isDirectory && obj->variant_type == YAFFS_OBJECT_TYPE_DIRECTORY)
                yaffsfs_SetError(-EISDIR);
        else if(isDirectory && obj->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY)
@@ -1344,7 +1392,13 @@ int yaffs_rename(const YCHAR *oldPath, const YCHAR *newPath)
 
        YCHAR *alt_newpath=NULL;
 
-       if(yaffsfs_CheckPath(newPath) < 0){
+       if(!oldPath || !newPath){
+               yaffsfs_SetError(-EFAULT);
+               return -1;
+       }
+
+       if(yaffsfs_CheckPath(oldPath) < 0 ||
+               yaffsfs_CheckPath(newPath) < 0){
                yaffsfs_SetError(-ENAMETOOLONG);
                return -1;
        }
@@ -1476,6 +1530,11 @@ static int yaffsfs_DoStatOrLStat(const YCHAR *path, struct yaffs_stat *buf,int d
        int notDir = 0;
        int loop = 0;
 
+       if(!path || !buf){
+               yaffsfs_SetError(-EFAULT);
+               return -1;
+       }
+
        if(yaffsfs_CheckPath(path) < 0){
                yaffsfs_SetError(-ENAMETOOLONG);
                return -1;
@@ -1519,6 +1578,11 @@ int yaffs_fstat(int fd, struct yaffs_stat *buf)
 
        int retVal = -1;
 
+       if(!buf){
+               yaffsfs_SetError(-EFAULT);
+               return -1;
+       }
+
        yaffsfs_Lock();
        obj = yaffsfs_GetHandleObject(fd);
 
@@ -1537,7 +1601,8 @@ int yaffs_fstat(int fd, struct yaffs_stat *buf)
 /* xattrib functions */
 
 
-static int yaffs_do_setxattr(const YCHAR *path, const char *name, const void *data, int size, int flags, int follow)
+static int yaffs_do_setxattr(const YCHAR *path, const char *name,
+                       const void *data, int size, int flags, int follow)
 {
        struct yaffs_obj *obj;
        struct yaffs_obj *dir;
@@ -1546,6 +1611,11 @@ static int yaffs_do_setxattr(const YCHAR *path, const char *name, const void *da
 
        int retVal = -1;
 
+       if(!path || !name || !data){
+               yaffsfs_SetError(-EFAULT);
+               return -1;
+       }
+
        if(yaffsfs_CheckPath(path) < 0){
                yaffsfs_SetError(-ENAMETOOLONG);
                return -1;
@@ -1596,6 +1666,11 @@ int yaffs_fsetxattr(int fd, const char *name, const void *data, int size, int fl
 
        int retVal = -1;
 
+       if(!name || !data){
+               yaffsfs_SetError(-EFAULT);
+               return -1;
+       }
+
        yaffsfs_Lock();
        obj = yaffsfs_GetHandleObject(fd);
 
@@ -1622,6 +1697,11 @@ static int yaffs_do_getxattr(const YCHAR *path, const char *name, void *data, in
        int notDir = 0;
        int loop = 0;
 
+       if(!path || !name || !data ){
+               yaffsfs_SetError(-EFAULT);
+               return -1;
+       }
+
        if(yaffsfs_CheckPath(path) < 0){
                yaffsfs_SetError(-ENAMETOOLONG);
                return -1;
@@ -1670,6 +1750,11 @@ int yaffs_fgetxattr(int fd, const char *name, void *data, int size)
 
        int retVal = -1;
 
+       if(!name || !data ){
+               yaffsfs_SetError(-EFAULT);
+               return -1;
+       }
+
        yaffsfs_Lock();
        obj = yaffsfs_GetHandleObject(fd);
 
@@ -1696,6 +1781,11 @@ static int yaffs_do_listxattr(const YCHAR *path, char *data, int size, int follo
        int notDir = 0;
        int loop = 0;
 
+       if(!path || !data ){
+               yaffsfs_SetError(-EFAULT);
+               return -1;
+       }
+
        if(yaffsfs_CheckPath(path) < 0){
                yaffsfs_SetError(-ENAMETOOLONG);
                return -1;
@@ -1744,6 +1834,11 @@ int yaffs_flistxattr(int fd, char *data, int size)
 
        int retVal = -1;
 
+       if(!data ){
+               yaffsfs_SetError(-EFAULT);
+               return -1;
+       }
+
        yaffsfs_Lock();
        obj = yaffsfs_GetHandleObject(fd);
 
@@ -1770,6 +1865,11 @@ static int yaffs_do_removexattr(const YCHAR *path, const char *name, int follow)
        int loop = 0;
        int retVal = -1;
 
+       if(!path || !name){
+               yaffsfs_SetError(-EFAULT);
+               return -1;
+       }
+
        if(yaffsfs_CheckPath(path) < 0){
                yaffsfs_SetError(-ENAMETOOLONG);
                return -1;
@@ -1818,6 +1918,11 @@ int yaffs_fremovexattr(int fd, const char *name)
 
        int retVal = -1;
 
+       if(!name){
+               yaffsfs_SetError(-EFAULT);
+               return -1;
+       }
+
        yaffsfs_Lock();
        obj = yaffsfs_GetHandleObject(fd);
 
@@ -1941,6 +2046,11 @@ int yaffs_access(const YCHAR *path, int amode)
        int loop = 0;
        int retval = -1;
 
+       if(!path){
+               yaffsfs_SetError(-EFAULT);
+               return -1;
+       }
+
        if(yaffsfs_CheckPath(path) < 0){
                yaffsfs_SetError(-ENAMETOOLONG);
                return -1;
@@ -1962,7 +2072,9 @@ int yaffs_access(const YCHAR *path, int amode)
                yaffsfs_SetError(-ELOOP);
        else if(!dir || !obj) 
                yaffsfs_SetError(-ENOENT);
-       else {
+       else if((amode & W_OK) && obj->my_dev->read_only)
+               yaffsfs_SetError(-EROFS);
+       else{
                int access_ok = 1;
 
                if((amode & R_OK) && !(obj->yst_mode & S_IREAD))
@@ -1993,6 +2105,11 @@ int yaffs_chmod(const YCHAR *path, mode_t mode)
        int notDir = 0;
        int loop = 0;
 
+       if(!path){
+               yaffsfs_SetError(-EFAULT);
+               return -1;
+       }
+
        if(yaffsfs_CheckPath(path) < 0){
                yaffsfs_SetError(-ENAMETOOLONG);
                return -1;
@@ -2006,6 +2123,7 @@ int yaffs_chmod(const YCHAR *path, mode_t mode)
        yaffsfs_Lock();
 
        obj = yaffsfs_FindObject(NULL,path,0,1, &dir, &notDir,&loop);
+       obj = yaffsfs_FollowLink(obj,0,&loop);
 
        if(!dir && notDir) 
                yaffsfs_SetError(-ENOTDIR);
@@ -2060,6 +2178,11 @@ int yaffs_mkdir(const YCHAR *path, mode_t mode)
        int notDir = 0;
        int loop = 0;
 
+       if(!path){
+               yaffsfs_SetError(-EFAULT);
+               return -1;
+       }
+
        if(yaffsfs_CheckPath(path) < 0){
                yaffsfs_SetError(-ENAMETOOLONG);
                return -1;
@@ -2108,6 +2231,11 @@ int yaffs_rmdir(const YCHAR *path)
        int result;
        YCHAR *alt_path;
 
+       if(!path){
+               yaffsfs_SetError(-EFAULT);
+               return -1;
+       }
+
        if(yaffsfs_CheckPath(path) < 0){
                yaffsfs_SetError(-ENAMETOOLONG);
                return -1;
@@ -2140,6 +2268,11 @@ int yaffs_mount2(const YCHAR *path,int read_only)
        int result=YAFFS_FAIL;
        struct yaffs_dev *dev=NULL;
 
+       if(!path){
+               yaffsfs_SetError(-EFAULT);
+               return -1;
+       }
+
        T(YAFFS_TRACE_MOUNT,(TSTR("yaffs: Mounting %s" TENDSTR),path));
 
        if(yaffsfs_CheckPath(path) < 0){
@@ -2182,6 +2315,11 @@ int yaffs_sync(const YCHAR *path)
         struct yaffs_dev *dev=NULL;
         YCHAR *dummy;
 
+       if(!path){
+               yaffsfs_SetError(-EFAULT);
+               return -1;
+       }
+
        if(yaffsfs_CheckPath(path) < 0){
                yaffsfs_SetError(-ENAMETOOLONG);
                return -1;
@@ -2190,15 +2328,17 @@ int yaffs_sync(const YCHAR *path)
         yaffsfs_Lock();
         dev = yaffsfs_FindDevice(path,&dummy);
         if(dev){
-                if(dev->is_mounted){
+                if(!dev->is_mounted)
+                       yaffsfs_SetError(-EINVAL);
+               else if(dev->read_only)
+                       yaffsfs_SetError(-EROFS);
+               else {
                         
                         yaffs_flush_whole_cache(dev);
                         yaffs_checkpoint_save(dev);
                         retVal = 0;
                         
-                } else
-                        yaffsfs_SetError(-EINVAL);
-                        
+                }      
         }else
                 yaffsfs_SetError(-ENODEV);
 
@@ -2213,6 +2353,11 @@ int yaffs_remount(const YCHAR *path, int force, int read_only)
        struct yaffs_dev *dev=NULL;
        yaffsfs_Handle *yh;
 
+       if(!path){
+               yaffsfs_SetError(-EFAULT);
+               return -1;
+       }
+
        if(yaffsfs_CheckPath(path) < 0){
                yaffsfs_SetError(-ENAMETOOLONG);
                return -1;
@@ -2259,6 +2404,11 @@ int yaffs_unmount2(const YCHAR *path, int force)
         int retVal=-1;
        struct yaffs_dev *dev=NULL;
 
+       if(!path){
+               yaffsfs_SetError(-EFAULT);
+               return -1;
+       }
+
        if(yaffsfs_CheckPath(path) < 0){
                yaffsfs_SetError(-ENAMETOOLONG);
                return -1;
@@ -2311,6 +2461,11 @@ loff_t yaffs_freespace(const YCHAR *path)
        struct yaffs_dev *dev=NULL;
        YCHAR *dummy;
 
+       if(!path){
+               yaffsfs_SetError(-EFAULT);
+               return -1;
+       }
+
        if(yaffsfs_CheckPath(path) < 0){
                yaffsfs_SetError(-ENAMETOOLONG);
                return -1;
@@ -2335,6 +2490,11 @@ loff_t yaffs_totalspace(const YCHAR *path)
        struct yaffs_dev *dev=NULL;
        YCHAR *dummy;
 
+       if(!path){
+               yaffsfs_SetError(-EFAULT);
+               return -1;
+       }
+
        if(yaffsfs_CheckPath(path) < 0){
                yaffsfs_SetError(-ENAMETOOLONG);
                return -1;
@@ -2361,6 +2521,11 @@ int yaffs_inodecount(const YCHAR *path)
        struct yaffs_dev *dev=NULL;
        YCHAR *dummy;
 
+       if(!path){
+               yaffsfs_SetError(-EFAULT);
+               return -1;
+       }
+
        if(yaffsfs_CheckPath(path) < 0){
                yaffsfs_SetError(-ENAMETOOLONG);
                return -1;
@@ -2498,6 +2663,11 @@ yaffs_DIR *yaffs_opendir(const YCHAR *dirname)
        int notDir = 0;
        int loop = 0;
 
+       if(!dirname){
+               yaffsfs_SetError(-EFAULT);
+               return NULL;
+       }
+
        if(yaffsfs_CheckPath(dirname) < 0){
                yaffsfs_SetError(-ENAMETOOLONG);
                return NULL;
@@ -2591,6 +2761,11 @@ int yaffs_closedir(yaffs_DIR *dirp)
 {
        yaffsfs_DirectorySearchContext *dsc = (yaffsfs_DirectorySearchContext *)dirp;
 
+       if(!dsc){
+               yaffsfs_SetError(-EFAULT);
+               return -1;
+       }
+
         yaffsfs_Lock();
         dsc->magic = 0;
         list_del(&dsc->others); /* unhook from list */
@@ -2612,10 +2787,17 @@ int yaffs_symlink(const YCHAR *oldpath, const YCHAR *newpath)
        int notDir = 0;
        int loop = 0;
 
-       if(yaffsfs_CheckPath(newpath) < 0){
+       if(!oldpath || !newpath){
+               yaffsfs_SetError(-EFAULT);
+               return -1;
+       }
+
+       if(yaffsfs_CheckPath(newpath) < 0 ||
+               yaffsfs_CheckPath(oldpath) < 0){
                yaffsfs_SetError(-ENAMETOOLONG);
                return -1;
        }
+
        yaffsfs_Lock();
        parent = yaffsfs_FindDirectory(NULL,newpath,&name,0,&notDir,&loop);
        if(!parent && notDir)
@@ -2650,6 +2832,11 @@ int yaffs_readlink(const YCHAR *path, YCHAR *buf, int bufsiz)
        int notDir = 0;
        int loop = 0;
 
+       if(!path || !buf){
+               yaffsfs_SetError(-EFAULT);
+               return -1;
+       }
+
        yaffsfs_Lock();
 
        obj = yaffsfs_FindObject(NULL,path,0,1, &dir,&notDir,&loop);
@@ -2686,7 +2873,13 @@ int yaffs_link(const YCHAR *oldpath, const YCHAR *linkpath)
        int lnkLoop = 0;
        YCHAR *newname;
 
-       if(yaffsfs_CheckPath(linkpath) < 0){
+       if(!oldpath || !linkpath){
+               yaffsfs_SetError(-EFAULT);
+               return -1;
+       }
+
+       if(yaffsfs_CheckPath(linkpath) < 0 ||
+               yaffsfs_CheckPath(oldpath) < 0){
                yaffsfs_SetError(-ENAMETOOLONG);
                return -1;
        }
@@ -2704,7 +2897,7 @@ int yaffs_link(const YCHAR *oldpath, const YCHAR *linkpath)
        else if(!obj_dir || !lnk_dir || !obj)
                yaffsfs_SetError(-ENOENT);
        else if(obj->my_dev->read_only)
-               yaffsfs_SetError(-EINVAL);
+               yaffsfs_SetError(-EROFS);
        else if(lnk)
                yaffsfs_SetError(-EEXIST);
        else if(lnk_dir->my_dev != obj->my_dev)
@@ -2750,6 +2943,11 @@ int yaffs_n_handles(const YCHAR *path)
 {
        struct yaffs_obj *obj;
 
+       if(!path){
+               yaffsfs_SetError(-EFAULT);
+               return -1;
+       }
+
        if(yaffsfs_CheckPath(path) < 0){
                yaffsfs_SetError(-ENAMETOOLONG);
                return -1;