iptables gives input/output error - iptables

I am trying to have iptables-1.4.3.2 work with Linux-2.6.35.9 on our MIPS based platform. The command issued is
iptables -t mangle -A POSTROUTING -p udp -j <TC name> --map tos
iptables exits with input/output error (The same command was working on Linux-2.6.28.8). Then did a strace for the same on our target and seeing problem as below :
socket(PF_INET, SOCK_RAW, IPPROTO_RAW) = 3
getsockopt(3, SOL_IP, 0x40 /* IP_??? */, "mangle\0\0\0\0\0\34\200F\0\0\200\1\340 \244\200\1\340\244\200\7W\224\200\7W\f\0"..., [84]) = 0
getsockopt(3, SOL_IP, 0x41 /* IP_??? */, "mangle\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., [976]) = 0
setsockopt(3, SOL_IP, 0x40 /* IP_??? */, "mangle\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 1240) = -1 EIO (Input/output error)
close(3) = 0
write(2, "iptables: "..., 10iptables: ) = 10
write(2, "Input/output error"..., 18Input/output error) = 18
write(2, ".\n"..., 2.
) = 2
munmap(0x2ab9b000, 75264) = 0
exit(1)
The above code is in libiptc.c ; Any suggestions to debug the error further would be helpful. Thanks.

EIO means that your custom "TC" target (or whatever it is you meant by it) module, i.e. xt_TC.c, does not adhere to the API. checkentry is not supposed to return values greater than zero (there is no meaning assigned to them) in 2.6.35 and up.

The issue seems to resolve by changing the following lines in linux-2.6.35/net/netfilter/x_tables.c
function xt_check_match:
changed following lines from :
if (par->match->checkentry != NULL) {
ret = par->match->checkentry(par);
if (ret < 0)
return ret;
else if (ret > 0)
{
/* Flag up potential errors. */
return -EIO;
}
}
to :
if (par->match->checkentry != NULL && !par->match->checkentry(par))
return -EINVAL;
Similarly in function xt_check_target : changed lines from:
if (par->target->checkentry != NULL) {
ret = par->target->checkentry(par);
if (ret < 0)
return ret;
else if (ret > 0)
{
/* Flag up potential errors. */
return -EIO;
}
}
to:
if (par->target->checkentry != NULL && !par->target->checkentry(par))
return -EINVAL;
These were the checks present in previous kernels. having the same checks solves the above issue. Thanks.

Related

Segmentation fault in libavformat tls_openssl.c:tls_open->SSL_ctrl while using static link 'libdecode.a', however, using 'libdecode.so' works well

source code link: https://gitee.com/yanxiuzi/video-engine
(If you are interested in this issue, please answer me so that you can grant you access to the code.)
current target 'tests' use static link library of target 'decode', I build it on Debian11 by gcc-10.2.1 (it could also easyly build on ubuntu, because of the code used apt install cmd in CMakelists.txt), then run tests, I got a segmentation fault at
SSL_ctrl.
The steps are as follows:(you should clone this repository first)
cmake -B build build
cmake --build build --target all -j
cd build/bin
./tests config/config.json
But if I modify https://gitee.com/yanxiuzi/video-engine/blob/master/CMakeLists.txt line 163 and line 112, change to the linked target 'decode_shared' instead of 'decode', evrything goes well.
After debugging many times, I have not been able to find the reason why libdecode.a crashed but libdecode.so works well.
the CMakelists.txt of target decode and decode_shared see here:
https://gitee.com/yanxiuzi/video-engine/blob/873ca16d25c416c28b9b54eab6d2ed36a689c412/common/decode/CMakeLists.txt
note: if you debug tests use gdb, please exec cmd set follow-fork-mode child before start running, or you may can not catch the place error occured.
I'd love to know the cause of the problem, although in the end I avoided this by changing ffmpeg build flags, which using --enable-gnutls instead of --enable-openssl.
This is the code where the problem occurred. 'SSL_set_tlsext_host_name' is a macro definitions of 'SSL_ctrl'.
static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
{
TLSContext *p = h->priv_data;
TLSShared *c = &p->tls_shared;
BIO *bio;
int ret;
if ((ret = ff_openssl_init()) < 0)
return ret;
if ((ret = ff_tls_open_underlying(c, h, uri, options)) < 0)
goto fail;
// We want to support all versions of TLS >= 1.0, but not the deprecated
// and insecure SSLv2 and SSLv3. Despite the name, SSLv23_*_method()
// enables support for all versions of SSL and TLS, and we then disable
// support for the old protocols immediately after creating the context.
p->ctx = SSL_CTX_new(c->listen ? SSLv23_server_method() : SSLv23_client_method());
if (!p->ctx)
{
av_log(h, AV_LOG_ERROR, "%s\n", ERR_error_string(ERR_get_error(), NULL));
ret = AVERROR(EIO);
goto fail;
}
SSL_CTX_set_options(p->ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
if (c->ca_file)
{
if (!SSL_CTX_load_verify_locations(p->ctx, c->ca_file, NULL))
av_log(h, AV_LOG_ERROR, "SSL_CTX_load_verify_locations %s\n", ERR_error_string(ERR_get_error(), NULL));
}
if (c->cert_file && !SSL_CTX_use_certificate_chain_file(p->ctx, c->cert_file))
{
av_log(h, AV_LOG_ERROR, "Unable to load cert file %s: %s\n", c->cert_file,
ERR_error_string(ERR_get_error(), NULL));
ret = AVERROR(EIO);
goto fail;
}
if (c->key_file && !SSL_CTX_use_PrivateKey_file(p->ctx, c->key_file, SSL_FILETYPE_PEM))
{
av_log(h, AV_LOG_ERROR, "Unable to load key file %s: %s\n", c->key_file,
ERR_error_string(ERR_get_error(), NULL));
ret = AVERROR(EIO);
goto fail;
}
// Note, this doesn't check that the peer certificate actually matches
// the requested hostname.
if (c->verify)
SSL_CTX_set_verify(p->ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
p->ssl = SSL_new(p->ctx);
if (!p->ssl)
{
av_log(h, AV_LOG_ERROR, "%s\n", ERR_error_string(ERR_get_error(), NULL));
ret = AVERROR(EIO);
goto fail;
}
#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
p->url_bio_method = BIO_meth_new(BIO_TYPE_SOURCE_SINK, "urlprotocol bio");
BIO_meth_set_write(p->url_bio_method, url_bio_bwrite);
BIO_meth_set_read(p->url_bio_method, url_bio_bread);
BIO_meth_set_puts(p->url_bio_method, url_bio_bputs);
BIO_meth_set_ctrl(p->url_bio_method, url_bio_ctrl);
BIO_meth_set_create(p->url_bio_method, url_bio_create);
BIO_meth_set_destroy(p->url_bio_method, url_bio_destroy);
bio = BIO_new(p->url_bio_method);
BIO_set_data(bio, p);
#else
bio = BIO_new(&url_bio_method);
bio->ptr = p;
#endif
SSL_set_bio(p->ssl, bio, bio);
if (!c->listen && !c->numerichost)
SSL_set_tlsext_host_name(p->ssl, c->host); /// <<<=== backtrace shown segmentation fault here
ret = c->listen ? SSL_accept(p->ssl) : SSL_connect(p->ssl);
if (ret == 0)
{
av_log(h, AV_LOG_ERROR, "Unable to negotiate TLS/SSL session\n");
ret = AVERROR(EIO);
goto fail;
}
else if (ret < 0)
{
ret = print_tls_error(h, ret);
goto fail;
}
return 0;
fail:
tls_close(h);
return ret;
}

in windows 10, redirect port monitor (redmon), run as user doesn't work

I have a redirected printer port that use redmon (redirect port monitor) with a postscript printer driver to convert postscript to pdf and apply some other effects like watermarks, overlays, etc.
In win 7 all work fine but in windows 10 the process run under system user account.
In the configuration window of the printer port there is a flag called "Run as user" and in win7, checking this flag let the job running under the user account.
In Windows 10 it seems not working.
Any suggestion will be very appreciated.
Thank you.
Roy
I had a similar problem. I needed the user that printed the document to select the type of document and a patient ID. Then print the document to our EHR system as a PDF. Works in Windows 7 when "Run as User" is checked, but not on Windows 10. Redmon always runs the program as "SYSTEM". So I added a bit to the beginning of the program to check the user name. If it is "SYSTEM" the program looks for the an interactive user on the system by finding an instance of explorer.exe. If more than one interactive user is logged onto the system this will fail. Not a problem for my task. The program then starts another instance of itself running as the same user as explorer.exe, passing the same command line. A pipe is used so that stdin from the first instance can be piped to stdin on the second instance. Another limitation is that on a 64 bit OS, a 64 bit version of the program must be used. Otherwise explorer.exe may not be found.
The following code is what I placed at the beginning of my program. Don't be fooled by the program starting at main(). I am using a GUII toolkit that has WinMain() in it and then calls main(). I have only tested the code on ASCII programs. I tried to use the ASCII version of calls so that it would work with non-ASCII programs, but I am not sure I got all of them.
The LogInfoSys("Hello World"); function just writes to a log file.
Good luck.
#include <Windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
#include <time.h>
#include <direct.h>
#include <process.h>
#include <sqlext.h>
#include <Psapi.h>
#include <tlhelp32.h>
int main(int argc, char *argv[])
{
int error;
char msg[1024];
DWORD *processIDs;
int processCount;
HANDLE hProcess = NULL;
HANDLE hToken;
char userName[64];
char progName[1024];
int i, j;
char nameMe[256];
char domainMe[256];
PTOKEN_USER ptuMe = NULL;
PROCESS_INFORMATION procInfo;
STARTUPINFO startUpInfo;
HMODULE *hMod;
DWORD cbNeeded;
SECURITY_ATTRIBUTES saAttr;
HANDLE hChildStd_IN_Rd = NULL;
HANDLE hChildStd_IN_Wr = NULL;
i = 64; // Get user name, if it is "SYSTEM" redirect input to output to a new instance of the program
GetUserNameA(userName, &i);
if (_stricmp(userName, "system") == 0)
{
LogInfoSys("Running as SYSTEM");
processIDs = (DWORD *)calloc(16384, sizeof(DWORD)); // Look for explorer.exe running. If found that should be the user we want to run as.
EnumProcesses(processIDs, sizeof(DWORD) * 16384, &i); // If there is more than one that is OK as long as they are both being run by the same
processCount = i / sizeof(DWORD); // user. If more than one user is logged on, this will be a problem.
hMod = (HMODULE *)calloc(4096, sizeof(HMODULE));
hProcess = NULL;
for (i = 0; (i < processCount) && (hProcess == NULL); i++)
{
if (processIDs[i] == 11276)
Sleep(0);
if (processIDs[i] != 0)
{
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processIDs[i]);
if (hProcess != NULL)
{
cbNeeded = 0;
error = EnumProcessModules(hProcess, hMod, sizeof(HMODULE) * 4096, &cbNeeded);
if (error == 0)
{
error = GetLastError();
Sleep(0);
}
progName[0] = 0;
error = GetModuleBaseNameA(hProcess, hMod[0], progName, 1024);
if (error == 0)
{
error = GetLastError();
Sleep(0);
}
if (_stricmp(progName, "explorer.exe") != 0)
{
CloseHandle(hProcess);
hProcess = NULL;
}
else
{
LogInfoSys("Found explorer.exe");
}
}
}
}
LogInfoSys("After looking for processes.");
nameMe[0] = domainMe[0] = 0;
if (hProcess != NULL)
{
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
if (!CreatePipe(&hChildStd_IN_Rd, &hChildStd_IN_Wr, &saAttr, 0)) // Create a pipe for the child process's STDIN.
LogInfoSys("Stdin CreatePipe error");
if (!SetHandleInformation(hChildStd_IN_Wr, HANDLE_FLAG_INHERIT, 0)) // Ensure the write handle to the pipe for STDIN is not inherited.
LogInfoSys("Stdin SetHandleInformation errir");
if (OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, &hToken) != 0)
{
GetStartupInfo(&startUpInfo);
startUpInfo.cb = sizeof(STARTUPINFO);
startUpInfo.lpReserved = NULL;
startUpInfo.lpDesktop = NULL;
startUpInfo.lpTitle = NULL;
startUpInfo.dwX = startUpInfo.dwY = 0;
startUpInfo.dwXSize = 0;
startUpInfo.dwYSize = 0;
startUpInfo.dwXCountChars = 0;
startUpInfo.dwYCountChars = 0;
startUpInfo.dwFillAttribute = 0;
startUpInfo.dwFlags |= STARTF_USESTDHANDLES;
startUpInfo.wShowWindow = 0;
startUpInfo.cbReserved2 = 0;
startUpInfo.lpReserved = NULL;
startUpInfo.hStdInput = hChildStd_IN_Rd;
startUpInfo.hStdOutput = NULL;
startUpInfo.hStdError = NULL;
GetModuleFileName(NULL, progName, 1024);
i = CreateProcessAsUserA(hToken, progName, GetCommandLine(), NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, &startUpInfo, &procInfo);
if (i == 0)
{
i = GetLastError();
}
do
{
i = (int)fread(msg, 1, 1024, stdin);
if (i > 0)
WriteFile(hChildStd_IN_Wr, msg, i, &j, NULL);
} while (i > 0);
}
}
LogInfoSys("End of running as SYSTEM.");
exit(0);
}
/**********************************************************************************************************
*
* End of running as SYSTEM and start of running as the user that printed the document (I hope).
*
**********************************************************************************************************/
exit(0);
}

catch return value after execute external task using AuthorizationExecuteWithPrivileges

I was managed to execute an external task on a different process (child proc) using the method AuthorizationExecuteWithPrivileges in the following manner :
AuthorizationExecuteWithPrivileges(
AuthorizationRef,
commandFullPath,
Flags,
Arguments,
&CommunicationsPipe)
However, I'd also like obtain the return value from that specific command. in bash it's saved in the special character $?. is there any equivalent in objective C ?
You can check for sub-process pid using the communication file you supplied to AuthorisationExecuteWithPrivileges in the following command :
FILE* pipe = NULL;
int status = AuthorizationExecuteWithPrivileges(auth, path, flags, args, &pipe)
if (status == errAuthorizationSuccess)
pid_t pid = fcntl(fileno(pipe), F_GETOWN, 0);
Then you can use the pid and wait till the sub-process returns and acquire its return value :
pid_t pid2 = 0;
while ((pid = waitpid(pid, &stat, WNOHANG)) == 0) { }
int terminationStatus = WEXITSTATUS(stat);

tftpGet error from tftpLib in VxWorks

I'm writing a little function that downloads a file from a TFTP server using VxWork's tftpLib (http://www.vxdev.com/docs/vx55man/vxworks/ref/tftpLib.html) - now I realized that my tftpGet() command is returning an error 1 but I'm not sure what errorcode 1 means. On the posted website it says:
ERRNO
S_tftpLib_INVALID_DESCRIPTOR
S_tftpLib_INVALID_ARGUMENT
S_tftpLib_NOT_CONNECTED
But how do I know what 1 corresponds with?
The get portion of my code looks like this:
/* Initialize and createlocal file handle */
pFile = fopen("ngfm.bin","wb");
if (pFile != NULL)
{
/* Get file from TFTP server and write it to the file descriptor */
status = tftpGet (pTftpDesc, pFilename, pFile, TFTP_CLIENT);
printf("GOT %s\n",pFilename);
}
else
{
printf("Error in tftpGet()\nfailed to get %s from %s\nERRNO %d",pFilename,pHost, status);
}
Try this code:
int status;
if (OK == (status = tftpGet (pTftpDesc, pFilename, fd, TFTP_CLIENT))) {
printf("tftpGet() successful\n");
} else {
printf("Error has occurred: %d\n", errno); // errno is where the error is stored
}
No,The problem in fact was, that I didn';t get a valid file pointer but NULL because there's no such thing as a "current directory" like in Linux in VxWorks but I had to change my fopen to say something like pFile = fopen("flash:/ngfm.bin","wb"); instead.

Unix C code cp in system()

I have a C code..
i which I have following code for UNIX:
l_iRet = system( "/bin/cp -p g_acOutputLogName g_acOutPutFilePath");
when I am running the binary generated..I am getting the following error:
cp: cannot access g_acOutputLogName
Can any one help me out?
You should generally prefer the exec family of functions over the system function. The system function passes the command to the shell which means that you need to worry about command injection and accidental parameter expansion. The way to call a subprocess using exec is as follows:
pid_t child;
child = fork();
if (child == -1) {
perror("Could not fork");
exit(EXIT_FAILURE);
} else if (child == 0) {
execlp("/bin/cp", g_acOutputLogName, g_acOutPutFilePath, NULL);
perror("Could not exec");
exit(EXIT_FAILURE);
} else {
int childstatus;
if (waitpid(child, &childstatus, 0) == -1) {
perror("Wait failed");
}
if (!(WIFEXITED(childstatus) && WEXITSTATUS(childstatus) == EXIT_SUCCESS)) {
printf("Copy failed\n");
}
}
Presumably g_acOutputLogName and g_acOutPutFilePath are char[] (or char*) variables in your program, rather than the actual paths involved.
You need to use the values stored therein, rather than the variable names, for example:
char command[512];
snprintf( command, sizeof command, "/bin/cp -p %s %s",
g_acOutputLogName, g_acOutPutFilePath );
l_iRet = system( command );