Is a lone linefeed (0x0A) a violation of the INI format? - android

Is it a violation if the INI format to have a single linefeed (0x0A) that is not preceded by a carraige return (0x0D)?
Ini4j is puking on this in my Android app.
Please abstain from asking why I'm using INI in an Android app...

Since *.ini is a windows format, you can expect, that each newline must be \r\n.
At least in the sources, only the Registry class definitivly relies on \r\n. In all other cases it seems, as if the system property line.separator is used.
It's still arguable is a cross-plattform library should rely on it...
The problem can be resolved setting setEmptyOption(true) e.g.
Config c = new Config();
c.setEmptyOption(true);
Ini i = new Ini();
i.setConfig(c);

Related

Add new security policy in SElinux on Android 10

I want witch /dev/i2c-1 device to be outside the SELinux security policy on Android 10.
I have the source code for Android 10. I tried creating a .te file in /device/thales/mt8768q/sepolicy/edgelab.te
In foo.te, I added a similar example to the site: https://source.android.com/security/selinux/customize.
allow domain i2c-1_device:chr_file rw_file_perms
But, in compilation, this line generates an error.
UPDATE:
I add new line on /device/manufacturer/device-name/BoardConfig.mk:
BOARD_SEPOLICY_DIRS += device/thales/mt8768q/sepolicy
The error is:
#line 206
device/mediatek/mt6765/sepolicy/bsp/mnld.te:8:ERROR 'syntax error' at token 'role' on line 97225:
#line 2 "device/thales/mt8768q/sepolicy/edgelab.te"
allow domain i2c-1_device:chr_file { { getattr open read ioctl lock map } { open append write lock map } }role r;
checkpolicy: error(s) encountered while parsing configuration
Maybe i2c-1_device is not a valid name, but I don't know how to refer to /dev/i2c-1 in .te file.
Your should define your domain and label.
Define your dev_type (device/"manufacturer"/"device-name"/sepolicy/"your-filename".te):
type i2c-1_device, dev_type;
Label file with your type (device/"manufacturer"/"device-name"/sepolicy/file_contexts):
/dev/i2c-1/* u:object_r:i2c-1_device:s0
Define your rule (device/"manufacturer"/"device-name"/"your-filename".te):
allow domain i2c-1_device:chr_file rw_file_perms
You'd better define your domain and restrict only your domain can access i2c-1_device. The example define an dhcp domain, it's an good example.

Titanium Hyperloop access to android.os.SystemProperties

I have been trying a ( i hope) simple bit of Android hyperloop code directly within a titanium project (using SDK 7.0.1.GA and hyperloop 3).
var sysProp = require('android.os.SystemProperties');
var serialNumber = sysProp.get("sys.serialnumber", "none");
But when the app is run it reports
Requested module not found:android.os.SystemProperties
I think this maybe due to the fact that when compiling the app (using the cli) it reports
hyperloop:generateSources: Skipping Hyperloop wrapper generation, no usage found ...
I have similar code in a jar and if I use this then it does work, so I am wondering why the hyperloop generation is not being triggered, as I assume that is the issue.
Sorry should have explained better.
This is the jar source that I use, the extraction of the serial number was just an example (I need access to other info manufacturer specific data as well), I wanted to see if I could replicate the JAR functionality using just hyperloop rather that including the JAR file. Guess if it's not broke don't fix it, but was curious to see if it could be done.
So with the feedback from #miga and a bit of trial and error, I have come up with a solution that works really well and will do the method reflection that is required. My new Hyperloop function is
function getData(data){
var result = false;
var Class = require("java.lang.Class");
var String = require("java.lang.String");
var c = Class.forName("android.os.SystemProperties");
var get = c.getMethod("get", String.class, String.class);
result = get.invoke(c, data, "Error");
return result;
}
Where data is a string of the system property I want.
I am using it to extract and match a serial number from a Samsung device that is a System Property call "ril.serialnumber" or "sys.serialnumber". Now I can use the above function to do what I was using the JAR file for. Just thought I'd share in case anyone else needed something similar.
It is because android.os.SystemProperties is not class you can import. Check the android documentation at https://developer.android.com/reference/android/os/package-summary.html
You could use
var build = require('android.os.Build');
console.log(build.SERIAL);
to access the serial number.

What is the purpose of using double underscore ( __ ) before the start and after the end of an file name in c?

I'm studying the android kernel as a beginner. I can read the messages thrown from the macro ERROR() inside the function main() at system/core/init/init.c using dmesg command through adb. I observed that after calling the function open_devnull_stdio() inside main(), dmesg no longer displays the messages thrown by ERROR().
To find the reason, I started digging into the declaration of open_devnull_stdio() inside system/core/init/util.c and I found this line I can't understand
static const char *name = "/dev/__null__";
Actually there was no file named __null__ inside /dev/ in the device, but there was a file named null and I was able to grab it using adb pull and it was a 0 byte (empty) file.
So why is a file name wrapped with double underscore (__) ?
Here is the link for the util.c
There is no special purpose of using double underscore before the start, after the end or both in C. From the point of view of C the file name is just a string, the operating system is free to interpret in whatever way it chooses. From the point of view of Linux, the same applies. Underscores in file names are just characters. They are not treated differently from the letters b and t.
If I guessed right and I'm reading the same file as you (it might be a good idea to link to the source code you're reading) then it should be pretty obvious what the code does on the lines after the one you mentioned. The next lines are:
if (mknod(name, S_IFCHR | 0600, (1 << 8) | 3) == 0) {
fd = open(name, O_RDWR);
unlink(name);
Which creates the null device which is then opened and immediately deleted again.
I suspect this is done so that programs can run without access to the root filesystem and still be able to open the equivalent of /dev/null.
I don't know the answer but I have an idea:
The following page shows an "strace" output where /dev/__null__ is used:
https://gist.github.com/tetsu-koba/1522515
Under Linux device files have a 33-bit (?) number which identifies the device. (At least under old Linux versions) you could delete some file in /dev and you could restore it or even create it in another directory (!) when you know the 33-bit number! (So you can delete the device /dev/sda2 and create the device (not file!) /home/myuser/sda2 instead.)
The trace in the link above shows the following three lines:
mknod("/dev/__null__", S_IFCHR|0600, makedev(1, 3)) = 0
open("/dev/__null__", O_RDWR|O_LARGEFILE) = 3
unlink("/dev/__null__") = 0
These lines will create the device file /dev/__null__ (with the 33-bit number identifying /dev/null). Then it opens that file and then it removes the file again.
Maybe this is done because the tool shall be able to run both on Linux installations where the device file "/dev/null" is present (in this case the file should not be overwritten) and on installations where that file is missing (in this case a replacement file must be created using the known 33-bit number).
As other people have pointed out this just tells it's the "null device", not a regular file called "null". null is supposed to act like an information sink, not like a normal file where you dump your data to. Hope this helps.

Android logback SizeBasedTriggeringPolicy not triggering

I'm using logback for android, and I'm configuring it in code because I want the log directory to dynamically change depending on the phone (e.g. some phones have external storage and I want to write to that, but other phones don't so we have to redirect to internal storage).
Here is my config code:
File logFilesDir = getLogFilesDir(this);
LoggerContext lc = (LoggerContext)LoggerFactory.getILoggerFactory();
lc.reset();
RollingFileAppender<ILoggingEvent> fileAppender = null;
lc.putProperty("LOG_DIR", logFilesDir.getAbsolutePath());
PatternLayoutEncoder encoder = new PatternLayoutEncoder();
encoder.setContext(lc);
encoder.setPattern("%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n");
encoder.start();
File logFile = new File(logFilesDir, "MyApplication.log");
FixedWindowRollingPolicy rollingPolicy = new FixedWindowRollingPolicy();
rollingPolicy.setContext(lc);
rollingPolicy.setFileNamePattern("${LOG_DIR}/MyApplication.%i.log");
rollingPolicy.setMinIndex(1);
rollingPolicy.setMaxIndex(5);
SizeBasedTriggeringPolicy<ILoggingEvent> triggeringPolicy = new SizeBasedTriggeringPolicy<>();
triggeringPolicy.setContext(lc);
triggeringPolicy.setMaxFileSize("1KB"); // for testing; would otherwise be 5MB
fileAppender = new RollingFileAppender<>();
fileAppender.setContext(lc);
fileAppender.setFile(logFile.getAbsolutePath());
fileAppender.setEncoder(encoder);
fileAppender.setRollingPolicy(rollingPolicy);
fileAppender.setTriggeringPolicy(triggeringPolicy);
rollingPolicy.setParent(fileAppender);
fileAppender.start();
rollingPolicy.start();
triggeringPolicy.start();
// add the newly created appenders to the root logger;
// qualify Logger to disambiguate from org.slf4j.Logger
ch.qos.logback.classic.Logger root = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
root.addAppender(fileAppender);
root.info("----- Application onCreate -----");
StatusPrinter.print(lc);
The log writes to the correct folder and it's all working ok, except when my log file exceeds the max file size (in my testing case 1KB) it fails to roll over. Instead, the file just keeps growing.
StatusPrinter.print writes the following output, which looks like everything's ok
|-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [assets/logback.xml]
|-INFO in ch.qos.logback.core.rolling.RollingFileAppender[null] - Active log file name: /storage/emulated/0/MyApplication/logs/MyApplication.log
|-INFO in ch.qos.logback.core.rolling.RollingFileAppender[null] - File property is set to [/storage/emulated/0/MyApplication/logs/MyApplication.log]
|-INFO in ch.qos.logback.core.rolling.FixedWindowRollingPolicy#34b71b53 - No compression will be used
I've looked at as many other similar issues as I can find, and usually people seem to miss out the RollingFileAppender or don't have WRITE_EXTERNAL_STORAGE permission... It doesn't seem to me like I'm hitting any of those cases. Is something about my code (vs the XML people normally use) different?
Is there anything I can do to fix this or troubleshoot it further?
Thanks
I can't immediately tell what the problem is, but it would be helpful add an OnConsoleStatusListener to see what happens during the rollover:
LoggerContext lc = (LoggerContext)LoggerFactory.getILoggerFactory();
lc.reset();
OnConsoleStatusListener.addNewInstanceToContext(lc);
Rollover problems from RollingFileAppender are typically caused by a mix of absolute and relative paths in their configuration (Issue #117, Issue #110) or missing the WRITE_EXTERNAL_STORAGE permission (which is not the case for you). The debug output from OnConsoleStatusListener might shed some light. If not, I can try to debug it if you create a GitHub Issue, preferably with an Android Studio project that reproduces the problem.

How can I import XML schema without network access?

I'm implementing schema validation using libxml2. The schema I'm validating against imports two other schemas with lines like:
<xs:import namespace="http://www.w3.org/XML/1998/namespace"
schemaLocation="http://www.somewebsite.com/xsd/xml.xsd"/>
All three schema files are located in the same directory on the device.
This works well when the device has internet access, but fails when it does not, as libxml2 still attempts to download the imported schemas from the schemaLocation even though I'm passing in XML_PARSE_NONET.
I tried getting libxml2 to load the files locally by editing the schemaLocation attribute to xml.xsd, ./xml.xsd, and file:///data/data/com.company.appname/files/xml.xsd, but all three resulted in the same libxml2 error:
domain: 16
code: 3069 (XML_SCHEMAP_INTERNAL)
message: Internal error: xmlSchemaParse, An internal error occurred.
I also tried removing the schemaLocation attribute entirely, on the off-chance that libxml2 might search for the imported schemas alongside the original schema, but that resulted in the following error when the schema parser hit a line that referenced the imported entities:
<xs:attribute ref="xml:lang" use="required"/>
domain: 16
code: 3004 (XML_SCHEMAP_SRC_RESOLVE)
message: attribute use (unknown), attribute 'ref': The QName value '{http://www.w3.org/XML/1998/namespace}lang' does not resolve to a(n) attribute declaration.
I also looked into manually merging the three schemas into a single file, but as they use different namespaces, this is not possible.
The standard solution for this seems to be the XML catalog, but I've read through libxml2's catalog documentation, and I can't figure out how (or even whether it's possible) to add mappings that will be used by my app when deployed to a device. I think I might need to implement an xmlExternalEntityLoader, but the documentation for that is quite slim.
How can I get libxml2 to import these schemas without network access? Obviously I'd ideally like a robust solution that works with the unedited schema, but I've be content with something quick-and-dirty that involves editing the schema, like my original attempts described above.
The errors described above are from an Android device (using JNI), but I'm having similar problems on iOS, where the solution will also need to work.
One way to do this is to intercept libxml2's call to open the imported URL with a custom xmlExternalEntityLoader.
The basic code for doing this is as follows:
#include <libxml/xmlIO.h>
#include <libxml/parserinternals.h>
xmlExternalEntityLoader defaultLoader = NULL;
xmlParserInputPtr
xmlMyExternalEntityLoader(const char *URL, const char *ID,
xmlParserCtxtPtr ctxt) {
xmlParserInputPtr ret;
const char *fileID = NULL;
/* lookup for the fileID
* The documentation suggests using the ID, but for me this was
* always NULL so I had to lookup by URL instead.
*/
ret = xmlNewInputFromFile(ctxt, fileID);
if (ret != NULL)
return(ret);
if (defaultLoader != NULL)
ret = defaultLoader(URL, ID, ctxt);
return(ret);
}
int main(..) {
...
/*
* Install our own entity loader
*/
defaultLoader = xmlGetExternalEntityLoader();
xmlSetExternalEntityLoader(xmlMyExternalEntityLoader);
...
}
(Slightly adjusted from the sample code in The entities loader section of libxml2's I/O Interfaces documentation.)

Categories

Resources