[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Flag checking the bad way (+patch)
[Thread Prev] | [Thread Next]
- Subject: Flag checking the bad way (+patch)
- From: Tilo Eckert <tilo.eckert@xxxxxxx>
- Reply-to: libssh@xxxxxxxxxx
- Date: Wed, 22 Jul 2015 15:50:37 +0200
- To: libssh@xxxxxxxxxx
Hi, I compiled libssh on a non-Linux system where all the O_ and S_ file flags are defined differently. The way libssh checks these flags results in some unexpected behavior. File access modes are defined as: #define O_WRONLY 0x01 #define O_RDONLY 0x02 #define O_RDWR 0x03 The way mode flags are checked in sftp_open resulted in read-only and write-only being translated to read-write. For flags which may have more than one bit set, ANDing them with the variable and checking for non-zero is not sufficient. Instead, the following pattern must be used (which is always a good idea to use to avoid such platform-dependency issues): if (((flags & FLAG) == FLAG)) Since the S_IF flags values are different too, sftp_parse_attr functions failed to translate the types of files received by sftp_readdir. Replacing all S_IF flags with own defines for platform-independence is a good idea. Patches for both are attached. Note that I only checked the SFTP module for flags issues. Someone might want to look for other similar places. Tilo
From 1a0b6de1b7e544b123132343e59e79028a4b7391 Mon Sep 17 00:00:00 2001
From: Tilo Eckert <tilo.eckert@xxxxxxx>
Date: Wed, 22 Jul 2015 15:26:56 +0200
Subject: fix file mode checks in sftp_open()
Signed-off-by: Tilo Eckert <tilo.eckert@xxxxxxx>
---
src/sftp.c | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/src/sftp.c b/src/sftp.c
index e925b52..ae7b7ef 100644
--- a/src/sftp.c
+++ b/src/sftp.c
@@ -1638,18 +1638,17 @@ sftp_file sftp_open(sftp_session sftp, const char *file, int flags,
attr.permissions = mode;
attr.flags = SSH_FILEXFER_ATTR_PERMISSIONS;
- if (flags == O_RDONLY)
- sftp_flags |= SSH_FXF_READ; /* if any of the other flag is set,
- READ should not be set initialy */
- if (flags & O_WRONLY)
+ if ((flags & O_RDONLY) == O_RDONLY)
+ sftp_flags |= SSH_FXF_READ;
+ if ((flags & O_WRONLY) == O_WRONLY)
sftp_flags |= SSH_FXF_WRITE;
- if (flags & O_RDWR)
+ if ((flags & O_RDWR) == O_RDWR)
sftp_flags |= (SSH_FXF_WRITE | SSH_FXF_READ);
- if (flags & O_CREAT)
+ if ((flags & O_CREAT) == O_CREAT)
sftp_flags |= SSH_FXF_CREAT;
- if (flags & O_TRUNC)
+ if ((flags & O_TRUNC) == O_TRUNC)
sftp_flags |= SSH_FXF_TRUNC;
- if (flags & O_EXCL)
+ if ((flags & O_EXCL) == O_EXCL)
sftp_flags |= SSH_FXF_EXCL;
SSH_LOG(SSH_LOG_PACKET,"Opening file %s with sftp flags %x",file,sftp_flags);
id = sftp_get_new_id(sftp);
--
2.4.5
From ce313999b6fd4a85b7ed67ea0b3cf55ad6e676f0 Mon Sep 17 00:00:00 2001
From: Tilo Eckert <tilo.eckert@xxxxxxx>
Date: Wed, 22 Jul 2015 15:24:14 +0200
Subject: define our own platform-independent S_IF macros
Signed-off-by: Tilo Eckert <tilo.eckert@xxxxxxx>
---
include/libssh/sftp.h | 10 ++++++++++
src/sftp.c | 40 ++++++++++++++++------------------------
2 files changed, 26 insertions(+), 24 deletions(-)
diff --git a/include/libssh/sftp.h b/include/libssh/sftp.h
index 8fb8f11..6620841 100644
--- a/include/libssh/sftp.h
+++ b/include/libssh/sftp.h
@@ -962,6 +962,16 @@ void sftp_handle_remove(sftp_session sftp, void *handle);
#define SSH_FXF_EXCL 0x20
#define SSH_FXF_TEXT 0x40
+/* file type flags */
+#define SSH_S_IFMT 00170000
+#define SSH_S_IFSOCK 0140000
+#define SSH_S_IFLNK 0120000
+#define SSH_S_IFREG 0100000
+#define SSH_S_IFBLK 0060000
+#define SSH_S_IFDIR 0040000
+#define SSH_S_IFCHR 0020000
+#define SSH_S_IFIFO 0010000
+
/* rename flags */
#define SSH_FXF_RENAME_OVERWRITE 0x00000001
#define SSH_FXF_RENAME_ATOMIC 0x00000002
diff --git a/src/sftp.c b/src/sftp.c
index ae7b7ef..56093fb 100644
--- a/src/sftp.c
+++ b/src/sftp.c
@@ -38,14 +38,6 @@
#ifndef _WIN32
#include <netinet/in.h>
#include <arpa/inet.h>
-#else
-#define S_IFSOCK 0140000
-#define S_IFLNK 0120000
-
-#ifdef _MSC_VER
-#define S_IFBLK 0060000
-#define S_IFIFO 0010000
-#endif
#endif
#include "libssh/priv.h"
@@ -1008,20 +1000,20 @@ static sftp_attributes sftp_parse_attr_4(sftp_session sftp, ssh_buffer buf,
attr->permissions = ntohl(attr->permissions);
/* FIXME on windows! */
- switch (attr->permissions & S_IFMT) {
- case S_IFSOCK:
- case S_IFBLK:
- case S_IFCHR:
- case S_IFIFO:
+ switch (attr->permissions & SSH_S_IFMT) {
+ case SSH_S_IFSOCK:
+ case SSH_S_IFBLK:
+ case SSH_S_IFCHR:
+ case SSH_S_IFIFO:
attr->type = SSH_FILEXFER_TYPE_SPECIAL;
break;
- case S_IFLNK:
+ case SSH_S_IFLNK:
attr->type = SSH_FILEXFER_TYPE_SYMLINK;
break;
- case S_IFREG:
+ case SSH_S_IFREG:
attr->type = SSH_FILEXFER_TYPE_REGULAR;
break;
- case S_IFDIR:
+ case SSH_S_IFDIR:
attr->type = SSH_FILEXFER_TYPE_DIRECTORY;
break;
default:
@@ -1244,20 +1236,20 @@ static sftp_attributes sftp_parse_attr_3(sftp_session sftp, ssh_buffer buf,
goto error;
}
- switch (attr->permissions & S_IFMT) {
- case S_IFSOCK:
- case S_IFBLK:
- case S_IFCHR:
- case S_IFIFO:
+ switch (attr->permissions & SSH_S_IFMT) {
+ case SSH_S_IFSOCK:
+ case SSH_S_IFBLK:
+ case SSH_S_IFCHR:
+ case SSH_S_IFIFO:
attr->type = SSH_FILEXFER_TYPE_SPECIAL;
break;
- case S_IFLNK:
+ case SSH_S_IFLNK:
attr->type = SSH_FILEXFER_TYPE_SYMLINK;
break;
- case S_IFREG:
+ case SSH_S_IFREG:
attr->type = SSH_FILEXFER_TYPE_REGULAR;
break;
- case S_IFDIR:
+ case SSH_S_IFDIR:
attr->type = SSH_FILEXFER_TYPE_DIRECTORY;
break;
default:
--
2.4.5
| Re: Flag checking the bad way (+patch) | Andreas Schneider <asn@xxxxxxxxxxxxxx> |