On 07/24/2015 07:50 PM, Andy Lutomirski wrote: > On Fri, Jul 24, 2015 at 6:47 AM, Denys Vlasenko <dvlas...@redhat.com> wrote: >> SYSCALL32 code is nearly identical to SYSCALL32, except for initial >> section. Merge them. >> >> The removal is split into two parts, to make review eaiser. This is part 1. >> >> auditsys_entry_common and auditsys_exit macros are indented one more tab >> without >> any changes. This prevents diff from becoming unreadable. >> They will be removed in part 2. > > I need to read these more closely, which is, at present, exceeding my > ability to look at asm. (See the big NMI thread.) I'll look soon. > > Meanwhile, this code is incredibly fragile wrt syscall restart. > (Syscall restart on compat is really weird.) Do we have a decent test > for it?
How about this? (Feel free to expand, this is a first cut only). $ ./test_restart [RUN] Test restart of read() [OK] Restart of read() worked [RUN] Test restart of recv() [OK] Restart of recv() worked #undef _GNU_SOURCE #define _GNU_SOURCE 1 #undef __USE_GNU #define __USE_GNU 1 #include <unistd.h> #include <stdlib.h> #include <string.h> #include <stdio.h> #include <signal.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/select.h> #include <sys/time.h> //#include <sys/ptrace.h> #include <sys/wait.h> void signal_SA_RESTART_empty_mask(int sig, void (*handler)(int)) { struct sigaction sa; memset(&sa, 0, sizeof(sa)); sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; sa.sa_handler = handler; sigaction(sig, &sa, NULL); } int make_writer(void) { int pid, fd[2]; if (pipe(fd)) exit(1); pid = fork(); if (pid < 0) exit(1); if (pid == 0) { /* child */ usleep(50*1000); write(fd[1], "123456789", 10); exit(0); } close(fd[1]); return fd[0]; } int make_sender(void) { int pid, fd[2]; if (socketpair(AF_UNIX, SOCK_STREAM, 0, fd)) exit(1); pid = fork(); if (pid < 0) exit(1); if (pid == 0) { /* child */ usleep(50*1000); write(fd[1], "123456789", 10); exit(0); } close(fd[1]); return fd[0]; } int got_sig; void sighandler(int sig) { got_sig = 1; } void prepare(char buf[10]) { got_sig = 0; strcpy(buf, "qwertyuio"); ualarm(25*1000, 0); } int check(const char *test_type, int len, char buf[10]) { int err = 0; if (len != 10 || strcmp(buf, "123456789") != 0) { printf("[FAIL]\tRestarted %s() returns wrong result\n", test_type); err = 1; } if (!got_sig) { printf("[FAIL]\tSignal was expected on %s read() but wasn't seen\n", test_type); err = 1; } if (!err) printf("[OK]\tRestart of %s() worked\n", test_type); return err; } int main(int argc, char **argv, char **envp) { char buf[10]; int fd; int len; int err; signal_SA_RESTART_empty_mask(SIGALRM, sighandler); printf("[RUN]\tTest restart of read()\n"); fd = make_writer(); prepare(buf); len = read(fd, buf, 10); err = check("read", len, buf); close(fd); printf("[RUN]\tTest restart of recv()\n"); fd = make_sender(); prepare(buf); len = recv(fd, buf, 10, MSG_PEEK); err |= check("recv", len, buf); if (!err) { /* Check that restarted recv() indeed had MSG_PEEK: * i.e. that it did not consume the data. */ strcpy(buf, "qwertyuio"); len = recv(fd, buf, 10, 0); if (len != 10 || strcmp(buf, "123456789") != 0) { printf("[FAIL]\tRestarted %s() had no MSG_PEEK flag\n", "recv"); err = 1; } } close(fd); return err; } -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/