db-d2/primevul-codebert-embeddings huggingface dataset:
Commit message: HID: hid-cypress: validate length of report

Make sure we have enough of a report structure to validate before
looking at it.

Reported-by: Benoit Camredon <benoit.camredon@airbus.com>
Tested-by: Benoit Camredon <benoit.camredon@airbus.com>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
CVE: CVE-2017-7273
CWE: CWE-703
Vulnerability description: The cp_report_fixup function in drivers/hid/hid-cypress.c in the Linux kernel 3.2 and 4.x before 4.9.4 allows physically proximate attackers to cause a denial of service (integer underflow) or possibly have unspecified other impact via a crafted HID report.

Project: linux
File: hid-cypress.c

static __u8 *cp_report_fixup(struct hid_device *hdev, __u8 *rdesc,
		unsigned int *rsize)
{
	unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
	unsigned int i;

 	if (!(quirks & CP_RDESC_SWAPPED_MIN_MAX))
 		return rdesc;
 
 	for (i = 0; i < *rsize - 4; i++)
 		if (rdesc[i] == 0x29 && rdesc[i + 2] == 0x19) {
 			rdesc[i] = 0x19;
			rdesc[i + 2] = 0x29;
			swap(rdesc[i + 3], rdesc[i + 1]);
		}
	return rdesc;
}
Commit message: xfrm_user: validate XFRM_MSG_NEWAE incoming ESN size harder

Kees Cook has pointed out that xfrm_replay_state_esn_len() is subject to
wrapping issues.  To ensure we are correctly ensuring that the two ESN
structures are the same size compare both the overall size as reported
by xfrm_replay_state_esn_len() and the internal length are the same.

CVE-2017-7184
Signed-off-by: Andy Whitcroft <apw@canonical.com>
Acked-by: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
CVE: CVE-2017-7184
CWE: CWE-284
Vulnerability description: The xfrm_replay_verify_len function in net/xfrm/xfrm_user.c in the Linux kernel through 4.10.6 does not validate certain size data after an XFRM_MSG_NEWAE update, which allows local users to obtain root privileges or cause a denial of service (heap-based out-of-bounds access) by leveraging the CAP_NET_ADMIN capability, as demonstrated during a Pwn2Own competition at CanSecWest 2017 for the Ubuntu 16.10 linux-image-* package 4.8.0.41.52.

Project: linux
File: xfrm_user.c

static inline int xfrm_replay_verify_len(struct xfrm_replay_state_esn *replay_esn,
					 struct nlattr *rp)
{
	struct xfrm_replay_state_esn *up;
	int ulen;

	if (!replay_esn || !rp)
		return 0;

 	up = nla_data(rp);
 	ulen = xfrm_replay_state_esn_len(up);
 
	if (nla_len(rp) < ulen || xfrm_replay_state_esn_len(replay_esn) != ulen)
 		return -EINVAL;
 
 	if (up->replay_window > up->bmp_len * sizeof(__u32) * 8)
		return -EINVAL;

	return 0;
}
Commit message: Fixed possible foveon buffer overrun (Secunia SA750000)
CVE: CVE-2017-6890
CWE: CWE-119
Vulnerability description: A boundary error within the "foveon_load_camf()" function (dcraw_foveon.c) when initializing a huffman table in LibRaw-demosaic-pack-GPL2 before 0.18.2 can be exploited to cause a stack-based buffer overflow.

Project: LibRaw-demosaic-pack-GPL2
File: dcraw_foveon.c

 void CLASS foveon_load_camf()
 {
   unsigned type, wide, high, i, j, row, col, diff;
  ushort huff[258], vpred[2][2] = {{512,512},{512,512}}, hpred[2];
 
   fseek (ifp, meta_offset, SEEK_SET);
   type = get4();  get4();  get4();
   wide = get4();
   high = get4();
   if (type == 2) {
     fread (meta_data, 1, meta_length, ifp);
     for (i=0; i < meta_length; i++) {
      high = (high * 1597 + 51749) % 244944;
      wide = high * (INT64) 301593171 >> 24;
      meta_data[i] ^= ((((high << 8) - wide) >> 1) + wide) >> 17;
    }
  } else if (type == 4) {
    free (meta_data);
    meta_data = (char *) malloc (meta_length = wide*high*3/2);
    merror (meta_data, "foveon_load_camf()");
    foveon_huff (huff);
    get4();
    getbits(-1);
    for (j=row=0; row < high; row++) {
      for (col=0; col < wide; col++) {
	diff = ljpeg_diff(huff);
	if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
	else         hpred[col & 1] += diff;
	if (col & 1) {
	  meta_data[j++] = hpred[0] >> 4;
	  meta_data[j++] = hpred[0] << 4 | hpred[1] >> 8;
	  meta_data[j++] = hpred[1];
        }
      }
    }
  } else
    fprintf (stderr,_("%s has unknown CAMF type %d.\n"), ifname, type);
}
Commit message: ucount: Remove the atomicity from ucount->count

