Skip to content

[Overflow Bug]RTKLIB stream.c: overflow in STR_TCPCLI path parsing via oversized address component #791

@neosys007

Description

@neosys007
I would like to report another current-head `Intra-Object Overflow` in `src/stream.c`, this time in the TCP client path parser used by `STR_TCPCLI`.

The relevant current-head object layout is:

```c
typedef struct {
    int state;
    char saddr[256];
    int port;
    struct sockaddr_in addr;
    socket_t sock;
    int tcon;
    unsigned int tact;
    unsigned int tdis;
} tcp_t;

typedef struct {
    tcp_t svr;
    int toinact;
    int tirecon;
} tcpcli_t;
```

The open path is:

```c
static tcpcli_t *opentcpcli(const char *path, char *msg)
{
    tcpcli_t *tcpcli, tcpcli0 = {{0}};
    char port[256] = "";
    ...
    *tcpcli = tcpcli0;
    decodetcppath(path, tcpcli->svr.saddr, port, NULL, NULL, NULL, NULL);
    if (sscanf(port, "%d", &tcpcli->svr.port) < 1) {
        ...
    }
    ...
}
```

And the parser helper is:

```c
static void decodetcppath(const char *path, char *addr, char *port, char *user,
                          char *passwd, char *mntpnt, char *str)
{
    char buff[MAXSTRPATH], *p, *q;
    ...
    strcpy(buff, path);
    ...
    if ((q = strchr(p, ':'))) {
        *q = '\0';
        if (port) strcpy(port, q + 1);
    }
    if (addr) strcpy(addr, p);
}
```

Why I believe this is a real current-head bug:

1. The documented grammar is:

```text
STR_TCPCLI address:port
```

2. The total `path` can remain safely below `MAXSTRPATH == 1024`, so this is independent of the earlier `stream->path` overflow.

3. There is no validation that the parsed address component fits into:

```c
tcpcli->svr.saddr[256]
```

4. In `tcp_t`, `saddr[256]` is followed by the live members `port` and `addr`.

5. Even though the later `sscanf(port, "%d", &tcpcli->svr.port)` restores the integer `port`, the overflow into the adjacent `addr` field remains.

I built a reduced source-faithful proof that preserves the exact member order and the exact parser behavior. Its output is:

```text
path_len=277
distance_saddr_to_port=256
distance_saddr_to_addr=260
addr_component_len=272
overflow_bytes_past_saddr=17
parsed_port=1234
addr_prefix_hex=4141414141414141
addr_corrupted=1
```

This shows:

- the total path is only `277`
- the address component is `272`
- the overflow reaches beyond `saddr` and persists in the adjacent `addr` object

I am making a narrow claim:

- this is current-head
- it is reachable from the documented `STR_TCPCLI` grammar
- it is a real write-side intra-object overflow
- the concrete overwrite is `tcp_t.saddr[256]` into the following live members

The clean fix is to validate the address component length against `sizeof(tcpcli->svr.saddr) - 1` before copying, and replace raw `strcpy()` with a bounded copy.

Best regards
Pengpeng Hou
ISCAS

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions