Short packets arriving at the netlink should not be processed.
Previously, we suffered buffer read overruns. In principle this might
be some kind of security problem, as it might make it possible to read
and have returned parts of the buffer which were used previously for
other data. I haven't analysed this possibility in any detail.
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
struct icmphdr *icmph;
uint32_t source;
struct icmphdr *icmph;
uint32_t source;
+ if (buf->size < (int)sizeof(struct icmphdr)) return False;
iph=(struct iphdr *)buf->start;
icmph=(struct icmphdr *)buf->start;
if (iph->protocol==1) {
iph=(struct iphdr *)buf->start;
icmph=(struct icmphdr *)buf->start;
if (iph->protocol==1) {
*/
static uint16_t netlink_icmp_reply_len(struct buffer_if *buf)
{
*/
static uint16_t netlink_icmp_reply_len(struct buffer_if *buf)
{
+ if (buf->size < (int)sizeof(struct iphdr)) return 0;
struct iphdr *iph=(struct iphdr *)buf->start;
uint16_t hlen,plen;
struct iphdr *iph=(struct iphdr *)buf->start;
uint16_t hlen,plen;
struct netlink_client *client,
uint8_t type, uint8_t code)
{
struct netlink_client *client,
uint8_t type, uint8_t code)
{
- struct iphdr *iph=(struct iphdr *)buf->start;
struct icmphdr *h;
uint16_t len;
if (netlink_icmp_may_reply(buf)) {
struct icmphdr *h;
uint16_t len;
if (netlink_icmp_may_reply(buf)) {
+ struct iphdr *iph=(struct iphdr *)buf->start;
len=netlink_icmp_reply_len(buf);
h=netlink_icmp_tmpl(st,ntohl(iph->saddr),len);
h->type=type; h->code=code;
len=netlink_icmp_reply_len(buf);
h=netlink_icmp_tmpl(st,ntohl(iph->saddr),len);
h->type=type; h->code=code;
return False; \
}while(0)
return False; \
}while(0)
+ if (buf->size < (int)sizeof(struct iphdr)) BAD("len %"PRIu32"",buf->size);
struct iphdr *iph=(struct iphdr *)buf->start;
int32_t len;
struct iphdr *iph=(struct iphdr *)buf->start;
int32_t len;
struct netlink_client *client,
struct buffer_if *buf)
{
struct netlink_client *client,
struct buffer_if *buf)
{
+ if (buf->size < (int)sizeof(struct iphdr)) {
+ Message(M_ERR,"%s: trying to deliver a too-short packet"
+ " from %s!\n",st->name, client?client->name:"(local)");
+ BUF_FREE(buf);
+ return;
+ }
+
struct iphdr *iph=(struct iphdr *)buf->start;
uint32_t dest=ntohl(iph->daddr);
uint32_t source=ntohl(iph->saddr);
struct iphdr *iph=(struct iphdr *)buf->start;
uint32_t dest=ntohl(iph->daddr);
uint32_t source=ntohl(iph->saddr);
struct netlink_client *client,
struct buffer_if *buf)
{
struct netlink_client *client,
struct buffer_if *buf)
{
+ if (buf->size < (int)sizeof(struct iphdr)) return;
struct iphdr *iph=(struct iphdr *)buf->start;
BUF_ASSERT_USED(buf);
struct iphdr *iph=(struct iphdr *)buf->start;
BUF_ASSERT_USED(buf);
+ if (buf->size < (int)sizeof(struct icmphdr)) {
+ Message(M_WARNING,"%s: short packet addressed to secnet; "
+ "ignoring it\n",st->name);
+ BUF_FREE(buf);
+ return;
+ }
h=(struct icmphdr *)buf->start;
if ((ntohs(h->iph.frag_off)&0xbfff)!=0) {
h=(struct icmphdr *)buf->start;
if ((ntohs(h->iph.frag_off)&0xbfff)!=0) {
+ assert(buf->size >= (int)sizeof(struct icmphdr));
iph=(struct iphdr *)buf->start;
source=ntohl(iph->saddr);
iph=(struct iphdr *)buf->start;
source=ntohl(iph->saddr);