Always increment/decrement ucount->count under the ucounts_lock.  The
increments are there already and moving the decrements there means the
locking logic of the code is simpler.  This simplification in the
locking logic fixes a race between put_ucounts and get_ucounts that
could result in a use-after-free because the count could go zero then
be found by get_ucounts and then be freed by put_ucounts.

A bug presumably this one was found by a combination of syzkaller and
KASAN.  JongWhan Kim reported the syzkaller failure and Dmitry Vyukov
spotted the race in the code.

Cc: stable@vger.kernel.org
Fixes: f6b2db1a3e8d ("userns: Make the count of user namespaces per user")
Reported-by: JongHwan Kim <zzoru007@gmail.com>
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Reviewed-by: Andrei Vagin <avagin@gmail.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
CVE: CVE-2017-6874
CWE: CWE-416
Vulnerability description: Race condition in kernel/ucount.c in the Linux kernel through 4.10.2 allows local users to cause a denial of service (use-after-free and system crash) or possibly have unspecified other impact via crafted system calls that leverage certain decrement behavior that causes incorrect interaction between put_ucounts and get_ucounts.

Project: linux
File: ucount.c

static struct ucounts *get_ucounts(struct user_namespace *ns, kuid_t uid)
{
	struct hlist_head *hashent = ucounts_hashentry(ns, uid);
	struct ucounts *ucounts, *new;

	spin_lock_irq(&ucounts_lock);
	ucounts = find_ucounts(ns, uid, hashent);
	if (!ucounts) {
		spin_unlock_irq(&ucounts_lock);

		new = kzalloc(sizeof(*new), GFP_KERNEL);
		if (!new)
			return NULL;
 
 		new->ns = ns;
 		new->uid = uid;
		atomic_set(&new->count, 0);
 
 		spin_lock_irq(&ucounts_lock);
 		ucounts = find_ucounts(ns, uid, hashent);
		if (ucounts) {
			kfree(new);
		} else {
			hlist_add_head(&new->node, hashent);
 			ucounts = new;
 		}
 	}
	if (!atomic_add_unless(&ucounts->count, 1, INT_MAX))
 		ucounts = NULL;
 	spin_unlock_irq(&ucounts_lock);
 	return ucounts;
 }

Project: linux
File: ucount.c

static void put_ucounts(struct ucounts *ucounts)
 {
 	unsigned long flags;
 
	if (atomic_dec_and_test(&ucounts->count)) {
		spin_lock_irqsave(&ucounts_lock, flags);
 		hlist_del_init(&ucounts->node);
		spin_unlock_irqrestore(&ucounts_lock, flags);
 
		kfree(ucounts);
	}
 }
Commit message: None
CVE: CVE-2017-6497
CWE: CWE-476
Vulnerability description: An issue was discovered in ImageMagick 6.9.7. A specially crafted psd file could lead to a NULL pointer dereference (thus, a DoS).

Project: ImageMagick

static MagickBooleanType ReadPSDChannel(Image *image,
  const ImageInfo *image_info,const PSDInfo *psd_info,LayerInfo* layer_info,
  const size_t channel,const PSDCompressionType compression,
  ExceptionInfo *exception)
{
  Image
    *channel_image,
    *mask;

  MagickOffsetType
    offset;

  MagickBooleanType
    status;

  channel_image=image;
  mask=(Image *) NULL;
  if (layer_info->channel_info[channel].type < -1)
    {
      const char
        *option;
      /*
        Ignore mask that is not a user supplied layer mask, if the mask is
        disabled or if the flags have unsupported values.
      */
      option=GetImageOption(image_info,"psd:preserve-opacity-mask");
      if ((layer_info->channel_info[channel].type != -2) ||
          (layer_info->mask.flags > 2) || ((layer_info->mask.flags & 0x02) &&
           (IsStringTrue(option) == MagickFalse)))
      {
        SeekBlob(image,layer_info->channel_info[channel].size-2,SEEK_CUR);
        return(MagickTrue);
       }
       mask=CloneImage(image,layer_info->mask.page.width,
         layer_info->mask.page.height,MagickFalse,exception);
      mask->matte=MagickFalse;
      channel_image=mask;
     }
 
   offset=TellBlob(image);
  status=MagickTrue;
  switch(compression)
  {
    case Raw:
      status=ReadPSDChannelRaw(channel_image,psd_info->channels,
        layer_info->channel_info[channel].type,exception);
      break;
    case RLE:
      {
        MagickOffsetType
          *sizes;

        sizes=ReadPSDRLESizes(channel_image,psd_info,channel_image->rows);
        if (sizes == (MagickOffsetType *) NULL)
          ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
            image->filename);
        status=ReadPSDChannelRLE(channel_image,psd_info,
          layer_info->channel_info[channel].type,sizes,exception);
        sizes=(MagickOffsetType *) RelinquishMagickMemory(sizes);
      }
      break;
    case ZipWithPrediction:
    case ZipWithoutPrediction:
#ifdef MAGICKCORE_ZLIB_DELEGATE
      status=ReadPSDChannelZip(channel_image,layer_info->channels,
        layer_info->channel_info[channel].type,compression,
        layer_info->channel_info[channel].size-2,exception);
#else
      (void) ThrowMagickException(exception,GetMagickModule(),
          MissingDelegateWarning,"DelegateLibrarySupportNotBuiltIn",
            "'%s' (ZLIB)",image->filename);
#endif
      break;
    default:
      (void) ThrowMagickException(exception,GetMagickModule(),TypeWarning,
        "CompressionNotSupported","'%.20g'",(double) compression);
      break;
  }

  SeekBlob(image,offset+layer_info->channel_info[channel].size-2,SEEK_SET);
  if (status == MagickFalse)
    {
      if (mask != (Image *) NULL)
        DestroyImage(mask);
      ThrowBinaryException(CoderError,"UnableToDecompressImage",
        image->filename);
    }
  layer_info->mask.image=mask;
  return(status);
}
Commit message: bplist: Make sure to bail out if malloc() fails in parse_string_node()

