File libssh2_org-CVE-2019-3860.patch of Package libssh2_org.30348

commit ed0d9bd45e4d55cb3ca600c70fa26c6b7bf9bf05
Author: Michael Buckley <michael@panic.com>
Date:   Wed Dec 5 10:35:19 2018 -0800

    Add a required_size parameter to sftp_packet_require et. al. to require callers of these functions to handle packets that are too short.

Index: src/sftp.c
===================================================================
--- src/sftp.c.orig
+++ src/sftp.c
@@ -505,11 +505,15 @@ sftp_packet_ask(LIBSSH2_SFTP *sftp, unsi
 static int
 sftp_packet_require(LIBSSH2_SFTP *sftp, unsigned char packet_type,
                     uint32_t request_id, unsigned char **data,
-                    size_t *data_len)
+                    size_t *data_len, size_t required_size)
 {
     LIBSSH2_SESSION *session = sftp->channel->session;
     int rc;
 
+    if (data == NULL || data_len == NULL || required_size == 0) {
+        return LIBSSH2_ERROR_BAD_USE;
+    }
+
     _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Requiring packet %d id %ld",
                    (int) packet_type, request_id);
 
@@ -517,6 +521,11 @@ sftp_packet_require(LIBSSH2_SFTP *sftp,
         /* The right packet was available in the packet brigade */
         _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Got %d",
                        (int) packet_type);
+
+        if (*data_len < required_size) {
+            return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
+        }
+
         return LIBSSH2_ERROR_NONE;
     }
 
@@ -530,6 +539,11 @@ sftp_packet_require(LIBSSH2_SFTP *sftp,
             /* The right packet was available in the packet brigade */
             _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Got %d",
                            (int) packet_type);
+
+            if (*data_len < required_size) {
+                return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
+            }
+
             return LIBSSH2_ERROR_NONE;
         }
     }
@@ -545,11 +559,15 @@ static int
 sftp_packet_requirev(LIBSSH2_SFTP *sftp, int num_valid_responses,
                      const unsigned char *valid_responses,
                      uint32_t request_id, unsigned char **data,
-                     size_t *data_len)
+                     size_t *data_len, size_t required_size)
 {
     int i;
     int rc;
 
+    if (data == NULL || data_len == NULL || required_size == 0) {
+        return LIBSSH2_ERROR_BAD_USE;
+    }
+
     /* If no timeout is active, start a new one */
     if (sftp->requirev_start == 0)
         sftp->requirev_start = time(NULL);
@@ -563,6 +581,11 @@ sftp_packet_requirev(LIBSSH2_SFTP *sftp,
                  * the timeout is not active
                  */
                 sftp->requirev_start = 0;
+
+                if (*data_len < required_size) {
+                    return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
+                }
+
                 return LIBSSH2_ERROR_NONE;
             }
         }
@@ -637,36 +660,65 @@ sftp_attr2bin(unsigned char *p, const LI
 /* sftp_bin2attr
  */
 static int
-sftp_bin2attr(LIBSSH2_SFTP_ATTRIBUTES * attrs, const unsigned char *p)
+sftp_bin2attr(LIBSSH2_SFTP_ATTRIBUTES * attrs, const unsigned char *p, size_t data_len)
 {
     const unsigned char *s = p;
 
-    memset(attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
-    attrs->flags = _libssh2_ntohu32(s);
-    s += 4;
+    if (data_len >= 4) {
+        memset(attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
+        attrs->flags = _libssh2_ntohu32(s);
+        s += 4;
+        data_len -= 4;
+    }
+    else {
+        return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
+    }
 
     if (attrs->flags & LIBSSH2_SFTP_ATTR_SIZE) {
-        attrs->filesize = _libssh2_ntohu64(s);
-        s += 8;
+        if (data_len >= 8) {
+            attrs->filesize = _libssh2_ntohu64(s);
+            s += 8;
+            data_len -= 8;
+        }
+        else {
+            return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
+        }
     }
 
     if (attrs->flags & LIBSSH2_SFTP_ATTR_UIDGID) {
-        attrs->uid = _libssh2_ntohu32(s);
-        s += 4;
-        attrs->gid = _libssh2_ntohu32(s);
-        s += 4;
+        if (data_len >= 8) {
+            attrs->uid = _libssh2_ntohu32(s);
+            s += 4;
+            attrs->gid = _libssh2_ntohu32(s);
+            s += 4;
+            data_len -= 8;
+        }
+        else {
+            return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
+        }
     }
 
     if (attrs->flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) {
-        attrs->permissions = _libssh2_ntohu32(s);
-        s += 4;
+        if (data_len >= 4) {
+            attrs->permissions = _libssh2_ntohu32(s);
+            s += 4;
+            data_len -= 4;
+        }
+        else {
+            return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
+        }
     }
 
     if (attrs->flags & LIBSSH2_SFTP_ATTR_ACMODTIME) {
-        attrs->atime = _libssh2_ntohu32(s);
-        s += 4;
-        attrs->mtime = _libssh2_ntohu32(s);
-        s += 4;
+        if (data_len >= 8) {
+            attrs->atime = _libssh2_ntohu32(s);
+            s += 4;
+            attrs->mtime = _libssh2_ntohu32(s);
+            s += 4;
+        }
+        else {
+            return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
+        }
     }
 
     return (s - p);
@@ -837,19 +889,25 @@ static LIBSSH2_SFTP *sftp_init(LIBSSH2_S
     }
 
     rc = sftp_packet_require(sftp_handle, SSH_FXP_VERSION,
-                             0, &data, &data_len);
-    if (rc == LIBSSH2_ERROR_EAGAIN)
-        return NULL;
-    else if (rc) {
-        _libssh2_error(session, rc,
-                       "Timeout waiting for response from SFTP subsystem");
-        goto sftp_init_error;
-    }
-    if (data_len < 5) {
-        _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
+			     0, &data, &data_len, 5);
+    if (rc == LIBSSH2_ERROR_EAGAIN) {
+	_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
+		       "Would block receiving SSH_FXP_VERSION");
+	return NULL;
+    }
+    else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
+	if (data_len > 0) {
+	    LIBSSH2_FREE(session, data);
+	}
+	_libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
                        "Invalid SSH_FXP_VERSION response");
         goto sftp_init_error;
     }
+    else if (rc) {
+	_libssh2_error(session, rc,
+		       "Timeout waiting for response from SFTP subsystem");
+	goto sftp_init_error;
+    }
 
     s = data + 1;
     sftp_handle->version = _libssh2_ntohu32(s);
@@ -1109,12 +1167,20 @@ sftp_open(LIBSSH2_SFTP *sftp, const char
             { SSH_FXP_HANDLE, SSH_FXP_STATUS };
         rc = sftp_packet_requirev(sftp, 2, fopen_responses,
                                   sftp->open_request_id, &data,
-                                  &data_len);
+                                  &data_len, 1);
         if (rc == LIBSSH2_ERROR_EAGAIN) {
             _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
                            "Would block waiting for status message");
             return NULL;
         }
+        else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
+            if (data_len > 0) {
+                LIBSSH2_FREE(session, data);
+            }
+            _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
+                           "Response too small");
+            return NULL;
+        }
         sftp->open_state = libssh2_NB_state_idle;
         if (rc) {
             _libssh2_error(session, rc, "Timeout waiting for status message");
@@ -1145,12 +1211,20 @@ sftp_open(LIBSSH2_SFTP *sftp, const char
                 /* silly situation, but check for a HANDLE */
                 rc = sftp_packet_require(sftp, SSH_FXP_HANDLE,
                                          sftp->open_request_id, &data,
-                                         &data_len);
+                                         &data_len, 10);
                 if(rc == LIBSSH2_ERROR_EAGAIN) {
                     /* go back to sent state and wait for something else */
                     sftp->open_state = libssh2_NB_state_sent;
                     return NULL;
                 }
+                else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
+                    if (data_len > 0) {
+                        LIBSSH2_FREE(session, data);
+                    }
+                    _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
+                                   "Too small FXP_HANDLE");
+                    return NULL;
+                }
                 else if(!rc)
                     /* we got the handle so this is not a bad situation */
                     badness = 0;
