check_uidgid(ipfw_insn_u32 *insn, int proto, struct ifnet *oif,
struct in_addr dst_ip, u_int16_t dst_port, struct in_addr src_ip,
u_int16_t src_port, struct ip_fw_ugid *ugp, int *ugid_lookupp,
- struct inpcb *inp)
+ struct inpcb *inp, struct sk_buff *skb)
{
-#if 1
- return 0;
-#else
+#if 1 /* Linux */
+
+ const struct file *filp;
+
+ if (insn->o.opcode == O_JAIL)
+ return 0;
+
+ if (skb->sk == NULL || skb->sk->sk_socket == NULL)
+ return 0;
+
+ filp = skb->sk->sk_socket->file;
+ if (filp == NULL)
+ return 0;
+
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,28)
+/* use the current's real uid/gid */
+#define UID f_uid
+#define GID f_gid
+#else /* 2.6.29 */
+/* use the current's file access real uid/gid */
+#define UID f_cred->fsuid
+#define GID f_cred->fsgid
+#endif
+
+ if (insn->o.opcode == O_UID) {
+ if (filp->UID != (uid_t)insn->d[0])
+ return 0;
+ }
+
+ if (insn->o.opcode == O_GID) {
+ if (filp->GID != (gid_t)insn->d[0])
+ return 0;
+ }
+
+ return 1;
+
+#else /* FreeBSD original code */
struct inpcbinfo *pi;
int wildcard;
struct inpcb *pcb;
proto, oif,
dst_ip, dst_port,
src_ip, src_port, &fw_ugid_cache,
- &ugid_lookup, args->inp);
+ &ugid_lookup, args->inp, m->m_skb);
break;
case O_RECV: