ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Linux-NBD/eg/attach-bin
Revision: 1.1
Committed: Thu May 8 23:43:43 2003 UTC (21 years ago) by root
Branch: MAIN
CVS Tags: rel-1_0, rel-0_91, rel-0_9, HEAD
Log Message:
*** empty log message ***

File Contents

# Content
1 #!/usr/bin/perl
2
3 # (c)2003 Marc Alexander Lehmann <nbd@plan9.de>
4 #
5 # This file is released under the General Public License, version 2 or later.
6
7 require v5.8;
8
9 use strict 'subs';
10
11 use Socket;
12 use IO::Socket::INET;
13
14 $VERSION = 0.1;
15
16 #############################################################################
17
18 $DEV = "/dev/nd0";
19
20 umask 077;
21
22 for (0..7) {
23 -e "/dev/nd$_" || qx<sh -x -c "mknod /dev/nd$_ b 43 $_">;
24 }
25
26 print <<EOF;
27
28 WARNING: This program contains a locally exploitable race condition.
29 EOF
30
31 sub NBD_SET_SOCK (){ 0x0000ab00 }
32 sub NBD_SET_BLKSIZE (){ 0x0000ab01 }
33 sub NBD_SET_SIZE (){ 0x0000ab02 }
34 sub NBD_DO_IT (){ 0x0000ab03 }
35 sub NBD_CLEAR_SOCK (){ 0x0000ab04 }
36 sub NBD_CLEAR_QUE (){ 0x0000ab05 }
37 sub NBD_PRINT_DEBUG (){ 0x0000ab06 }
38 sub NBD_SET_SIZE_BLOCKS (){ 0x0000ab07 }
39 sub NBD_DISCONNECT (){ 0x0000ab08 }
40
41 open ND, "+<", $DEV or die "$DEV: $!";
42
43 ioctl ND, NBD_CLEAR_QUE, my $x or die "NBD_CLEAR_QUE: $!";
44 ioctl ND, NBD_DISCONNECT, my $x;
45 ioctl ND, NBD_CLEAR_SOCK, my $x;
46
47 #############################################################################
48
49 $BIN = shift or die "usage: $0 iso9660.bin";
50
51 open BIN, "<", $BIN or die "$BIN: $!";
52
53 # create a socketpair... ugh
54 my $srv = new IO::Socket::INET LocalHost => "127.0.0.1", Listen => 1
55 or die "unable to create listen socket: $!";
56 my $cli = new IO::Socket::INET PeerHost => $srv->sockhost, PeerPort => $srv->sockport
57 or die "unable to connect to listen socket: $!";
58 $srv = $srv->accept
59 or die "accept: $!";
60
61 # TODO: should exchange secure token, but I don't care for races now
62
63 ioctl ND, NBD_SET_SOCK, 0 + fileno $cli or die "NBD_SET_SOCK: $!";
64
65 sub REQ_MAGIC () { 0x25609513 }
66 sub REQ($) { unpack "N N a8 NN N", $_[0] }
67 sub REQ_SIZE (){ 4+4+4 + 8 + 8 }
68 sub REP_MAGIC () { 0x67446698 }
69 sub REP($$$;$) { pack "N N a8 a*", @_ }
70
71 if (!($srv_pid = fork)) {
72 ioctl ND, NBD_DO_IT, my $x
73 or die "unable do _do_ _it_: $!";
74 exit;
75 }
76
77 $SIG{INT} =
78 $SIG{TERM} =
79 $SIG{QUIT} =
80 $SIG{HUP} = sub { exit };
81
82 sub END {
83 if ($srv_pid) {
84 print "killing server...\n";
85 kill 9, $srv_pid;
86 }
87 print "bye.\n";
88 }
89
90 #if (fork == 0) {
91 # system "isoinfo", "-l", "-i", $DEV;
92 # _exit(1);
93 #}
94
95 print <<EOF;
96
97 Everything seems to be set up now, try sth. like:
98
99 mount -tiso9660 $DEV /mnt
100
101 Press ^C to exit...
102 EOF
103
104 while (REQ_SIZE == sysread $srv, my $req, REQ_SIZE) {
105 my ($magic, $type, $handle, undef, $from, $len) = REQ $req;
106
107 $magic == REQ_MAGIC
108 or die "protocol error (magic number mismatch)";
109
110 my ($from_l, $from_h) = ($from & 2047, $from >> 11);
111
112 if ($type == 0) {
113 printf "READ %08x \@%08x (block $from_h+$from_l)\n", $len, $from;
114
115 syswrite $srv, REP REP_MAGIC, 0, $handle;
116
117 while ($len) {
118 sysseek BIN, ($from_h * 2352) + $from_l + 0x18, 0
119 or die;
120
121 $from_l = 2048 - $from_l;
122 $from_l < $len or $from_l = $len;
123
124 sysread BIN, my $buf, $from_l;
125
126 $from_l == length $buf or $buf = "\x0" x $from_l;
127
128 syswrite $srv, $buf;
129
130 $len -= $from_l;
131
132 $from_l = 0;
133 $from_h++;
134 }
135 } elsif ($type == 1) {
136 die "write not supported\n";
137 } elsif ($type == 2) {
138 print "disconnect requested, exiting...\n";
139 last;
140 } else {
141 die "unsupported operation ($type)\n";
142 }
143 }
144