@@ -1247,6 +1321,7 @@ static ssize_t sftp_read(LIBSSH2_SFTP_HA
     ssize_t rc;
     struct _libssh2_sftp_handle_file_data *filep =
         &handle->u.file;
+     size_t bytes_in_buffer = 0;
 
     /* This function can be interrupted in three different places where it
        might need to wait for data from the network.  It returns EAGAIN to
@@ -1367,6 +1442,11 @@ static ssize_t sftp_read(LIBSSH2_SFTP_HA
             uint32_t packet_len = (uint32_t)handle->handle_len + 25;
             uint32_t request_id;
 
+	    if(size < buffer_size)
+		size = buffer_size;
+            if(size > MAX_SFTP_READ_SIZE)
+		size = MAX_SFTP_READ_SIZE;
+	    
             chunk = LIBSSH2_ALLOC(session, packet_len +
                                   sizeof(struct sftp_pipeline_chunk));
             if (!chunk)
@@ -1444,14 +1524,36 @@ static ssize_t sftp_read(LIBSSH2_SFTP_HA
                 SSH_FXP_DATA, SSH_FXP_STATUS
             };
 
-            if(chunk->lefttosend)
+            if(chunk->lefttosend) {
                 /* if the chunk still has data left to send, we shouldn't wait
                    for an ACK for it just yet */
+		if(bytes_in_buffer > 0) {
+                    return bytes_in_buffer;
+                }
+                else {
+                    /* we should never reach this point */
+                    return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
+                                          "sftp_read() internal error");
+		}
                 break;
+	    }
 
             rc = sftp_packet_requirev(sftp, 2, read_responses,
-                                      chunk->request_id, &data, &data_len);
-            if (rc < 0) {
+                                      chunk->request_id, &data, &data_len, 9);
+	    if (rc == LIBSSH2_ERROR_EAGAIN && bytes_in_buffer != 0) {
+		/* do not return EAGAIN if we have already
+		 * written data into the buffer */
+		return bytes_in_buffer;
+	    }
+
+            if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
+		if (data_len > 0) {
+		    LIBSSH2_FREE(session, data);
+                }
+                return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
+                                      "Response too small");
+            }
+	    else if(rc < 0) {
                 sftp->read_state = libssh2_NB_state_sent2;
                 return rc;
             }
@@ -1647,7 +1749,7 @@ static ssize_t sftp_readdir(LIBSSH2_SFTP
             if (attrs)
                 memset(attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
 
-            s += sftp_bin2attr(attrs ? attrs : &attrs_dummy, s);
+            s += sftp_bin2attr(attrs ? attrs : &attrs_dummy, s, 32);
 
             handle->u.dir.next_name = (char *) s;
           end:
@@ -1702,9 +1804,16 @@ static ssize_t sftp_readdir(LIBSSH2_SFTP
 
     retcode = sftp_packet_requirev(sftp, 2, read_responses,
                                    sftp->readdir_request_id, &data,
-                                   &data_len);
+                                   &data_len, 9);
     if (retcode == LIBSSH2_ERROR_EAGAIN)
         return retcode;
+    else if (retcode == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
+        if (data_len > 0) {
+            LIBSSH2_FREE(session, data);
+        }
+            return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
+                                  "Status message too short");
+    }
     else if (retcode) {
         sftp->readdir_state = libssh2_NB_state_idle;
         return _libssh2_error(session, retcode,
@@ -1930,8 +2039,15 @@ static ssize_t sftp_write(LIBSSH2_SFTP_H
 
             /* we check the packets in order */
             rc = sftp_packet_require(sftp, SSH_FXP_STATUS,
-                                     chunk->request_id, &data, &data_len);
-            if (rc < 0) {
+                                     chunk->request_id, &data, &data_len, 9);
+            if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
+                if (data_len > 0) {
+                    LIBSSH2_FREE(session, data);
+                }
+                return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
+                                      "FXP write packet too short");
+            }
+            else if (rc < 0) {
                 if (rc == LIBSSH2_ERROR_EAGAIN)
                     sftp->write_state = libssh2_NB_state_sent;
                 return rc;
@@ -2083,9 +2199,16 @@ static int sftp_fstat(LIBSSH2_SFTP_HANDL
 
     rc = sftp_packet_requirev(sftp, 2, fstat_responses,
                               sftp->fstat_request_id, &data,
-                              &data_len);
+                              &data_len, 9);
     if (rc == LIBSSH2_ERROR_EAGAIN)
         return rc;
+    else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
+        if (data_len > 0) {
+            LIBSSH2_FREE(session, data);
+        }
+        return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
+                              "SFTP fstat packet too short");
+    }
     else if (rc) {
         sftp->fstat_state = libssh2_NB_state_idle;
         return _libssh2_error(session, rc,
@@ -2108,7 +2231,12 @@ static int sftp_fstat(LIBSSH2_SFTP_HANDL
         }
     }
 
-    sftp_bin2attr(attrs, data + 5);
+    if (sftp_bin2attr(attrs, data + 5, data_len - 5) < 0) {
+        LIBSSH2_FREE(session, data);
+        return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
+                              "Attributes too short in SFTP fstat");
+    }
+
     LIBSSH2_FREE(session, data);
 
     return 0;
@@ -2280,11 +2408,19 @@ sftp_close_handle(LIBSSH2_SFTP_HANDLE *h
     if (handle->close_state == libssh2_NB_state_sent) {
         rc = sftp_packet_require(sftp, SSH_FXP_STATUS,
                                  handle->close_request_id, &data,
-                                 &data_len);
+                                 &data_len, 9);
         if (rc == LIBSSH2_ERROR_EAGAIN) {
             return rc;
-        } else if (rc) {
-            handle->close_state = libssh2_NB_state_idle;
+        } else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
+	    if (data_len > 0) {
+		LIBSSH2_FREE(session, data);
+            }
+            data = NULL;
+            _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
+                           "Packet too short in FXP_CLOSE command");
+	}
+	else if (rc) {
+	    handle->close_state = libssh2_NB_state_idle;
             return _libssh2_error(session, rc,
                                   "Error waiting for status message");
         }
