Giter Club home page Giter Club logo

picotcp's Introduction

picotcp's People

Contributors

alexandervp avatar bogdanlu avatar brechtdevlieger avatar brunochevalier avatar danielinux avatar dekumans avatar frederikvs avatar jelledevleeschouwer avatar jonasvanpelt avatar jvzp avatar laurensmiers avatar ldoolitt avatar ludolinux avatar matthiasvp avatar maximevince avatar mhagmajer avatar micjo avatar milanplatisa avatar pdvloed avatar phalox avatar progval avatar q-thomas avatar ramenguy99 avatar rd235 avatar scribam avatar sergegadeyne avatar simonmaes avatar swendrickx avatar tassinfo avatar toonst avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

picotcp's Issues

Several Security Issues Report

Hi, I've found several potential issues in picoTCP v1.7.0 and picoTCP-NG v2.1. While it's difficult for these bugs to actually have an impact, I still think it's worth letting you know about and fixing these potential issues.

1. Integer Overflow in pico_icmp4_send_echo

The parameter cookie of function pico_icmp4_send_echo is completely controllable by the developer. When the cookie->size is set to a large value, an integer overflow will occur when calculating transport_len (Line 393). PICO_ICMPHDR_UN_SIZE is specified as 8, so overflow occurs when the value of cookie->size larger than 65528.

If developers use PicoTCP to develop applications and allow remote visitors to set cookie->size, it may lead to out-of-bounds read and write, which may eventually lead to information leakage and even remote code execution.

static int8_t pico_icmp4_send_echo(struct pico_stack *S, struct pico_icmp4_ping_cookie *cookie)
{
struct pico_frame *echo = NULL;
struct pico_icmp4_hdr *hdr;
struct pico_device *dev = pico_ipv4_source_dev_find(S, &cookie->dst);
if (!dev)
return -1;
echo = pico_proto_ipv4.alloc(S, &pico_proto_ipv4, dev, (uint16_t)(PICO_ICMPHDR_UN_SIZE + cookie->size));
if (!echo)
return -1;
hdr = (struct pico_icmp4_hdr *) echo->transport_hdr;
hdr->type = PICO_ICMP_ECHO;
hdr->code = 0;
hdr->hun.ih_idseq.idseq_id = short_be(cookie->id);
hdr->hun.ih_idseq.idseq_seq = short_be(cookie->seq);
echo->transport_len = (uint16_t)(PICO_ICMPHDR_UN_SIZE + cookie->size);
echo->payload = echo->transport_hdr + PICO_ICMPHDR_UN_SIZE;
echo->payload_len = cookie->size;
/* XXX: Fill payload */
pico_icmp4_checksum(echo);
pico_ipv4_frame_push(S, echo, &cookie->dst, PICO_PROTO_ICMP4);
return 0;
}

2. Integer Overflow in pico_socket_fionread

