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, 1 month ago) by root
Branch: MAIN
CVS Tags: rel-1_0, rel-0_91, rel-0_9, HEAD
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.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