@@ -2397,10 +2533,17 @@ static int sftp_unlink(LIBSSH2_SFTP *sft
 
     rc = sftp_packet_require(sftp, SSH_FXP_STATUS,
                              sftp->unlink_request_id, &data,
-                             &data_len);
+                             &data_len, 9);
     if (rc == LIBSSH2_ERROR_EAGAIN) {
         return rc;
     }
+    else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
+        if (data_len > 0) {
+            LIBSSH2_FREE(session, data);
+        }
+        return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
+                              "SFTP unlink packet too short");
+    }
     else if (rc) {
         sftp->unlink_state = libssh2_NB_state_idle;
         return _libssh2_error(session, rc,
@@ -2508,10 +2651,18 @@ static int sftp_rename(LIBSSH2_SFTP *sft
 
     rc = sftp_packet_require(sftp, SSH_FXP_STATUS,
                              sftp->rename_request_id, &data,
-                             &data_len);
+                             &data_len, 9);
     if (rc == LIBSSH2_ERROR_EAGAIN) {
         return rc;
-    } else if (rc) {
+    }
+    else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
+        if (data_len > 0) {
+            LIBSSH2_FREE(session, data);
+        }
+        return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
+                              "SFTP rename packet too short");
+    }
+    else if (rc) {
         sftp->rename_state = libssh2_NB_state_idle;
         return _libssh2_error(session, rc,
                               "Error waiting for FXP STATUS");
@@ -2631,10 +2782,17 @@ static int sftp_fstatvfs(LIBSSH2_SFTP_HA
     }
 
     rc = sftp_packet_require(sftp, SSH_FXP_EXTENDED_REPLY,
-                             sftp->fstatvfs_request_id, &data, &data_len);
+                             sftp->fstatvfs_request_id, &data, &data_len, 9);
     if (rc == LIBSSH2_ERROR_EAGAIN) {
         return rc;
-    } else if (rc) {
+    } else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
+	if (data_len > 0) {
+	    LIBSSH2_FREE(session, data);
+	}
+	return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
+			      "SFTP rename packet too short");
+    }
+    else if (rc) {
         sftp->fstatvfs_state = libssh2_NB_state_idle;
         return _libssh2_error(session, rc,
                               "Error waiting for FXP EXTENDED REPLY");
@@ -2744,10 +2902,17 @@ static int sftp_statvfs(LIBSSH2_SFTP *sf
     }
 
     rc = sftp_packet_require(sftp, SSH_FXP_EXTENDED_REPLY,
-                             sftp->statvfs_request_id, &data, &data_len);
+                             sftp->statvfs_request_id, &data, &data_len, 9);
     if (rc == LIBSSH2_ERROR_EAGAIN) {
         return rc;
-    } else if (rc) {
+    } else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
+	if (data_len > 0) {
+	    LIBSSH2_FREE(session, data);
+        }
+	return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
+			      "SFTP fstat packet too short");
+    }
+    else if (rc) {
         sftp->statvfs_state = libssh2_NB_state_idle;
         return _libssh2_error(session, rc,
                               "Error waiting for FXP EXTENDED REPLY");
@@ -2863,10 +3028,18 @@ static int sftp_mkdir(LIBSSH2_SFTP *sftp
     }
 
     rc = sftp_packet_require(sftp, SSH_FXP_STATUS, sftp->mkdir_request_id,
-                             &data, &data_len);
+                             &data, &data_len, 9);
     if (rc == LIBSSH2_ERROR_EAGAIN) {
         return rc;
-    } else if (rc) {
+    }
+    else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
+        if (data_len > 0) {
+            LIBSSH2_FREE(session, data);
+        }
+        return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
+                              "SFTP mkdir packet too short");
+    }
+    else if (rc) {
         sftp->mkdir_state = libssh2_NB_state_idle;
         return _libssh2_error(session, rc,
                               "Error waiting for FXP STATUS");
@@ -2957,10 +3130,18 @@ static int sftp_rmdir(LIBSSH2_SFTP *sftp
     }
 
     rc = sftp_packet_require(sftp, SSH_FXP_STATUS,
-                             sftp->rmdir_request_id, &data, &data_len);
+                             sftp->rmdir_request_id, &data, &data_len, 9);
     if (rc == LIBSSH2_ERROR_EAGAIN) {
         return rc;
-    } else if (rc) {
+    }
+    else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
+        if (data_len > 0) {
+            LIBSSH2_FREE(session, data);
+        }
+        return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
+                              "SFTP rmdir packet too short");
+    }
+    else if (rc) {
         sftp->rmdir_state = libssh2_NB_state_idle;
         return _libssh2_error(session, rc,
                               "Error waiting for FXP STATUS");
@@ -3070,9 +3251,16 @@ static int sftp_stat(LIBSSH2_SFTP *sftp,
     }
 
     rc = sftp_packet_requirev(sftp, 2, stat_responses,
-                              sftp->stat_request_id, &data, &data_len);
+                              sftp->stat_request_id, &data, &data_len, 9);
     if (rc == LIBSSH2_ERROR_EAGAIN)
         return rc;