I think there are two potential integer overflows in the pico_socket_fionread function. When a packet that is too short is received, an integer underflow may occur when calculating f->payload_len of the received packet. This issue may occur when UDP packets are less than 8 bytes ([Line 1619]) or IPV4 packets are less than 20 bytes ([Line 1633). (just like CVE-2020-17443)
Although I didn't find where to call pico_socket_fionread, but to be on the safe side, I hope you can fix both issues.

picotcp/stack/pico_socket.c

Lines 1595 to 1642 in 72ffa74

int pico_socket_fionread(struct pico_socket *s)
{
struct pico_frame *f;
if (s == NULL) {
pico_err = PICO_ERR_EINVAL;
return -1;
} else {
if (pico_check_socket(s) != 0) {
pico_err = PICO_ERR_EINVAL;
return -1;
}
}
if ((s->state & PICO_SOCKET_STATE_BOUND) == 0) {
pico_err = PICO_ERR_EIO;
return -1;
}
if (PROTO(s) == PICO_PROTO_UDP)
{
f = pico_queue_peek(&s->q_in);
if (!f)
return 0;
if(!f->payload_len) {
f->payload = f->transport_hdr + sizeof(struct pico_udp_hdr);
f->payload_len = (uint16_t)(f->transport_len - sizeof(struct pico_udp_hdr));
}
return f->payload_len;
}
#ifdef PICO_SUPPORT_RAWSOCKETS
else if (PROTO(s) == PICO_PROTO_IPV4) {
struct pico_socket_ipv4 *s4 = (struct pico_socket_ipv4 *)s;
f = pico_queue_peek(&s->q_in);
if (!f)
return 0;
if(!f->payload_len) {
f->payload = f->net_hdr + f->net_len;
f->payload_len = (uint16_t)(f->len);
if (!s4->hdr_included)
f->payload_len = (uint16_t)(f->payload_len - PICO_SIZE_IP4HDR);
}
return f->payload_len;
}
#endif
else if (PROTO(s) == PICO_PROTO_TCP) {
return pico_tcp_queue_in_size(s);
}
return 0;
}

PicoTCP unable to use loopback devices.

I have written a custom device to my application to allow PicoTCP to send and receive data over raw sockets on Linux. (e.g. using socket (AF_PACKET, SOCK_RAW, htons (ETH_P_ALL)), with sendto and recvfrom) which is working well when sending traffic between hosts. (e.g. one app with PicoTCP embedded acting as a TCP server on one host and another app acting as the TCP client on another host).

However, it would be helpful to also run this for testing purposes with both client and server running on the same host (either on a loop-back adapter or even on a physical adapter) . Unfortunately, when the client is listening for its responses on the same IP address as the server it is intending to send it's packets to, rather than the out-bound packets being sent down to the device layer to be written to the link, the client application attempts to process the out-bound packet itself resulting in an error message saying "No such port".

It would seem that the design (understandably) is such that the stack assumes it has exclusive ownership of any IP it is managing, but is there any means to modify this behavior?

Double Free Issue Report

I found a security issue in picoTCP v1.7.0 and picoTCP-NG v2.1. It's a double free bug in function pico_fragments_reassemble (Line 362 and Line 364 in modules/pico_fragments.c ).

In function pico_transport_receive, when the switch goes into a default branch, it would release f (Line 239 in stack/pico_stack.c) and return -1. However, after -1 have been return from pico_transport_receive(full, proto) (Line 362 in modules/pico_fragments.c), another pico_frame_discard(full)(Line 364 in modules/pico_fragments.c) would be called and pico_frame_discard release full again. This leads a double free bug.

TCP Handshake failing

Hi All,

I am currently trying to port from the original PicoTCP to PicoTCP-NG and ecountered an issue.
As I was not yet able to find the source of the bug, I am kindly asking for your help/advice.

During the Handshake process, the following check in module/pico_tcp.c: tcp_parse_options fails:

static int tcp_parse_options(struct pico_frame *f)
{
    struct pico_socket_tcp *t = (struct pico_socket_tcp *)f->sock;
    uint8_t *opt = f->transport_hdr + PICO_SIZE_TCPHDR;
    uint32_t i = 0;
    f->timestamp = 0;

    if (f->buffer + f->buffer_len > f->transport_hdr + f->transport_len) //THIS CHECK FAILS
        return -1;

   [...]

I added some logging to the function and the output is as follows: (I cutted some output)

[...]
pico_tcp.c:2893: [sam] TCP> [tcp input] t_len: 40
pico_tcp.c:2894: [sam] TCP> flags = 0x02
pico_tcp.c:2895: [sam] TCP> s->state >> 8 = 2
pico_tcp.c:2896: [sam] TCP> [tcp input] socket: 0x1a7014 state: 2 <-- local port:5555 remote port: 59288 seq: 0x5e7f74ae ack: 0x00000000 flags: 0x02 t_len: 40, hdr: 40 payload: 0

pico_tcp.c:897: f->buffer + f->buffer_len (1733274) > f-transport_hdr + f->transport_len(1733270)
pico_tcp.c:898: f->buffer: 1733196 f->buffer_len: 78
pico_tcp.c:898: f-transport_hdr: 1733230 f->transport_len: 40
[...]

This log repeats till the test ist shutdown.

As the above check returns with -1 the frame is discarded and a handshake is never completed.

My understanding is, if the header len is 40, this means no options are present, therefore there are no options to parse.
Would it maybe correct if the return value of the check is instead 0? (in this case its working correct in my test)

I am not sure I 100% understand whats happening here, so I would be very glad if someone had some answers for me.

Kind Regards,
Felix

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.