Credit to Wang Junjie <zhunkibatu@gmail.com> (#93)
CVE: CVE-2017-6435
CWE: CWE-119
Vulnerability description: The parse_string_node function in bplist.c in libimobiledevice libplist 1.12 allows local users to cause a denial of service (memory corruption) via a crafted plist file.

Project: libplist
File: bplist.c

static plist_t parse_string_node(const char **bnode, uint64_t size)
{
    plist_data_t data = plist_new_plist_data();
 
     data->type = PLIST_STRING;
     data->strval = (char *) malloc(sizeof(char) * (size + 1));
     memcpy(data->strval, *bnode, size);
     data->strval[size] = '\0';
     data->length = strlen(data->strval);

    return node_create(NULL, data);
}
Commit message: Exit gracefully in case of corrupted filters (Closes issue #782)
CVE: CVE-2017-6430
CWE: CWE-125
Vulnerability description: The compile_tree function in ef_compiler.c in the Etterfilter utility in Ettercap 0.8.2 and earlier allows remote attackers to cause a denial of service (out-of-bounds read) via a crafted filter.

Project: ettercap
File: ef_compiler.c

size_t compile_tree(struct filter_op **fop)
{
   int i = 1;
    struct filter_op *array = NULL;
    struct unfold_elm *ue;
 
   BUG_IF(tree_root == NULL);
   
    fprintf(stdout, " Unfolding the meta-tree ");
    fflush(stdout);
     
   /* start the recursion on the tree */
   unfold_blk(&tree_root);

   fprintf(stdout, " done.\n\n");

   /* substitute the virtual labels with real offsets */
   labels_to_offsets();
   
   /* convert the tailq into an array */
   TAILQ_FOREACH(ue, &unfolded_tree, next) {

      /* label == 0 means a real instruction */
      if (ue->label == 0) {
         SAFE_REALLOC(array, i * sizeof(struct filter_op));
         memcpy(&array[i - 1], &ue->fop, sizeof(struct filter_op));
         i++;
      }
   }
   
   /* always append the exit function to a script */
   SAFE_REALLOC(array, i * sizeof(struct filter_op));
   array[i - 1].opcode = FOP_EXIT;
   
   /* return the pointer to the array */
   *fop = array;
   
   return (i);
}
Commit message: irda: Fix lockdep annotations in hashbin_delete().

A nested lock depth was added to the hasbin_delete() code but it
doesn't actually work some well and results in tons of lockdep splats.

Fix the code instead to properly drop the lock around the operation
and just keep peeking the head of the hashbin queue.

Reported-by: Dmitry Vyukov <dvyukov@google.com>
Tested-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
CVE: CVE-2017-6348
CWE: CWE-200
Vulnerability description: The hashbin_delete function in net/irda/irqueue.c in the Linux kernel before 4.9.13 improperly manages lock dropping, which allows local users to cause a denial of service (deadlock) via crafted operations on IrDA devices.

Project: linux
File: irqueue.c

 int hashbin_delete( hashbin_t* hashbin, FREE_FUNC free_func)
 {
 	irda_queue_t* queue;
	unsigned long flags = 0;
	int i;

	IRDA_ASSERT(hashbin != NULL, return -1;);
 	IRDA_ASSERT(hashbin->magic == HB_MAGIC, return -1;);
 
 	/* Synchronize */
	if ( hashbin->hb_type & HB_LOCK ) {
		spin_lock_irqsave_nested(&hashbin->hb_spinlock, flags,
					 hashbin_lock_depth++);
	}
 
 	/*
 	 *  Free the entries in the hashbin, TODO: use hashbin_clear when
 	 *  it has been shown to work
 	 */
 	for (i = 0; i < HASHBIN_SIZE; i ++ ) {
		queue = dequeue_first((irda_queue_t**) &hashbin->hb_queue[i]);
		while (queue ) {
			if (free_func)
				(*free_func)(queue);
			queue = dequeue_first(
				(irda_queue_t**) &hashbin->hb_queue[i]);
 		}
 	}
 
	/* Cleanup local data */
	hashbin->hb_current = NULL;
 	hashbin->magic = ~HB_MAGIC;
 
 	/* Release lock */
	if ( hashbin->hb_type & HB_LOCK) {
 		spin_unlock_irqrestore(&hashbin->hb_spinlock, flags);
#ifdef CONFIG_LOCKDEP
		hashbin_lock_depth--;
#endif
	}
 
 	/*
 	 *  Free the hashbin structure
	 */
	kfree(hashbin);

	return 0;
}
Commit message: ip: fix IP_CHECKSUM handling

The skbs processed by ip_cmsg_recv() are not guaranteed to
be linear e.g. when sending UDP packets over loopback with
MSGMORE.
Using csum_partial() on [potentially] the whole skb len
is dangerous; instead be on the safe side and use skb_checksum().

Thanks to syzkaller team to detect the issue and provide the
reproducer.

v1 -> v2:
 - move the variable declaration in a tighter scope

Fixes: ad6f939ab193 ("ip: Add offset parameter to ip_cmsg_recv")
Reported-by: Andrey Konovalov <andreyknvl@google.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Acked-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
CVE: CVE-2017-6347
CWE: CWE-125
Vulnerability description: The ip_cmsg_recv_checksum function in net/ipv4/ip_sockglue.c in the Linux kernel before 4.10.1 has incorrect expectations about skb data layout, which allows local users to cause a denial of service (buffer over-read) or possibly have unspecified other impact via crafted system calls, as demonstrated by use of the MSG_MORE flag in conjunction with loopback UDP transmission.

Project: linux
File: ip_sockglue.c

static void ip_cmsg_recv_checksum(struct msghdr *msg, struct sk_buff *skb,
				  int tlen, int offset)
{
	__wsum csum = skb->csum;

 	if (skb->ip_summed != CHECKSUM_COMPLETE)
 		return;
 
	if (offset != 0)
		csum = csum_sub(csum,
				csum_partial(skb_transport_header(skb) + tlen,
					     offset, 0));
 
 	put_cmsg(msg, SOL_IP, IP_CHECKSUM, sizeof(__wsum), &csum);
 }
Commit message: tcp: avoid infinite loop in tcp_splice_read()

Splicing from TCP socket is vulnerable when a packet with URG flag is
received and stored into receive queue.

__tcp_splice_read() returns 0, and sk_wait_data() immediately
returns since there is the problematic skb in queue.

This is a nice way to burn cpu (aka infinite loop) and trigger
soft lockups.

Again, this gem was found by syzkaller tool.

Fixes: 9c55e01c0cc8 ("[TCP]: Splice receive support.")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reported-by: Dmitry Vyukov  <dvyukov@google.com>
Cc: Willy Tarreau <w@1wt.eu>
Signed-off-by: David S. Miller <davem@davemloft.net>
CVE: CVE-2017-6214
CWE: CWE-835
Vulnerability description: The tcp_splice_read function in net/ipv4/tcp.c in the Linux kernel before 4.9.11 allows remote attackers to cause a denial of service (infinite loop and soft lockup) via vectors involving a TCP packet with the URG flag.

Project: linux
File: tcp.c

ssize_t tcp_splice_read(struct socket *sock, loff_t *ppos,
			struct pipe_inode_info *pipe, size_t len,
			unsigned int flags)
{
	struct sock *sk = sock->sk;
	struct tcp_splice_state tss = {
		.pipe = pipe,
		.len = len,
		.flags = flags,
	};
	long timeo;
	ssize_t spliced;
	int ret;

	sock_rps_record_flow(sk);
	/*
	 * We can't seek on a socket input
	 */
	if (unlikely(*ppos))
		return -ESPIPE;

	ret = spliced = 0;

	lock_sock(sk);

	timeo = sock_rcvtimeo(sk, sock->file->f_flags & O_NONBLOCK);
	while (tss.len) {
		ret = __tcp_splice_read(sk, &tss);
		if (ret < 0)
			break;
		else if (!ret) {
			if (spliced)
				break;
			if (sock_flag(sk, SOCK_DONE))
				break;
			if (sk->sk_err) {
				ret = sock_error(sk);
				break;
			}
			if (sk->sk_shutdown & RCV_SHUTDOWN)
				break;
			if (sk->sk_state == TCP_CLOSE) {
				/*
				 * This occurs when user tries to read
				 * from never connected socket.
				 */
				if (!sock_flag(sk, SOCK_DONE))
					ret = -ENOTCONN;
				break;
			}
			if (!timeo) {
 				ret = -EAGAIN;
 				break;
 			}
 			sk_wait_data(sk, &timeo, NULL);
 			if (signal_pending(current)) {
 				ret = sock_intr_errno(timeo);
				break;
			}
			continue;
		}
		tss.len -= ret;
		spliced += ret;

		if (!timeo)
			break;
		release_sock(sk);
		lock_sock(sk);

		if (sk->sk_err || sk->sk_state == TCP_CLOSE ||
		    (sk->sk_shutdown & RCV_SHUTDOWN) ||
		    signal_pending(current))
			break;
	}

	release_sock(sk);

	if (spliced)
		return spliced;

	return ret;
}
Commit message: CVE-2017-5985: Ensure target netns is caller-owned

Before this commit, lxc-user-nic could potentially have been tricked into
operating on a network namespace over which the caller did not hold privilege.

This commit ensures that the caller is privileged over the network namespace by
temporarily dropping privilege.

Launchpad: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/1654676
Reported-by: Jann Horn <jannh@google.com>
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
CVE: CVE-2017-5985
CWE: CWE-862
Vulnerability description: lxc-user-nic in Linux Containers (LXC) allows local users with a lxc-usernet allocation to create network interfaces on the host and choose the name of those interfaces by leveraging lack of netns ownership check.

Project: lxc
File: lxc_user_nic.c

 static int rename_in_ns(int pid, char *oldname, char **newnamep)
 {
	int fd = -1, ofd = -1, ret, ifindex = -1;
 	bool grab_newname = false;
 
 	ofd = lxc_preserve_ns(getpid(), "net");
 	if (ofd < 0) {
		fprintf(stderr, "Failed opening network namespace path for '%d'.", getpid());
		return -1;
 	}
 
 	fd = lxc_preserve_ns(pid, "net");
 	if (fd < 0) {
		fprintf(stderr, "Failed opening network namespace path for '%d'.", pid);
		return -1;
 	}
 
	if (setns(fd, 0) < 0) {
		fprintf(stderr, "setns to container network namespace\n");
		goto out_err;
 	}
	close(fd); fd = -1;
 	if (!*newnamep) {
 		grab_newname = true;
 		*newnamep = VETH_DEF_NAME;
		if (!(ifindex = if_nametoindex(oldname))) {
			fprintf(stderr, "failed to get netdev index\n");
			goto out_err;
 		}
 	}
	if ((ret = lxc_netdev_rename_by_name(oldname, *newnamep)) < 0) {
		fprintf(stderr, "Error %d renaming netdev %s to %s in container\n", ret, oldname, *newnamep);
		goto out_err;
 	}
 	if (grab_newname) {
		char ifname[IFNAMSIZ], *namep = ifname;
 		if (!if_indextoname(ifindex, namep)) {
			fprintf(stderr, "Failed to get new netdev name\n");
			goto out_err;
 		}
 		*newnamep = strdup(namep);
 		if (!*newnamep)
			goto out_err;
 	}
	if (setns(ofd, 0) < 0) {
		fprintf(stderr, "Error returning to original netns\n");
		close(ofd);
		return -1;
 	}
	close(ofd);
 
	return 0;
 
out_err:
	if (ofd >= 0)
		close(ofd);
	if (setns(ofd, 0) < 0)
		fprintf(stderr, "Error returning to original network namespace\n");
 	if (fd >= 0)
 		close(fd);
	return -1;
 }
Commit message: ipv4: keep skb->dst around in presence of IP options

Andrey Konovalov got crashes in __ip_options_echo() when a NULL skb->dst
is accessed.

ipv4_pktinfo_prepare() should not drop the dst if (evil) IP options
are present.

We could refine the test to the presence of ts_needtime or srr,
but IP options are not often used, so let's be conservative.

Thanks to syzkaller team for finding this bug.

Fixes: d826eb14ecef ("ipv4: PKTINFO doesnt need dst reference")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reported-by: Andrey Konovalov <andreyknvl@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
CVE: CVE-2017-5970
CWE: CWE-476
Vulnerability description: The ipv4_pktinfo_prepare function in net/ipv4/ip_sockglue.c in the Linux kernel through 4.9.9 allows attackers to cause a denial of service (system crash) via (1) an application that makes crafted system calls or possibly (2) IPv4 traffic with invalid IP options.

Project: linux
File: ip_sockglue.c

void ipv4_pktinfo_prepare(const struct sock *sk, struct sk_buff *skb)
{
	struct in_pktinfo *pktinfo = PKTINFO_SKB_CB(skb);
	bool prepare = (inet_sk(sk)->cmsg_flags & IP_CMSG_PKTINFO) ||
		       ipv6_sk_rxinfo(sk);

	if (prepare && skb_rtable(skb)) {
		/* skb->cb is overloaded: prior to this point it is IP{6}CB
		 * which has interface index (iif) as the first member of the
		 * underlying inet{6}_skb_parm struct. This code then overlays
		 * PKTINFO_SKB_CB and in_pktinfo also has iif as the first
		 * element so the iif is picked up from the prior IPCB. If iif
		 * is the loopback interface, then return the sending interface
		 * (e.g., process binds socket to eth0 for Tx which is
		 * redirected to loopback in the rtable/dst).
		 */
		if (pktinfo->ipi_ifindex == LOOPBACK_IFINDEX)
			pktinfo->ipi_ifindex = inet_iif(skb);

		pktinfo->ipi_spec_dst.s_addr = fib_compute_spec_dst(skb);
	} else {
 		pktinfo->ipi_ifindex = 0;
 		pktinfo->ipi_spec_dst.s_addr = 0;
 	}
	skb_dst_drop(skb);
 }
Commit message: purple: Fix crash on ft requests from unknown contacts

Followup to 701ab81 (included in 3.5) which was a partial fix which only
improved things for non-libpurple file transfers (that is, just jabber)
CVE: CVE-2017-5668
CWE: CWE-476
Vulnerability description: bitlbee-libpurple before 3.5.1 allows remote attackers to cause a denial of service (NULL pointer dereference and crash) and possibly execute arbitrary code via a file transfer request for a contact that is not in the contact list.  NOTE: this vulnerability exists because of an incomplete fix for CVE-2016-10189.

Project: bitlbee

static gboolean prplcb_xfer_new_send_cb(gpointer data, gint fd, b_input_condition cond)
{
	PurpleXfer *xfer = data;
	struct im_connection *ic = purple_ic_by_pa(xfer->account);
	struct prpl_xfer_data *px = xfer->ui_data;
	PurpleBuddy *buddy;
	const char *who;

	buddy = purple_find_buddy(xfer->account, xfer->who);
	who = buddy ? purple_buddy_get_name(buddy) : xfer->who;

 	/* TODO(wilmer): After spreading some more const goodness in BitlBee,
 	   remove the evil cast below. */
 	px->ft = imcb_file_send_start(ic, (char *) who, xfer->filename, xfer->size);
 	px->ft->data = px;
 
 	px->ft->accept = prpl_xfer_accept;
	px->ft->canceled = prpl_xfer_canceled;
	px->ft->free = prpl_xfer_free;
	px->ft->write_request = prpl_xfer_write_request;

	return FALSE;
}