+    else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
+        if (data_len > 0) {
+            LIBSSH2_FREE(session, data);
+        }
+        return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
+                              "SFTP stat packet too short");
+    }
     else if (rc) {
         sftp->stat_state = libssh2_NB_state_idle;
         return _libssh2_error(session, rc,
@@ -3096,7 +3284,12 @@ static int sftp_stat(LIBSSH2_SFTP *sftp,
     }
 
     memset(attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
-    sftp_bin2attr(attrs, data + 5);
+    if (sftp_bin2attr(attrs, data + 5, data_len - 5) < 0) {
+        LIBSSH2_FREE(session, data);
+        return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
+                              "Attributes too short in SFTP fstat");
+    }
+
     LIBSSH2_FREE(session, data);
 
     return 0;
@@ -3201,9 +3394,16 @@ static int sftp_symlink(LIBSSH2_SFTP *sf
 
     retcode = sftp_packet_requirev(sftp, 2, link_responses,
                                    sftp->symlink_request_id, &data,
-                                   &data_len);
+                                   &data_len, 9);
     if (retcode == LIBSSH2_ERROR_EAGAIN)
         return retcode;
+    else if (retcode == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
+        if (data_len > 0) {
+            LIBSSH2_FREE(session, data);
+        }
+        return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
+                              "SFTP symlink packet too short");
+    }
     else if (retcode) {
         sftp->symlink_state = libssh2_NB_state_idle;
         return _libssh2_error(session, retcode,
@@ -3233,6 +3433,14 @@ static int sftp_symlink(LIBSSH2_SFTP *sf
                               "no name entries");
     }
 
+    if (data_len < 13) {
+        if (data_len > 0) {
+            LIBSSH2_FREE(session, data);
+        }
+        return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
+                              "SFTP stat packet too short");
+    }
+
     /* this reads a u32 and stores it into a signed 32bit value */
     link_len = _libssh2_ntohu32(data + 9);
     if (link_len < target_len) {
openSUSE Build Service is sponsored by